From fce66a6a60d27b0ebcc796d8b996a263d857a5bf Mon Sep 17 00:00:00 2001 From: Smittix Date: Mon, 9 Feb 2026 18:14:33 +0000 Subject: [PATCH] Fix DMR audio stream failing with "no supported source found" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Digital voice is intermittent — dsd-fme only outputs PCM during active voice transmissions. Without input, ffmpeg never wrote the WAV header and the browser got an empty response. Add an audio bridge thread that feeds 100ms silence chunks during voice gaps so ffmpeg always has input and the browser receives a continuous WAV stream. Add auto-reconnect on the frontend if the audio stream drops while the decoder is running. Co-Authored-By: Claude Opus 4.6 --- routes/dmr.py | 65 +++++++++++++++++++++++++++++++++++------- static/js/modes/dmr.js | 13 ++++++++- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/routes/dmr.py b/routes/dmr.py index bf368e9..8878219 100644 --- a/routes/dmr.py +++ b/routes/dmr.py @@ -205,6 +205,45 @@ def parse_dsd_output(line: str) -> dict | None: _HEARTBEAT_INTERVAL = 3.0 # seconds between heartbeats when decoder is idle +# 100ms of silence at 8kHz 16-bit mono = 1600 bytes +_SILENCE_CHUNK = b'\x00' * 1600 + + +def _audio_bridge(dsd_stdout, ffmpeg_stdin): + """Bridge DSD audio output to ffmpeg, inserting silence during gaps. + + Digital voice is intermittent — the decoder only outputs PCM during + active voice transmissions. Without this bridge, ffmpeg would block + waiting for its first input bytes and never write the WAV header, + causing the browser ``