mirror of
https://github.com/smittix/intercept.git
synced 2026-04-24 06:40:00 -07:00
Add diagnostic logging for SDR device audio debugging
- Log rtl_fm stderr to /tmp/rtl_fm_stderr.log instead of /dev/null - Add detailed logging for audio start requests and parameters - Log audio stream status and bytes transferred - Help diagnose SDR1 airband audio issues Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -439,7 +439,9 @@ def _start_audio_stream(frequency: float, modulation: str):
|
||||
|
||||
try:
|
||||
# Use shell pipe for reliable streaming (Python subprocess piping can be unreliable)
|
||||
shell_cmd = f"{' '.join(sdr_cmd)} 2>/dev/null | {' '.join(encoder_cmd)}"
|
||||
# Log stderr to a temp file so we can see any errors from rtl_fm
|
||||
stderr_log = '/tmp/rtl_fm_stderr.log'
|
||||
shell_cmd = f"{' '.join(sdr_cmd)} 2>{stderr_log} | {' '.join(encoder_cmd)}"
|
||||
logger.info(f"Starting audio pipeline: {shell_cmd}")
|
||||
|
||||
audio_rtl_process = None # Not used in shell mode
|
||||
@@ -456,10 +458,25 @@ def _start_audio_stream(frequency: float, modulation: str):
|
||||
time.sleep(0.3)
|
||||
|
||||
if audio_process.poll() is not None:
|
||||
stderr = audio_process.stderr.read().decode() if audio_process.stderr else ''
|
||||
logger.error(f"Audio pipeline exited immediately: {stderr}")
|
||||
# Read rtl_fm stderr from temp file
|
||||
rtl_stderr = ''
|
||||
try:
|
||||
with open(stderr_log, 'r') as f:
|
||||
rtl_stderr = f.read().strip()
|
||||
except:
|
||||
pass
|
||||
logger.error(f"Audio pipeline exited immediately. rtl_fm stderr: {rtl_stderr}")
|
||||
return
|
||||
|
||||
# Also check for rtl_fm errors even if process is still running
|
||||
try:
|
||||
with open(stderr_log, 'r') as f:
|
||||
rtl_stderr = f.read().strip()
|
||||
if rtl_stderr:
|
||||
logger.warning(f"rtl_fm stderr: {rtl_stderr}")
|
||||
except:
|
||||
pass
|
||||
|
||||
audio_running = True
|
||||
audio_frequency = frequency
|
||||
audio_modulation = modulation
|
||||
@@ -775,7 +792,7 @@ def start_audio() -> Response:
|
||||
"""Start audio at specific frequency (manual mode)."""
|
||||
global scanner_running
|
||||
|
||||
logger.info("Audio start request received")
|
||||
logger.info(f"Audio start request received: {request.json}")
|
||||
|
||||
# Stop scanner if running
|
||||
if scanner_running:
|
||||
@@ -823,6 +840,8 @@ def start_audio() -> Response:
|
||||
scanner_config['device'] = device
|
||||
scanner_config['sdr_type'] = sdr_type
|
||||
|
||||
logger.info(f"Starting audio: freq={frequency} MHz, mod={modulation}, device={device}, gain={gain}, squelch={squelch}")
|
||||
|
||||
_start_audio_stream(frequency, modulation)
|
||||
|
||||
if audio_running:
|
||||
@@ -858,6 +877,8 @@ def audio_status() -> Response:
|
||||
@listening_post_bp.route('/audio/stream')
|
||||
def stream_audio() -> Response:
|
||||
"""Stream MP3 audio."""
|
||||
logger.info(f"Audio stream requested - running: {audio_running}, process: {audio_process is not None}")
|
||||
|
||||
# Wait for audio to be ready (up to 2 seconds for modulation/squelch changes)
|
||||
for _ in range(40):
|
||||
if audio_running and audio_process:
|
||||
@@ -865,9 +886,24 @@ def stream_audio() -> Response:
|
||||
time.sleep(0.05)
|
||||
|
||||
if not audio_running or not audio_process:
|
||||
logger.warning("Audio stream requested but no audio running")
|
||||
return Response(b'', mimetype='audio/mpeg', status=204)
|
||||
|
||||
# Check if process is still alive
|
||||
poll_result = audio_process.poll()
|
||||
logger.info(f"Audio process poll result: {poll_result} (None means running)")
|
||||
|
||||
# Check for rtl_fm errors
|
||||
try:
|
||||
with open('/tmp/rtl_fm_stderr.log', 'r') as f:
|
||||
rtl_stderr = f.read().strip()
|
||||
if rtl_stderr:
|
||||
logger.warning(f"rtl_fm stderr (at stream request): {rtl_stderr}")
|
||||
except:
|
||||
pass
|
||||
|
||||
def generate():
|
||||
bytes_sent = 0
|
||||
try:
|
||||
while audio_running and audio_process and audio_process.poll() is None:
|
||||
# Use select to avoid blocking forever
|
||||
@@ -875,13 +911,21 @@ def stream_audio() -> Response:
|
||||
if ready:
|
||||
chunk = audio_process.stdout.read(4096)
|
||||
if chunk:
|
||||
bytes_sent += len(chunk)
|
||||
yield chunk
|
||||
else:
|
||||
logger.warning(f"Audio stream: empty chunk after {bytes_sent} bytes")
|
||||
break
|
||||
else:
|
||||
# Timeout - check if process died
|
||||
if audio_process.poll() is not None:
|
||||
logger.warning(f"Audio process died during streaming after {bytes_sent} bytes")
|
||||
break
|
||||
logger.info(f"Audio stream ended - sent {bytes_sent} bytes, running={audio_running}, poll={audio_process.poll() if audio_process else 'N/A'}")
|
||||
except GeneratorExit:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
logger.info(f"Audio stream: client disconnected after {bytes_sent} bytes")
|
||||
except Exception as e:
|
||||
logger.error(f"Audio stream error: {e}")
|
||||
|
||||
return Response(
|
||||
generate(),
|
||||
|
||||
Reference in New Issue
Block a user