diff --git a/routes/dmr.py b/routes/dmr.py index 8878219..ec4db2d 100644 --- a/routes/dmr.py +++ b/routes/dmr.py @@ -37,14 +37,19 @@ dmr_bp = Blueprint('dmr', __name__, url_prefix='/dmr') dmr_rtl_process: Optional[subprocess.Popen] = None dmr_dsd_process: Optional[subprocess.Popen] = None -dmr_audio_process: Optional[subprocess.Popen] = None dmr_thread: Optional[threading.Thread] = None dmr_running = False -dmr_audio_running = False +dmr_has_audio = False # True when ffmpeg available and dsd outputs audio dmr_lock = threading.Lock() dmr_queue: queue.Queue = queue.Queue(maxsize=QUEUE_MAX_SIZE) dmr_active_device: Optional[int] = None +# Audio mux: the sole reader of dsd-fme stdout. Writes to an ffmpeg +# stdin when a streaming client is connected, discards otherwise. +# This prevents dsd-fme from blocking on stdout (which would also +# freeze stderr / text data output). +_active_ffmpeg_stdin: Optional[object] = None # set by stream endpoint + VALID_PROTOCOLS = ['auto', 'dmr', 'p25', 'nxdn', 'dstar', 'provoice'] # Classic dsd flags @@ -209,40 +214,40 @@ _HEARTBEAT_INTERVAL = 3.0 # seconds between heartbeats when decoder is idle _SILENCE_CHUNK = b'\x00' * 1600 -def _audio_bridge(dsd_stdout, ffmpeg_stdin): - """Bridge DSD audio output to ffmpeg, inserting silence during gaps. +def _dsd_audio_mux(dsd_stdout): + """Mux thread: sole reader of dsd-fme stdout. - 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 ``