Timeout audio stream if no first chunk

This commit is contained in:
Smittix
2026-02-04 10:53:03 +00:00
parent 4042d0e5f1
commit 33090419df

View File

@@ -914,29 +914,35 @@ def stream_audio() -> Response:
if not audio_running or not audio_process:
return Response(b'', mimetype='audio/mpeg', status=204)
def generate():
# Capture local reference to avoid race condition with stop
proc = audio_process
if not proc or not proc.stdout:
return
try:
while audio_running and proc.poll() is None:
# Use select to avoid blocking forever
ready, _, _ = select.select([proc.stdout], [], [], 2.0)
if ready:
chunk = proc.stdout.read(4096)
if chunk:
yield chunk
else:
break
else:
# Timeout - check if process died
if proc.poll() is not None:
break
except GeneratorExit:
pass
except Exception as e:
logger.error(f"Audio stream error: {e}")
def generate():
# Capture local reference to avoid race condition with stop
proc = audio_process
if not proc or not proc.stdout:
return
try:
# First byte timeout to avoid hanging clients forever
first_chunk_deadline = time.time() + 3.0
while audio_running and proc.poll() is None:
# Use select to avoid blocking forever
ready, _, _ = select.select([proc.stdout], [], [], 2.0)
if ready:
chunk = proc.stdout.read(4096)
if chunk:
yield chunk
else:
break
else:
# If no data arrives shortly after start, exit so caller can retry
if time.time() > first_chunk_deadline:
logger.warning("Audio stream timed out waiting for first chunk")
break
# Timeout - check if process died
if proc.poll() is not None:
break
except GeneratorExit:
pass
except Exception as e:
logger.error(f"Audio stream error: {e}")
return Response(
generate(),