diff --git a/CloudServer/server.js b/CloudServer/server.js index 5a19c08..4409a2d 100644 --- a/CloudServer/server.js +++ b/CloudServer/server.js @@ -244,6 +244,7 @@ async function sendAudioBufferToStation(stationName, fallbackWs, task) { channels: Number(task.channels || 1), audioFormat, streamUrl, + loop: !!task.loop, priority: Number(task.priority || 0), interruptMode: task.interruptMode || getInterruptModeForPriority(Number(task.priority || 0)), source: task.source || 'unknown' @@ -2376,6 +2377,11 @@ app.post('/api/music/start', express.json(), (req, res) => { stopStationMusic(name, ws); stationMusicStates.set(name, { enabled: true, track, loop }); + const streamName = getStationStreamName(name); + const hlsUrl = HLS_OUTPUT_MODE === 'local' + ? getLocalHlsUrlForRequest(streamName, req) + : getStationHlsUrlForRequest(streamName, req); + const enqueueOnce = () => { const currentWs = getStationWs(name); if (!currentWs || currentWs.readyState !== WebSocket.OPEN) { @@ -2384,6 +2390,24 @@ app.post('/api/music/start', express.json(), (req, res) => { return; } + if (HLS_ENABLE) { + enqueueHlsPush(name, [track]); + enqueueStationAudioTask(name, currentWs, { + audioFormat: 'hls', + streamUrl: hlsUrl, + durationSec: playbackAudio.durationSec, + priority: -1, + interruptMode: 'none', + source: 'music', + loop, + audioId: `music-${track}-${name}-${Date.now()}`, + requeueOnPreempt: true, + consoleStreamStart: { type: 'stream_start', station: name, seq: [`MUSIC:${track}`], streamName, hlsUrl }, + consoleStreamEnd: { type: 'stream_end', station: name } + }); + return; + } + enqueueStationAudioTask(name, currentWs, { audioFormat: playbackAudio.audioFormat, buffer: playbackAudio.buffer, @@ -2392,23 +2416,11 @@ app.post('/api/music/start', express.json(), (req, res) => { priority: -1, interruptMode: 'none', source: 'music', + loop, audioId: `music-${track}-${name}-${Date.now()}`, requeueOnPreempt: true, - consoleStreamStart: { type: 'stream_start', station: name, seq: [`MUSIC:${track}`], streamName: getStationStreamName(name), hlsUrl: getStationHlsUrl(getStationStreamName(name)) }, - consoleStreamEnd: { type: 'stream_end', station: name }, - onDone: (info) => { - const st = stationMusicStates.get(name); - if (!st || !st.enabled) return; - if (st.track !== track) return; - if (!st.loop) return; - // Only stop if cancelled by something else (like stopMusic or higher priority) - if (info && info.cancelled) { - // If it was just preempted, enqueueStationAudioTask handles the re-insertion - // If it was cancelled by stopStationMusic, st.enabled will be false - return; - } - enqueueOnce(); - } + consoleStreamStart: { type: 'stream_start', station: name, seq: [`MUSIC:${track}`], streamName, hlsUrl }, + consoleStreamEnd: { type: 'stream_end', station: name } }); }; diff --git a/install_station_broadcast.lua b/install_station_broadcast.lua index f3e7184..922babb 100644 --- a/install_station_broadcast.lua +++ b/install_station_broadcast.lua @@ -1,4 +1,4 @@ -local STATION_BROADCAST_URL = "https://gitea.fse-media.group/Henry_Du/CC-StationBroadcast/raw/commit/e4b4fa5cdb2bc42279fd87098fef0d27a90e23d5/station_broadcast.lua" +local STATION_BROADCAST_URL = "https://gitea.fse-media.group/Henry_Du/CC-StationBroadcast/raw/branch/main/station_broadcast.lua" local function fetch(url) if not http then diff --git a/station_broadcast.lua b/station_broadcast.lua index c159c1b..5f6c878 100644 --- a/station_broadcast.lua +++ b/station_broadcast.lua @@ -718,10 +718,18 @@ local function playHqAudioItem(item) local controller = Peripherals.speakers[1] local called = false + local loopEnabled = item.loop and true or false if controller then + pcall(function() + if type(controller.setLoopingAll) == "function" then + controller.setLoopingAll(loopEnabled) + end + end) local ok, result = pcall(function() - if format == "wav" and type(controller.speakWavAll) == "function" then + if format == "hls" and type(controller.speakHLSAll) == "function" then + return controller.speakHLSAll(payload, CONFIG.AUDIO_VOLUME) + elseif format == "wav" and type(controller.speakWavAll) == "function" then return controller.speakWavAll(payload, CONFIG.AUDIO_VOLUME) elseif format == "mp3" and type(controller.speakMp3All) == "function" then return controller.speakMp3All(payload, CONFIG.AUDIO_VOLUME) @@ -738,8 +746,15 @@ local function playHqAudioItem(item) if not called then for _, sp in ipairs(Peripherals.speakers) do + pcall(function() + if type(sp.setLooping) == "function" then + sp.setLooping(loopEnabled) + end + end) local ok, result = pcall(function() - if format == "wav" and type(sp.speakWav) == "function" then + if format == "hls" and type(sp.speakHLS) == "function" then + return sp.speakHLS(payload, CONFIG.AUDIO_VOLUME) + elseif format == "wav" and type(sp.speakWav) == "function" then return sp.speakWav(payload, CONFIG.AUDIO_VOLUME) elseif format == "mp3" and type(sp.speakMp3) == "function" then return sp.speakMp3(payload, CONFIG.AUDIO_VOLUME) @@ -811,7 +826,7 @@ end function Audio.playItem(item) local format = tostring(item.audioFormat or "dfpwm"):lower() - if format == "wav" or format == "file" or format == "stream" then + if format == "wav" or format == "file" or format == "stream" or format == "hls" then return playHqAudioItem(item) end return Audio.playDfpwmItem(item) @@ -1092,6 +1107,7 @@ function Network.messageLoop() audioData = table.concat(rx.chunks or {}), audioFormat = rx.audioFormat or "wav", priority = rx.priority, + loop = rx.loop and true or false, source = rx.source, audioId = rx.audioId }) @@ -1129,15 +1145,17 @@ function Network.messageLoop() expectedBytes = tonumber(data.byteLength) or 0, receivedBytes = 0, priority = priority, + loop = data.loop and true or false, source = data.source or data.category, audioFormat = audioFormat } - if audioFormat == "stream" and streamUrl and streamUrl ~= "" then + if (audioFormat == "stream" or audioFormat == "hls") and streamUrl and streamUrl ~= "" then Audio.enqueueItem({ audioData = streamUrl, - audioFormat = "stream", + audioFormat = audioFormat, priority = priority, + loop = State.audioRx.loop, source = State.audioRx.source, audioId = data.audioId }) diff --git a/update_station_broadcast.lua b/update_station_broadcast.lua index fa04ce9..e3fa4a4 100644 --- a/update_station_broadcast.lua +++ b/update_station_broadcast.lua @@ -1,4 +1,4 @@ -local STATION_BROADCAST_URL = "https://gitea.fse-media.group/Henry_Du/CC-StationBroadcast/raw/commit/e4b4fa5cdb2bc42279fd87098fef0d27a90e23d5/station_broadcast.lua" +local STATION_BROADCAST_URL = "https://gitea.fse-media.group/Henry_Du/CC-StationBroadcast/raw/branch/main/station_broadcast.lua" local function fetch(url) if not http then