diff --git a/play.lua b/play.lua index d5636a0..84b4a09 100644 --- a/play.lua +++ b/play.lua @@ -1,11 +1,72 @@ -- 简化版视频播放器 local gpu = peripheral.wrap("tm_gpu_0") -local gpu_Size = 64 +local gpu_Size_Auto = true --自动分辨率设置 +local gpu_Size = 64 --默认屏幕分辨率 if not gpu then gpu = peripheral.find("tm_gpu") end gpu.refreshSize() gpu.setSize(gpu_Size) -local w, h = gpu.getSize() +local w, h, w_black, h_black, Size = gpu.getSize() + + +-- 分批下载(每批 10 帧) +local BATCH_SIZE = 10 + + +local function computeOptimalSize(w_black, h_black) + local w_target, h_target = 640, 360 + local max_size = 64 + + -- 避免除零 + if w_black <= 0 or h_black <= 0 then + return 1 + end + + -- 计算理想缩放比例(不能让任一边超过目标) + local size_by_w = w_target / w_black + local size_by_h = h_target / h_black + local ideal_size = math.min(size_by_w, size_by_h) + + -- 如果理想值 >= 64,直接用 64 + if ideal_size >= max_size then + return max_size + end + + -- 否则,在 floor 和 ceil 中选更优的(但不能超过 64) + local size_floor = math.floor(ideal_size) + local size_ceil = math.ceil(ideal_size) + + -- 确保不越界 + if size_floor < 1 then size_floor = 1 end + if size_ceil > max_size then size_ceil = max_size end + + -- 计算两个候选的误差(欧氏距离或曼哈顿距离均可,这里用平方和) + local function error(size) + local w = w_black * size + local h = h_black * size + return (w - w_target)^2 + (h - h_target)^2 + end + + local err_floor = error(size_floor) + local err_ceil = error(size_ceil) + + if err_floor <= err_ceil then + return size_floor + else + return size_ceil + end +end + +if gpu_Size_Auto then + local optimal_Size = computeOptimalSize(w_black, h_black) + print("[I] gpu_Size: "..optimal_Size) + gpu.refreshSize() + gpu.setSize(optimal_Size) +end +local w, h, w_black, h_black, Size = gpu.getSize() + + + local mypath = "/"..fs.getDir(shell.getRunningProgram()) if not fs.exists(mypath.."/speakerlib.lua") then shell.run("wget https://git.liulikeji.cn/xingluo/computer_craft_video_play/raw/branch/main/speakerlib.lua") end @@ -188,8 +249,6 @@ local function unpackFramePack(data) return frames end --- 分批下载(每批 50 帧) -local BATCH_SIZE = 20 -- local totalFrames = #videoInfo.frame_urls local totalFrames = videoInfo.fps * 20 -- 仅下载前20秒以节省时间 local allFrameData = {} @@ -219,7 +278,7 @@ for _, batch in ipairs(initBatches) do url = server_url .. "/api/framepack?" .. batch.urls[1], headers = { ["Content-Type"] = "application/json" }, body = textutils.serializeJSON({ urls = batch.urls }), - timeout = 3, + timeout = 2, binary = true }) @@ -265,7 +324,7 @@ until _G.audio_ready local starttime1 = os.clock() --- 播放前已缓存 20 秒 + local totalFramesToPlay = #videoInfo.frame_urls -- 标志:是否还在播放 @@ -319,7 +378,7 @@ local function cacheAhead() url = url, headers = { ["Content-Type"] = "application/json" }, body = body, - timeout = 3, + timeout = 2, binary = true }) pendingRequests[url] = batch @@ -455,7 +514,7 @@ local function renderVideo() math.floor(ui_avgMs), math.floor(ui_lowFps), math.floor(ui_lowMs), - w,h,gpu_Size + w,h,Size ) gpu.drawText(1, 1, statusText, 0xFD452A) end @@ -484,11 +543,7 @@ local function renderVideo() if nil_e >= 200 then error("\n[E] No available video data for 10 seconds \nDownload speed is below the minimum threshold! \nPlease try checking your network bandwidth or adjusting the resolution.") end - repeat - local event, id = os.pullEvent("timer") - until id == timer_id - - + sleep(2) timer_id = os.startTimer(frameDelay) -- === 修改点:数据为空时,不做任何操作,直接进入下方的同步逻辑 === -- 此时 frameEnd 依然等于 frameStart,计算出的 costTime 为 0