边转换边播放功能
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
.history
|
||||||
|
|
||||||
149
play.lua
149
play.lua
@@ -1,5 +1,5 @@
|
|||||||
-- 简化版视频播放器
|
-- 简化版视频播放器
|
||||||
local gpu = peripheral.wrap("tm_gpu_2")
|
local gpu = peripheral.wrap("tm_gpu_0")
|
||||||
gpu.refreshSize()
|
gpu.refreshSize()
|
||||||
gpu.setSize(64)
|
gpu.setSize(64)
|
||||||
local w, h = gpu.getSize()
|
local w, h = gpu.getSize()
|
||||||
@@ -65,7 +65,7 @@ print("task_id: " .. task_id)
|
|||||||
|
|
||||||
-- 用于记录已打印的日志数量,避免重复打印
|
-- 用于记录已打印的日志数量,避免重复打印
|
||||||
local total_logs_printed = 0
|
local total_logs_printed = 0
|
||||||
|
speakerrun = true
|
||||||
while true do
|
while true do
|
||||||
|
|
||||||
|
|
||||||
@@ -97,9 +97,16 @@ while true do
|
|||||||
total_logs_printed = total_logs_printed + #task_info.new_logs
|
total_logs_printed = total_logs_printed + #task_info.new_logs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if task_info.result.audio_urls and speakerrun then
|
||||||
|
speakerrun = false
|
||||||
|
shell.run("bg speakerlib play ".. server_url .. task_info.result.audio_urls.audio_dfpwm_url .." ".. server_url .. task_info.result.audio_urls.audio_dfpwm_left_url .." ".. server_url .. task_info.result.audio_urls.audio_dfpwm_right_url)
|
||||||
|
end
|
||||||
|
|
||||||
-- 检查是否完成
|
-- 检查是否完成
|
||||||
if task_info.status == "completed" then
|
if task_info.result.current_frames then
|
||||||
break
|
if task_info.result.current_frames >= 200 then
|
||||||
|
break
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
sleep(1)
|
sleep(1)
|
||||||
@@ -111,18 +118,23 @@ local response = http.get(status_url, {["Content-Type"] = "application/json"})
|
|||||||
local finalResp = textutils.unserialiseJSON(response.readAll())
|
local finalResp = textutils.unserialiseJSON(response.readAll())
|
||||||
response.close()
|
response.close()
|
||||||
|
|
||||||
videoInfo = finalResp.result.result
|
videoInfo = finalResp.result
|
||||||
|
videoInfo.fps = 20
|
||||||
|
|
||||||
-- 此时 videoInfo 包含 frame_urls, audio_dfpwm_url 等字段
|
videoInfo.frame_urls = {}
|
||||||
print("\nTask completed! Total frames: " .. #videoInfo.frame_urls)
|
|
||||||
|
-- /frames/20116713/frame_000001.png
|
||||||
|
for i = 1, videoInfo.total_frames - 10 do
|
||||||
|
videoInfo.frame_urls[i] = "/frames/"..task_id.."/frame_" .. string.format("%06d", i) .. ".png"
|
||||||
|
end
|
||||||
|
|
||||||
-- 播放音频 单通道
|
-- 播放音频 单通道
|
||||||
--shell.run("bg speaker play", server_url .. videoInfo.audio_dfpwm_url)
|
--shell.run("bg speaker play", server_url .. videoInfo.audio_dfpwm_url)
|
||||||
|
|
||||||
-- server_url .. videoInfo.audio_dfpwm_url -- 音频单通道文件 URL
|
-- server_url .. videoInfo.audio_urls.audio_dfpwm_url -- 音频单通道文件 URL
|
||||||
-- server_url .. videoInfo.audio_dfpwm_right_url -- 音频右通道文件 URL
|
-- server_url .. videoInfo.audio_urls.audio_dfpwm_right_url -- 音频右通道文件 URL
|
||||||
-- server_url .. videoInfo.audio_dfpwm_left_url -- 音频左通道文件 URL
|
-- server_url .. videoInfo.audio_urls.audio_dfpwm_left_url -- 音频左通道文件 URL
|
||||||
shell.run("bg speakerlib play ".. server_url .. videoInfo.audio_dfpwm_url .." ".. server_url .. videoInfo.audio_dfpwm_left_url .." ".. server_url .. videoInfo.audio_dfpwm_right_url)
|
|
||||||
-- 下载和播放函数
|
-- 下载和播放函数
|
||||||
frames = {}
|
frames = {}
|
||||||
local frameCount = 0
|
local frameCount = 0
|
||||||
@@ -163,92 +175,73 @@ local function unpackFramePack(data)
|
|||||||
|
|
||||||
return frames
|
return frames
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 分批下载(每批 50 帧)
|
-- 分批下载(每批 50 帧)
|
||||||
local BATCH_SIZE = 20
|
local BATCH_SIZE = 20
|
||||||
-- local totalFrames = #videoInfo.frame_urls
|
-- local totalFrames = #videoInfo.frame_urls
|
||||||
local totalFrames = videoInfo.fps * 10 -- 仅下载前10秒以节省时间
|
local totalFrames = videoInfo.fps * 10 -- 仅下载前10秒以节省时间
|
||||||
local allFrameData = {}
|
local allFrameData = {}
|
||||||
|
|
||||||
|
-- 第一步:构建所有需要下载的批次(仅前10秒)
|
||||||
|
local initBatches = {}
|
||||||
for startIdx = 1, totalFrames, BATCH_SIZE do
|
for startIdx = 1, totalFrames, BATCH_SIZE do
|
||||||
local endIdx = math.min(startIdx + BATCH_SIZE - 1, totalFrames)
|
local endIdx = math.min(startIdx + BATCH_SIZE - 1, totalFrames)
|
||||||
print("Downloading batch: " .. startIdx .. " - " .. endIdx)
|
|
||||||
|
|
||||||
-- 构造要下载的 URL 列表(相对路径)
|
|
||||||
local urls = {}
|
local urls = {}
|
||||||
for i = startIdx, endIdx do
|
for i = startIdx, endIdx do
|
||||||
|
|
||||||
table.insert(urls, videoInfo.frame_urls[i])
|
table.insert(urls, videoInfo.frame_urls[i])
|
||||||
end
|
end
|
||||||
|
table.insert(initBatches, {
|
||||||
-- 请求打包
|
start = startIdx,
|
||||||
|
urls = urls
|
||||||
while true do
|
})
|
||||||
resp1,err = http.post(
|
|
||||||
server_url .. "/api/framepack",
|
|
||||||
textutils.serializeJSON({ urls = urls }),
|
|
||||||
{ ["Content-Type"] = "application/json" },
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
if resp1 then break end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if not resp1 then error("Failed to download framepack "..err) end
|
|
||||||
|
|
||||||
local binData = resp1.readAll()
|
|
||||||
print(#binData .. " bytes received")
|
|
||||||
resp1.close()
|
|
||||||
|
|
||||||
-- 解包
|
|
||||||
local batchFrames = unpackFramePack(binData)
|
|
||||||
for i = 1, #batchFrames do
|
|
||||||
allFrameData[startIdx + i - 1] = batchFrames[i]
|
|
||||||
end
|
|
||||||
|
|
||||||
print("Loaded batch: " .. #batchFrames .. " frames")
|
|
||||||
sleep(0.1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
print("Pre-caching first " .. totalFrames .. " frames (" .. #initBatches .. " batches)...")
|
||||||
|
|
||||||
|
-- 第二步:并发下载所有初始化批次
|
||||||
|
local initTasks = {}
|
||||||
|
for _, batch in ipairs(initBatches) do
|
||||||
|
table.insert(initTasks, function()
|
||||||
|
while true do
|
||||||
|
local resp = http.post({
|
||||||
|
url = server_url .. "/api/framepack?" .. batch.urls[1],
|
||||||
|
headers = { ["Content-Type"] = "application/json" },
|
||||||
|
body = textutils.serializeJSON({ urls = batch.urls }),
|
||||||
|
timeout = 3,
|
||||||
|
binary = true
|
||||||
|
})
|
||||||
|
|
||||||
|
if resp then
|
||||||
|
local binData = resp.readAll()
|
||||||
|
resp.close()
|
||||||
|
|
||||||
-- -- 预加载前N帧
|
local batchFrames = unpackFramePack(binData)
|
||||||
-- for i = 1, math.min(videoInfo.fps, #videoInfo.frame_urls) do
|
for idx = 1, #batchFrames do
|
||||||
|
local globalIdx = batch.start + idx - 1
|
||||||
|
allFrameData[globalIdx] = batchFrames[idx]
|
||||||
|
end
|
||||||
|
|
||||||
-- if frameData[i] then
|
print("Cached init batch: " .. batch.start .. " - " .. (batch.start + #batchFrames - 1))
|
||||||
-- local data = frameData[i]
|
break
|
||||||
-- local imgBin = {}
|
else
|
||||||
-- for j = 1, #data do
|
print("Retry init batch starting at " .. batch.start)
|
||||||
-- imgBin[#imgBin + 1] = data:byte(j)
|
sleep(0.5)
|
||||||
-- end
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 执行并发下载
|
||||||
|
parallel.waitForAll(table.unpack(initTasks))
|
||||||
|
|
||||||
-- local success, image = pcall(function()
|
print("Initial caching completed.")
|
||||||
-- return gpu.decodeImage(table.unpack(imgBin))
|
|
||||||
-- end)
|
|
||||||
|
|
||||||
-- if success then
|
|
||||||
-- print("Loaded frame "..i .."/"..#videoInfo.frame_urls)
|
|
||||||
|
|
||||||
-- frames[i] = image
|
|
||||||
|
|
||||||
-- frameData[i] = nil
|
|
||||||
-- data = nil
|
|
||||||
-- frameCount = frameCount + 1
|
|
||||||
-- else
|
|
||||||
-- print(image)
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- 播放循环
|
-- 播放循环
|
||||||
local frameDelay = tonumber(string.format("%.3f",1 / videoInfo.fps))
|
local frameDelay = tonumber(string.format("%.3f",1 / videoInfo.fps))
|
||||||
print("Starting playback (FPS: " .. videoInfo.fps .. ")")
|
print("Starting playback (FPS: " .. videoInfo.fps .. ")")
|
||||||
print(frameDelay * #videoInfo.frame_urls)
|
print(frameDelay * #videoInfo.frame_urls)
|
||||||
local starttime1 = os.clock()
|
local starttime1 = os.clock()
|
||||||
sleep(1)
|
sleep(4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -311,11 +304,6 @@ local function cacheAhead()
|
|||||||
table.insert(downloadTasks, function()
|
table.insert(downloadTasks, function()
|
||||||
print("Downloading batch: " .. batch.start .. " - " .. (batch.start + #batch.urls - 1))
|
print("Downloading batch: " .. batch.start .. " - " .. (batch.start + #batch.urls - 1))
|
||||||
while true do
|
while true do
|
||||||
-- local resp = http.post(
|
|
||||||
-- server_url .. "/api/framepack?"..batch.urls[1],
|
|
||||||
-- textutils.serializeJSON({ urls = batch.urls }),
|
|
||||||
-- { ["Content-Type"] = "application/json" }
|
|
||||||
-- )
|
|
||||||
local resp = http.post({
|
local resp = http.post({
|
||||||
url = server_url .. "/api/framepack?"..batch.urls[1],
|
url = server_url .. "/api/framepack?"..batch.urls[1],
|
||||||
headers = { ["Content-Type"] = "application/json" },
|
headers = { ["Content-Type"] = "application/json" },
|
||||||
@@ -361,15 +349,6 @@ local function cacheAhead()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- -- 音频播放协程
|
|
||||||
-- local function playAudio()
|
|
||||||
-- os.queueEvent("audio_start") -- 触发同步
|
|
||||||
-- shell.run("bg speakerlib play " ..
|
|
||||||
-- server_url .. videoInfo.audio_dfpwm_url .. " " ..
|
|
||||||
-- server_url .. videoInfo.audio_dfpwm_left_url .. " " ..
|
|
||||||
-- server_url .. videoInfo.audio_dfpwm_right_url)
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- 视频渲染协程
|
-- 视频渲染协程
|
||||||
local function renderVideo()
|
local function renderVideo()
|
||||||
local frameIndex2 = 0
|
local frameIndex2 = 0
|
||||||
|
|||||||
Reference in New Issue
Block a user