diff --git a/play.lua b/play.lua index 84b4a09..c105d4e 100644 --- a/play.lua +++ b/play.lua @@ -400,25 +400,42 @@ local function httpResponseHandler() local batch = pendingRequests[url] if batch then pendingRequests[url] = nil - local binData = handleOrErr.readAll() - handleOrErr.close() - - local success, batchFrames = pcall(unpackFramePack, binData) - if success then - for idx = 1, #batchFrames do - local globalIdx = batch.start + idx - 1 - if not allFrameData[globalIdx] then - allFrameData[globalIdx] = batchFrames[idx] - end - end - local sizeInMB = #binData / (1024 * 1024) - - print("[V] Cached batch: " .. batch.start .. " - " .. (batch.start + #batchFrames - 1) .." ("..tonumber(string.format("%.1f", sizeInMB)).." Mb)") + + -- [优化] 检查整个批次是否已经完全过期待(最晚的一帧都小于 frameIndex - 10) + -- 虽然 unpacking 很快,但在极端延迟下可以直接跳过解包 + local batchEndIdx = batch.start + #batch.urls - 1 + if batchEndIdx < frameIndex - 10 then + -- 批次过旧,直接丢弃,仅释放句柄 + handleOrErr.close() + print("[X] Drop old batch (too late): " .. batch.start) else - print("[R] Unpack failed for batch " .. batch.start .. ": " .. tostring(batchFrames)) - -- 标记这些帧可重试 - for j = batch.start, batch.start + #batch.urls - 1 do - downloadedFrames[j] = nil + local binData = handleOrErr.readAll() + handleOrErr.close() + + local success, batchFrames = pcall(unpackFramePack, binData) + if success then + for idx = 1, #batchFrames do + local globalIdx = batch.start + idx - 1 + + -- [核心修改] 只有当帧号 >= 当前帧 - 10 时才存入内存 + -- 防止旧数据占用内存或被错误地重新缓存 + if globalIdx >= frameIndex - 10 then + if not allFrameData[globalIdx] then + allFrameData[globalIdx] = batchFrames[idx] + end + end + end + -- 仅计算大致大小用于日志,逻辑不变 + local sizeInMB = #binData / (1024 * 1024) + print("[V] Cached batch: " .. batch.start .. " - " .. (batch.start + #batchFrames - 1) .." ("..tonumber(string.format("%.1f", sizeInMB)).." Mb)") + else + print("[R] Unpack failed for batch " .. batch.start .. ": " .. tostring(batchFrames)) + -- 这里如果解包失败,如果数据还算新才许重试 + if batchEndIdx >= frameIndex - 10 then + for j = batch.start, batch.start + #batch.urls - 1 do + downloadedFrames[j] = nil + end + end end end end @@ -427,22 +444,38 @@ local function httpResponseHandler() local batch = pendingRequests[url] if batch then pendingRequests[url] = nil - batch.retry = (batch.retry or 0) + 1 - if batch.retry < 3 then - print("[R] Retrying batch " .. batch.start .. " (attempt " .. (batch.retry + 1) .. ") Error: "..handleOrErr) - -- 允许重试 - for j = batch.start, batch.start + #batch.urls - 1 do - downloadedFrames[j] = nil - end - -- 重新触发 cacheAhead 下一轮会重发 - else - print("[X] Giving up on batch " .. batch.start) - print("[E] " .. batch.start.." "..handleOrErr) - - -- 永久失败,不再重试 + + -- [核心修改] 检查批次时效性 + -- 如果该批次最晚的一帧都比 (frameIndex - 10) 还旧,直接丢弃,不再重试 + local batchEndIdx = batch.start + #batch.urls - 1 + + if batchEndIdx < frameIndex - 10 then + -- 这里的 print 可以注释掉,或者保留用于调试 + print("[X] Drop old batch (too late): " .. batch.start) + + -- 标记已下载(尽管是失败),防止 cacheAhead 再次死循环请求它 for j = batch.start, batch.start + #batch.urls - 1 do downloadedFrames[j] = true end + else + -- 只有数据还比较“新鲜”时,才进行重试逻辑 + batch.retry = (batch.retry or 0) + 1 + if batch.retry < 3 then + print("[R] Retrying batch " .. batch.start .. " (attempt " .. (batch.retry + 1) .. ") Error: "..tostring(handleOrErr)) + -- 允许重试 + for j = batch.start, batch.start + #batch.urls - 1 do + downloadedFrames[j] = nil + end + -- 重新触发 cacheAhead 下一轮会重发 + else + print("[X] Giving up on batch " .. batch.start) + print("[E] " .. batch.start.." "..tostring(handleOrErr)) + + -- 永久失败,不再重试 + for j = batch.start, batch.start + #batch.urls - 1 do + downloadedFrames[j] = true + end + end end end @@ -540,7 +573,7 @@ local function renderVideo() else print("[E] "..frameIndex.." is nil") nil_e = nil_e + 1 - if nil_e >= 200 then + if nil_e >= 5 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 sleep(2)