From d86c74f0ccd8d15ff06052515177eed1619c55e4 Mon Sep 17 00:00:00 2001 From: HenryDu8133 <813367384@qq.com> Date: Fri, 31 Jul 2026 22:03:35 +0800 Subject: [PATCH] fix(music): stream live dfpwm instead of pcm Move live music streaming back onto the proven DFPWM playback path and silently ignore legacy train_arrival, train_departure, and play_sequence messages from older station clients so they no longer spam logs. --- CloudServer/server.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/CloudServer/server.js b/CloudServer/server.js index 2755f45..e70cbab 100644 --- a/CloudServer/server.js +++ b/CloudServer/server.js @@ -286,13 +286,13 @@ async function sendAudioBufferToStation(stationName, fallbackWs, task) { return { audioId, cancelled: false, durationSec }; } -async function sendPcmStreamToStation(stationName, fallbackWs, task) { +async function sendLiveDfpwmToStation(stationName, fallbackWs, task) { const targetWs = getStationWs(stationName, fallbackWs); if (!targetWs) throw new Error(`Station "${stationName}" not connected`); const sourcePath = String(task.sourcePath || '').trim(); - if (!sourcePath) throw new Error('PCM stream sourcePath required'); - if (!fs.existsSync(sourcePath)) throw new Error(`PCM source missing: ${sourcePath}`); + if (!sourcePath) throw new Error('Live DFPWM sourcePath required'); + if (!fs.existsSync(sourcePath)) throw new Error(`Live DFPWM source missing: ${sourcePath}`); const audioId = String(task.audioId || `${Date.now()}-${Math.random().toString(16).slice(2)}`); const durationSec = Number(task.durationSec || 0); @@ -306,8 +306,7 @@ async function sendPcmStreamToStation(stationName, fallbackWs, task) { byteLength: 0, sampleRate: 48000, channels: 1, - audioFormat: 'pcm', - pcmEncoding: 's8', + audioFormat: 'dfpwm', loop, priority: Number(task.priority || 0), interruptMode: task.interruptMode || getInterruptModeForPriority(Number(task.priority || 0)), @@ -317,12 +316,13 @@ async function sendPcmStreamToStation(stationName, fallbackWs, task) { const ffmpegArgs = ['-hide_banner', '-loglevel', 'error']; if (loop) ffmpegArgs.push('-stream_loop', '-1'); ffmpegArgs.push('-re', '-i', sourcePath, '-f', 's8', '-acodec', 'pcm_s8', '-ac', '1', '-ar', '48000', 'pipe:1'); - log('INFO', `PCM music stream start for ${stationName}: ${path.basename(sourcePath)}${loop ? ' (loop)' : ''}`); + log('INFO', `Live DFPWM music stream start for ${stationName}: ${path.basename(sourcePath)}${loop ? ' (loop)' : ''}`); return await new Promise((resolve, reject) => { let stderr = ''; let settled = false; let proc = null; + const encoder = new dfpwm.Encoder(); const finish = (result, error) => { if (settled) return; @@ -376,7 +376,10 @@ async function sendPcmStreamToStation(stationName, fallbackWs, task) { } try { - ws.send(chunk); + const encoded = encoder.encode(Buffer.from(chunk)); + if (encoded && encoded.length > 0) { + ws.send(encoded); + } } catch (err) { finish(null, err); } @@ -392,7 +395,7 @@ async function sendPcmStreamToStation(stationName, fallbackWs, task) { proc.on('close', (code, signal) => { const cancelled = token && token.cancelled; - log(cancelled ? 'INFO' : 'SUCCESS', `PCM music stream end for ${stationName}: ${path.basename(sourcePath)}${cancelled ? ' (cancelled)' : ''}`); + log(cancelled ? 'INFO' : 'SUCCESS', `Live DFPWM music stream end for ${stationName}: ${path.basename(sourcePath)}${cancelled ? ' (cancelled)' : ''}`); if (!cancelled && code !== 0) { finish(null, new Error((stderr || `ffmpeg exited with code ${code ?? 'unknown'} signal ${signal ?? 'none'}`).trim())); return; @@ -584,8 +587,8 @@ async function processStationAudioQueue(stationName, fallbackWs) { try { if (task.consoleStreamStart) broadcastToConsole(task.consoleStreamStart); - const result = task.audioFormat === 'pcm' - ? await sendPcmStreamToStation(cleanStation, fallbackWs, task) + const result = task.audioFormat === 'dfpwm-live' + ? await sendLiveDfpwmToStation(cleanStation, fallbackWs, task) : await sendAudioBufferToStation(cleanStation, fallbackWs, task); if (task.consoleStreamEnd) { if (result.cancelled) { @@ -1370,6 +1373,10 @@ function handleMessage(ws, data) { case 'station_register': handleStationRegister(ws, data); break; + case 'train_arrival': + case 'train_departure': + case 'play_sequence': + break; case 'request_station_time': handleStationTimeRequest(ws, data); break; @@ -2379,7 +2386,7 @@ app.post('/api/music/start', express.json(), (req, res) => { if (playbackAudio.sourcePath) { enqueueStationAudioTask(name, currentWs, { - audioFormat: 'pcm', + audioFormat: 'dfpwm-live', sourcePath: playbackAudio.sourcePath, durationSec: playbackAudio.durationSec, priority: -1,