fix: use pcall to uncapped AUDIO_VOLUME for HQ speakers while keeping 3.0 fallback for vanilla speakers

This commit is contained in:
2026-08-02 08:53:49 +08:00
parent 832658ad58
commit ac8405e300
2 changed files with 29 additions and 15 deletions
+5 -6
View File
@@ -1289,7 +1289,7 @@ function buildSequenceWavFile(seq) {
const inputs = files.map(f => `-i "${f}"`).join(' '); const inputs = files.map(f => `-i "${f}"`).join(' ');
const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';'); const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';');
const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1,volume=5.0[a]`; const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1[a]`;
const filterComplex = `${filterResamples};${filterConcat}`; const filterComplex = `${filterResamples};${filterConcat}`;
try { try {
@@ -1330,7 +1330,7 @@ function runFfmpegRtmpPush(streamName, seq) {
const tmpAacPath = path.join(tmpDir, `prebuild-${Date.now()}-${Math.random().toString(16).slice(2)}.aac`); const tmpAacPath = path.join(tmpDir, `prebuild-${Date.now()}-${Math.random().toString(16).slice(2)}.aac`);
const inputs = files.map(f => `-i "${f}"`).join(' '); const inputs = files.map(f => `-i "${f}"`).join(' ');
const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';'); const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';');
const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1,volume=5.0[a]`; const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1[a]`;
const filterComplex = `${filterResamples};${filterConcat}`; const filterComplex = `${filterResamples};${filterConcat}`;
const buildArgs = [ const buildArgs = [
@@ -1425,7 +1425,7 @@ function runFfmpegRtmpPush(streamName, seq) {
} }
const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';'); const filterResamples = files.map((_, i) => `[${i}:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a${i}]`).join(';');
const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1,volume=5.0[a]`; const filterConcat = files.map((_, i) => `[a${i}]`).join('') + `concat=n=${files.length}:v=0:a=1[a]`;
const filterComplex = `${filterResamples};${filterConcat}`; const filterComplex = `${filterResamples};${filterConcat}`;
const args = [ const args = [
@@ -2086,8 +2086,7 @@ function convertToDfpwm(filePath) {
// -f s8: signed 8-bit pcm // -f s8: signed 8-bit pcm
// -ac 1: mono // -ac 1: mono
// -ar 48000: 48kHz // -ar 48000: 48kHz
// -filter:a volume=5.0: boost volume significantly execSync(`ffmpeg -y -v quiet -i "${filePath}" -f s8 -acodec pcm_s8 -ac 1 -ar 48000 "${rawPath}"`);
execSync(`ffmpeg -y -v quiet -i "${filePath}" -filter:a volume=5.0 -f s8 -acodec pcm_s8 -ac 1 -ar 48000 "${rawPath}"`);
if (fs.existsSync(rawPath)) { if (fs.existsSync(rawPath)) {
const buffer = fs.readFileSync(rawPath); const buffer = fs.readFileSync(rawPath);
@@ -2715,7 +2714,7 @@ function buildTempBroadcastFromWav(prefixWavPath, contentWavPath) {
const filterComplex = [ const filterComplex = [
'[0:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a0]', '[0:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a0]',
'[1:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a1]', '[1:a]aformat=sample_rates=48000:channel_layouts=mono,aresample=48000[a1]',
'[a0][a1]concat=n=2:v=0:a=1,volume=5.0[a]' '[a0][a1]concat=n=2:v=0:a=1[a]'
].join(';'); ].join(';');
execSync(`ffmpeg -hide_banner -loglevel error -y -i "${prefixWavPath}" -i "${contentWavPath}" -filter_complex "${filterComplex}" -map "[a]" -ac 1 -ar 48000 -c:a pcm_s16le "${outWavPath}"`); execSync(`ffmpeg -hide_banner -loglevel error -y -i "${prefixWavPath}" -i "${contentWavPath}" -filter_complex "${filterComplex}" -map "[a]" -ac 1 -ar 48000 -c:a pcm_s16le "${outWavPath}"`);
+24 -9
View File
@@ -1127,10 +1127,15 @@ local function queueSamplesSynchronized(samples, volume, playSeq)
if shouldStop(playSeq) then return false end if shouldStop(playSeq) then return false end
for name, sp in pairs(pending) do for name, sp in pairs(pending) do
local ok = false local ok = false
pcall(function() local success, err = pcall(function()
local safeVolume = math.min(volume or 3, 3.0) ok = sp.playAudio(samples, volume)
ok = sp.playAudio(samples, safeVolume)
end) end)
if not success then
-- Fallback for vanilla speakers which throw an error if volume > 3.0
pcall(function()
ok = sp.playAudio(samples, 3.0)
end)
end
if ok then if ok then
pending[name] = nil pending[name] = nil
end end
@@ -1161,12 +1166,18 @@ local function playChunkOnSpeakers(samples, volume, playSeq, waitForDrain)
if shouldStop(playSeq) then return false end if shouldStop(playSeq) then return false end
for name, sp in pairs(pending) do for name, sp in pairs(pending) do
local ok = false local ok = false
pcall(function() local success, err = pcall(function()
if type(sp.playAudio) == "function" then if type(sp.playAudio) == "function" then
local safeVolume = math.min(volume or 3, 3.0) ok = sp.playAudio(samples, volume)
ok = sp.playAudio(samples, safeVolume)
end end
end) end)
if not success then
pcall(function()
if type(sp.playAudio) == "function" then
ok = sp.playAudio(samples, 3.0)
end
end)
end
if ok then if ok then
usedNativePath = true usedNativePath = true
pending[name] = nil pending[name] = nil
@@ -1189,10 +1200,14 @@ local function playChunkOnSpeakers(samples, volume, playSeq, waitForDrain)
while true do while true do
if shouldStop(playSeq) then return false end if shouldStop(playSeq) then return false end
local ok = false local ok = false
pcall(function() local success, err = pcall(function()
local safeVolume = math.min(volume or 3, 3.0) ok = controller.playAudioAll(samples, volume)
ok = controller.playAudioAll(samples, safeVolume)
end) end)
if not success then
pcall(function()
ok = controller.playAudioAll(samples, 3.0)
end)
end
if ok then break end if ok then break end
local ev = { os.pullEvent() } local ev = { os.pullEvent() }
if ev[1] == "audio_interrupt" and tonumber(ev[2]) and tonumber(ev[2]) >= playSeq then if ev[1] == "audio_interrupt" and tonumber(ev[2]) and tonumber(ev[2]) >= playSeq then