Refactor MediaMTX configuration and enhance RTSP streaming logging
- Removed outdated timeout settings from MediaMTX configuration for improved stream handling. - Updated CameraStreamer class to include detailed logging for RTSP streaming state and frame dimension checks. - Added environment variable support for configuring MediaMTX host, enhancing flexibility in deployment.
This commit is contained in:
@@ -86,6 +86,9 @@ class CameraStreamer:
|
||||
|
||||
# RTSP settings
|
||||
self.rtsp_fps = 15.0 # RTSP FPS (can be higher than MJPEG preview)
|
||||
# Use MEDIAMTX_HOST env var if set, otherwise default to localhost
|
||||
# Note: If API uses network_mode: host, MediaMTX container ports are exposed to host
|
||||
# So localhost should work, but MediaMTX must be accessible on that port
|
||||
self.rtsp_host = os.getenv("MEDIAMTX_HOST", "localhost")
|
||||
self.rtsp_port = int(os.getenv("MEDIAMTX_RTSP_PORT", "8554"))
|
||||
self._rtsp_process: Optional[subprocess.Popen] = None
|
||||
@@ -525,15 +528,27 @@ class CameraStreamer:
|
||||
# Wait for frame dimensions to be set
|
||||
timeout = 10.0 # Wait up to 10 seconds for first frame
|
||||
start_time = time.time()
|
||||
self.logger.info(f"Waiting for frame dimensions (current: {self._rtsp_frame_width}x{self._rtsp_frame_height})...")
|
||||
while self._rtsp_frame_width == 0 and (time.time() - start_time) < timeout:
|
||||
if self._stop_rtsp_event.is_set():
|
||||
self.logger.info("RTSP streaming stopped before frame dimensions were available")
|
||||
return
|
||||
time.sleep(0.1)
|
||||
# Check if streaming is actually producing frames
|
||||
if not self.streaming:
|
||||
self.logger.error("Camera streaming stopped, cannot start RTSP")
|
||||
self.rtsp_streaming = False
|
||||
return
|
||||
time.sleep(0.5)
|
||||
elapsed = time.time() - start_time
|
||||
if elapsed > 2 and int(elapsed) % 2 == 0: # Log every 2 seconds
|
||||
self.logger.debug(f"Still waiting for frame dimensions... ({elapsed:.1f}s elapsed, queue size: {self._rtsp_frame_queue.qsize()})")
|
||||
|
||||
if self._rtsp_frame_width == 0:
|
||||
self.logger.error("Could not determine frame dimensions for RTSP streaming")
|
||||
self.logger.error(f"Could not determine frame dimensions for RTSP streaming after {timeout}s. Stream active: {self.streaming}, Queue size: {self._rtsp_frame_queue.qsize()}")
|
||||
self.rtsp_streaming = False
|
||||
return
|
||||
|
||||
self.logger.info(f"Frame dimensions available: {self._rtsp_frame_width}x{self._rtsp_frame_height}")
|
||||
|
||||
rtsp_url = f"rtsp://{self.rtsp_host}:{self.rtsp_port}/{self.camera_config.name}"
|
||||
self.logger.info(f"Publishing RTSP stream to {rtsp_url} with dimensions {self._rtsp_frame_width}x{self._rtsp_frame_height} @ {self.rtsp_fps}fps")
|
||||
|
||||
87
diagnose_rtsp.sh
Executable file
87
diagnose_rtsp.sh
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/bin/bash
|
||||
# Comprehensive RTSP diagnostic script
|
||||
|
||||
echo "=========================================="
|
||||
echo "RTSP Streaming Diagnostic"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
|
||||
echo "1. Checking API health..."
|
||||
API_HEALTH=$(curl -s http://exp-dash:8000/health 2>&1)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo " ✅ API is responding"
|
||||
else
|
||||
echo " ❌ API is not responding"
|
||||
echo " Response: $API_HEALTH"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "2. Checking camera status..."
|
||||
CAMERA_STATUS=$(curl -s http://exp-dash:8000/cameras/camera1/status 2>&1)
|
||||
echo "$CAMERA_STATUS" | python3 -m json.tool 2>/dev/null || echo "$CAMERA_STATUS"
|
||||
echo ""
|
||||
|
||||
echo "3. Starting camera streaming..."
|
||||
curl -X POST http://exp-dash:8000/cameras/camera1/start-stream 2>&1 | python3 -m json.tool 2>/dev/null || curl -X POST http://exp-dash:8000/cameras/camera1/start-stream 2>&1
|
||||
echo ""
|
||||
|
||||
echo "4. Waiting for stream to initialize (8 seconds)..."
|
||||
sleep 8
|
||||
|
||||
echo "5. Starting RTSP streaming..."
|
||||
RTSP_RESPONSE=$(curl -s -X POST http://exp-dash:8000/cameras/camera1/start-rtsp)
|
||||
echo "$RTSP_RESPONSE" | python3 -m json.tool 2>/dev/null || echo "$RTSP_RESPONSE"
|
||||
echo ""
|
||||
|
||||
echo "6. Waiting for RTSP to initialize (10 seconds)..."
|
||||
sleep 10
|
||||
|
||||
echo "7. Checking for FFmpeg process..."
|
||||
FFMPEG_PID=$(docker compose exec api bash -c "ps aux | grep '[f]fmpeg' | grep -v grep | awk '{print \$2}'" 2>/dev/null | head -1)
|
||||
if [ -n "$FFMPEG_PID" ]; then
|
||||
echo " ✅ FFmpeg is running (PID: $FFMPEG_PID)"
|
||||
echo " Process details:"
|
||||
docker compose exec api bash -c "ps aux | grep '[f]fmpeg' | grep -v grep" 2>/dev/null
|
||||
else
|
||||
echo " ❌ FFmpeg is NOT running"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "8. Checking API logs for RTSP activity..."
|
||||
echo " Recent RTSP/FFmpeg logs:"
|
||||
docker compose logs api --tail 100 | grep -E "RTSP|FFmpeg|frame dimensions|Waiting|Could not|Starting RTSP|Publishing|error|Error" | tail -20
|
||||
echo ""
|
||||
|
||||
echo "9. Checking MediaMTX for stream..."
|
||||
PATH_INFO=$(curl -s http://localhost:8889/v2/paths/get/camera1 2>/dev/null)
|
||||
if [ -n "$PATH_INFO" ] && [ "$PATH_INFO" != "null" ] && [ "$PATH_INFO" != "{}" ]; then
|
||||
echo " ✅ Stream path exists in MediaMTX"
|
||||
echo "$PATH_INFO" | python3 -m json.tool 2>/dev/null | head -20 || echo "$PATH_INFO"
|
||||
SOURCE_READY=$(echo "$PATH_INFO" | python3 -c "import sys, json; d=json.load(sys.stdin); print(d.get('sourceReady', False))" 2>/dev/null || echo "false")
|
||||
if [ "$SOURCE_READY" = "True" ]; then
|
||||
echo ""
|
||||
echo " ✅ Stream is READY!"
|
||||
else
|
||||
echo ""
|
||||
echo " ⚠️ Stream exists but source is not ready"
|
||||
fi
|
||||
else
|
||||
echo " ❌ Stream not found in MediaMTX"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "10. MediaMTX recent activity..."
|
||||
docker compose logs mediamtx --tail 20 | grep -E "camera1|RTSP|publishing|session" | tail -10
|
||||
echo ""
|
||||
|
||||
echo "=========================================="
|
||||
echo "Diagnostic Complete"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
TAILSCALE_IP=$(tailscale ip -4 2>/dev/null || hostname -I | awk '{print $1}')
|
||||
echo "If stream is ready, try accessing:"
|
||||
echo " http://$TAILSCALE_IP:8889/static/"
|
||||
echo " http://$TAILSCALE_IP:8889/camera1/webrtc"
|
||||
echo ""
|
||||
|
||||
@@ -9,11 +9,6 @@ paths:
|
||||
# allow any path to be read; publishers can be added on-demand
|
||||
readUser: any
|
||||
sourceOnDemand: no
|
||||
sourceOnDemandStartTimeout: 10s
|
||||
sourceOnDemandCloseAfter: 10s
|
||||
# Keep source alive even without readers (remove timeout)
|
||||
# sourceCloseAfter: never # Keep stream alive indefinitely
|
||||
sourceCloseAfter: 30s # Keep stream alive for 30 seconds after last reader disconnects
|
||||
|
||||
# Example on-demand publisher for a demo VOD (adjust file path):
|
||||
# vod:
|
||||
|
||||
59
test_rtsp_working.md
Normal file
59
test_rtsp_working.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# RTSP Streaming is Working! 🎉
|
||||
|
||||
**Status**: ✅ RTSP streaming is functional and VLC can view the stream!
|
||||
|
||||
## Current Status
|
||||
|
||||
- ✅ FFmpeg is encoding and publishing frames
|
||||
- ✅ MediaMTX is receiving the RTSP stream
|
||||
- ✅ VLC can successfully view the stream via RTSP
|
||||
- ⚠️ WebRTC requires the stream to be active when accessed
|
||||
|
||||
## Access Methods
|
||||
|
||||
### 1. RTSP (Working - Use This!)
|
||||
```bash
|
||||
rtsp://100.93.40.84:8554/camera1
|
||||
```
|
||||
|
||||
**For VLC:**
|
||||
- File → Open Network Stream
|
||||
- URL: `rtsp://100.93.40.84:8554/camera1`
|
||||
- Or with TCP: `rtsp://100.93.40.84:8554/camera1?transport=tcp`
|
||||
|
||||
### 2. WebRTC (Browser Player)
|
||||
The WebRTC player needs the stream to be active when you open it.
|
||||
|
||||
**To use WebRTC:**
|
||||
1. First, make sure RTSP is running:
|
||||
```bash
|
||||
curl -X POST http://exp-dash:8000/cameras/camera1/start-rtsp
|
||||
```
|
||||
|
||||
2. Then quickly open (within 10 seconds):
|
||||
```
|
||||
http://100.93.40.84:8889/camera1/webrtc
|
||||
```
|
||||
|
||||
**Note**: WebRTC uses POST requests to `/camera1/whep`, so 404/405 errors are normal if the stream isn't active.
|
||||
|
||||
## Troubleshooting WebRTC
|
||||
|
||||
If you see "stream not found" in the browser:
|
||||
- The RTSP stream may have timed out
|
||||
- Restart RTSP and immediately open the WebRTC URL
|
||||
- MediaMTX closes streams after ~10 seconds without active viewers
|
||||
|
||||
## Quick Test Commands
|
||||
|
||||
```bash
|
||||
# Check if RTSP is running
|
||||
curl -X POST http://exp-dash:8000/cameras/camera1/start-rtsp
|
||||
|
||||
# Check stream status
|
||||
curl -s http://localhost:8889/v2/paths/get/camera1 | python3 -m json.tool
|
||||
|
||||
# Full diagnostic
|
||||
./diagnose_rtsp.sh
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user