Convert multiple RTSP streams to MJPEG and serve them over HTTP. Supports both native installation on Debian ARM64 and Docker deployment.
📚 Documentation
- Quick Start Guide - Get started in 5 minutes
- Migration Guide - Migrate from Docker to native
- Comparison - Legacy vs new implementation
- Legacy Docker Info - Information about deprecated Docker setup
┌─────────────────┐
│ RTSP Camera 1 │────┐
└─────────────────┘ │
│ ┌──────────────────────────────┐
┌─────────────────┐ │ │ rtsp2mjpg.py (Flask) │
│ RTSP Camera 2 │────┼───▶│ - HTTP Server (port 8080) │────▶ Web Browser
└─────────────────┘ │ │ - FFmpeg stream converters │ Mobile App
│ │ - Multi-stream support │ Home Assistant
┌─────────────────┐ │ └──────────────────────────────┘ etc.
│ RTSP Camera N │────┘
└─────────────────┘
Each camera stream is independently converted from RTSP to MJPEG using FFmpeg
and served via HTTP endpoints. The Flask server handles multiple concurrent streams.
- Multiple RTSP streams - Configure and serve multiple camera streams simultaneously
- Native installation - Run directly on Debian ARM64 without Docker overhead
- Easy configuration - JSON-based configuration file
- RESTful endpoints - Access streams via simple HTTP URLs
- Systemd integration - Run as a system service with automatic restart
- Low latency - Direct FFmpeg streaming without intermediate servers
- Debian-based system (tested on ARM64)
- Python 3.6 or higher
- FFmpeg
git clone https://github.com/knotekt/rtsp2mjpg.git
cd rtsp2mjpg
sudo ./install.shEdit /etc/rtsp2mjpg/config.json to configure your streams:
{
"port": 8080,
"host": "0.0.0.0",
"streams": [
{
"name": "camera1",
"rtsp_url": "rtsp://your-camera-url",
"width": 1920,
"height": 1080,
"fps": 15,
"quality": 5
},
{
"name": "camera2",
"rtsp_url": "rtsp://your-camera-2-url",
"width": 1280,
"height": 720,
"fps": 10,
"quality": 5
}
]
}# Enable service to start on boot
sudo systemctl enable rtsp2mjpg
# Start the service
sudo systemctl start rtsp2mjpg
# Check service status
sudo systemctl status rtsp2mjpg
# View logs
sudo journalctl -u rtsp2mjpg -f
# Restart service (e.g., after config changes)
sudo systemctl restart rtsp2mjpg
# Stop service
sudo systemctl stop rtsp2mjpgIf you prefer to run manually without systemd:
# Install dependencies
pip3 install -r requirements.txt
# Run with config file
CONFIG_FILE=/path/to/config.json python3 rtsp2mjpg.py
# Or run with single stream via environment variable (backward compatibility)
RTSP_URL=rtsp://your-camera-url python3 rtsp2mjpg.pyOnce running, you can access the streams at:
- Index page:
http://<IP>:8080/- Lists all available streams - Live stream:
http://<IP>:8080/stream/<stream_name>/live.mjpg - Still snapshot:
http://<IP>:8080/stream/<stream_name>/still.jpg - Health check:
http://<IP>:8080/health
Example:
http://192.168.1.100:8080/stream/camera1/live.mjpghttp://192.168.1.100:8080/stream/camera1/still.jpg
For backward compatibility, you can run with environment variables for a single stream:
| Variable | Default | Description |
|---|---|---|
RTSP_URL |
rtsp://freja.hiof.no:1935/rtplive/definst/hessdalen03.stream | RTSP stream URL |
VIDEO_WIDTH |
1920 | Video width |
VIDEO_HEIGHT |
1080 | Video height |
VIDEO_FPS |
15 | Frames per second |
VIDEO_QUALITY |
5 | JPEG quality (1-31, lower=better) |
CONFIG_FILE |
/etc/rtsp2mjpg/config.json | Path to configuration file |
Note: The original Docker setup using ffserver is deprecated. For Docker deployment with the new multi-stream version, you would need to build a custom image from the updated codebase.
The legacy docker-compose setup can still be used but is no longer maintained:
docker-compose up -dLegacy access (with nginx proxy):
- Live stream:
http://<IP>/live.mjpg - Still snapshot:
http://<IP>/still.jpg
Each stream in the config.json can have the following options:
- name (required): Unique identifier for the stream (used in URLs)
- rtsp_url (required): RTSP URL of the camera
- width (optional, default: 1920): Video width in pixels
- height (optional, default: 1080): Video height in pixels
- fps (optional, default: 15): Frames per second
- quality (optional, default: 5): JPEG quality (1-31, lower is better quality)
- port (optional, default: 8080): HTTP server port
- host (optional, default: 0.0.0.0): HTTP server bind address
ffmpeg -versionffmpeg -rtsp_transport tcp -i rtsp://your-camera-url -frames:v 1 test.jpgsudo journalctl -u rtsp2mjpg -f- Stream not connecting: Check if the RTSP URL is correct and accessible from your server
- High CPU usage: Reduce FPS or resolution in the stream configuration
- Port already in use: Change the port in config.json to an available port