diff --git a/CloudServer/server.js b/CloudServer/server.js index d796e83..2935089 100644 --- a/CloudServer/server.js +++ b/CloudServer/server.js @@ -324,7 +324,7 @@ async function sendLiveWavChunksToStation(stationName, fallbackWs, task) { const sampleRate = 48000; const channels = 1; const bitsPerSample = 16; - const chunkDurationSec = 0.25; + const chunkDurationSec = 1.0; const chunkBytes = Math.max(4096, Math.floor(sampleRate * channels * (bitsPerSample / 8) * chunkDurationSec)); targetWs.send(JSON.stringify({ @@ -344,7 +344,7 @@ async function sendLiveWavChunksToStation(stationName, fallbackWs, task) { const ffmpegArgs = ['-hide_banner', '-loglevel', 'error']; if (loop) ffmpegArgs.push('-stream_loop', '-1'); ffmpegArgs.push('-re', '-i', sourcePath, '-f', 's16le', '-acodec', 'pcm_s16le', '-ac', String(channels), '-ar', String(sampleRate), 'pipe:1'); - log('INFO', `Live WAV chunk stream start for ${stationName}: ${path.basename(sourcePath)}${loop ? ' (loop)' : ''}`); + log('INFO', `Live WAV chunk stream start for ${stationName}: ${path.basename(sourcePath)}${loop ? ' (loop)' : ''} chunk=${chunkDurationSec}s`); return await new Promise((resolve, reject) => { let stderr = ''; diff --git a/station_broadcast.lua b/station_broadcast.lua index 94fe81e..afe3278 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -799,15 +799,29 @@ end local function pushWavChunkToSpeakers(payload, playSeq) local controller = Peripherals.speakers and Peripherals.speakers[1] or nil if controller and type(controller.speakWavAll) == "function" then + local retryCount = 0 while true do if shouldStop(playSeq) then return false end local ok = false + local queueSize = -1 + local isPlaying = false pcall(function() ok = controller.speakWavAll(payload, CONFIG.AUDIO_VOLUME) + if type(controller.speakQueueSize) == "function" then + queueSize = tonumber(controller.speakQueueSize()) or -1 + end + if type(controller.speakIsPlaying) == "function" then + isPlaying = controller.speakIsPlaying() and true or false + end end) if ok then + Utils.log("INFO", string.format("WAV chunk accepted: bytes=%d queue=%d playing=%s", #payload, queueSize, tostring(isPlaying))) return true end + retryCount = retryCount + 1 + if retryCount == 1 or retryCount % 20 == 0 then + Utils.log("WARN", string.format("WAV chunk waiting: bytes=%d queue=%d playing=%s retries=%d", #payload, queueSize, tostring(isPlaying), retryCount)) + end if not waitForInterruptibleDelay(playSeq, 0.05) then return false end @@ -820,6 +834,7 @@ local function pushWavChunkToSpeakers(payload, playSeq) if name then pending[name] = sp end end + local retryCount = 0 while next(pending) do if shouldStop(playSeq) then return false end for name, sp in pairs(pending) do @@ -831,6 +846,18 @@ local function pushWavChunkToSpeakers(payload, playSeq) end) if ok then pending[name] = nil end end + if next(pending) then + retryCount = retryCount + 1 + if retryCount == 1 or retryCount % 20 == 0 then + local pendingCount = 0 + for _ in pairs(pending) do + pendingCount = pendingCount + 1 + end + Utils.log("WARN", string.format("WAV chunk waiting on %d speakers: bytes=%d retries=%d", pendingCount, #payload, retryCount)) + end + else + Utils.log("INFO", string.format("WAV chunk accepted by fallback speakers: bytes=%d", #payload)) + end if next(pending) and not waitForInterruptibleDelay(playSeq, 0.05) then return false end