A lightweight desktop viewer for RTSP cameras. It provides three interchangeable backends, one shared configuration, fullscreen viewing, camera hotkeys, and multi-camera layouts without requiring a browser.
| Backend | Best for | Layouts | Notes |
|---|---|---|---|
| go2rtc | Low-latency H.264/H.265 viewing without a local server | 1×1, 2×2 | Native Go RTSP/RTP processing and libVLC display |
| VLC | Lowest CPU usage for one camera | 1×1 | Direct native rendering; requires camera RTSP support in VLC |
| FFmpeg/OpenCV | Broad codec portability and native Wayland compatibility | 1×1, 2×2 | Frames pass through Python/Tk, so CPU usage is higher |
The go2rtc backend is not the go2rtc server or web interface. It connects outbound to each selected camera, depacketizes RTSP/RTP in a local bridge, muxes the stream to MPEG-TS, and passes it to libVLC through an anonymous OS pipe. It does not start an HTTP, WebSocket, WebRTC, or RTSP listening service.
All backends require:
- Python 3.10 or newer
- Tk
- An RTSP camera or NVR stream
The VLC and go2rtc backends additionally require native libVLC and
python-vlc. The FFmpeg backend requires OpenCV, NumPy, and Pillow.
On Debian, Ubuntu, Raspberry Pi OS, or Pop!_OS:
sudo apt install python3-tk python3-venv vlc libvlc5 \
vlc-plugin-base vlc-plugin-video-outputOn Fedora:
sudo dnf install python3-tkinter vlcOn Arch Linux:
sudo pacman -S tk vlcNative VLC embedding on Linux requires X11 or XWayland. Use the FFmpeg backend when running Tk as a native Wayland application.
Tagged releases provide project archives with a prebuilt go2rtc bridge for:
linux-amd64: ordinary 64-bit Intel/AMD PCslinux-arm64: 64-bit ARM systems, including modern Raspberry Pi OS
Download the archive for your architecture from
GitHub Releases, verify it
against SHA256SUMS, and extract it. The go2rtc bridge is already compiled, so
Go is not required on the destination machine.
Then create the Python environment:
cd rtsp-viewer-vX.Y.Z-linux-amd64
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pipInstall the backend dependencies you intend to use:
# go2rtc or VLC
python -m pip install -r requirements-vlc.txt
# FFmpeg/OpenCV
python -m pip install -r requirements-ffmpeg.txtgit clone https://github.com/ivoryroot/rtsp-viewer.git
cd rtsp-viewer
python3 -m venv .venv
source .venv/bin/activateInstall one of the requirements files shown above. To use go2rtc from a source checkout, install Go 1.24 or newer and build the pinned bridge:
rtsp-viewer-go2rtc/build.shThe bridge uses the official github.com/AlexxIT/go2rtc Go module pinned in
go.mod; no separate go2rtc source checkout is needed.
Create the one shared private configuration:
cp config.example.json config.jsonEdit config.json:
{
"fullscreen_text": "Camera monitor",
"settings": {
"auto_start": false,
"fullscreen": false,
"render_fps": 20,
"rtsp_transport": "tcp",
"vlc_network_caching_ms": 400,
"vlc_disable_audio": true,
"reconnect_max_seconds": 10
},
"feeds": [
{
"name": "Front entrance",
"url": "rtsp://username:password@camera.example:554/stream1",
"hotkey": "F1"
}
]
}config.json is ignored by Git because camera URLs commonly contain
credentials. Never commit it or include real camera URLs in issues and
screenshots.
Configuration is resolved in this order:
--config PATHRTSP_VIEWER_CONFIG$XDG_CONFIG_HOME/rtsp-viewer/config.json- The project-root
config.json config.example.json
The complete format is documented by config.schema.json.
| Setting | Used by | Description |
|---|---|---|
auto_start |
All | Start the first configured feed when the window opens |
fullscreen |
All | Open in fullscreen mode |
render_fps |
FFmpeg | Maximum Tk rendering rate, from 1 to 60 |
rtsp_transport |
All | tcp, udp, or auto |
vlc_network_caching_ms |
VLC, go2rtc | Native playback cache, from 0 to 10000 ms |
vlc_disable_audio |
VLC, go2rtc | Disable camera audio |
reconnect_max_seconds |
go2rtc | Maximum reconnect backoff, from 1 to 60 seconds |
Activate the virtual environment first, then choose a backend:
# go2rtc; builds the bridge automatically if it is absent
rtsp-viewer-go2rtc/run.sh
# Native VLC
python rtsp-viewer-vlc/rtsp-viewer.py
# FFmpeg/OpenCV
python rtsp-viewer-ffmpeg/rtsp-viewer.pyUse a different configuration with any backend:
python rtsp-viewer-ffmpeg/rtsp-viewer.py --config /path/to/config.json- Click a camera or press its configured hotkey to assign it.
F: toggle fullscreen.Escape: leave fullscreen.- FFmpeg and go2rtc: choose
1x1or2x2, then click a tile before assigning a camera. - FFmpeg only:
Atoggles stretched and aspect-preserving display.
- Prefer a camera's low-resolution substream on small systems. Resizing after decoding does not reduce the cost of decoding a 4K source.
- The go2rtc bridge supports H.264 and H.265 video and optional AAC audio. Configure a compatible camera substream when the main stream uses MJPEG, VP8, VP9, or another codec.
- Prefer VLC for a single camera and minimum CPU usage.
- Set
vlc_disable_audiototruewhen audio is unnecessary. - Reduce
render_fpsto 10–15 for FFmpeg 2×2 layouts on low-end hardware. - TCP is reliable on most networks. UDP can reduce latency but may expose packet loss and uses local UDP receive sockets.
The camera host was reached, but no RTSP service accepted the configured port. Verify the URL, port, credentials, and camera RTSP setting.
Select an H.264/H.265 camera stream or enable a compatible substream.
The installed VLC build may lack the live555 module used for camera RTSP.
Use a complete native VLC installation, the external VLC mode documented
below, the go2rtc backend, or the FFmpeg backend.
python rtsp-viewer-vlc/rtsp-viewer.py \
--vlc-backend external --vlc-command /snap/bin/vlcRun Tk through XWayland/X11 or use the FFmpeg backend.
Use the camera substream, lower its frame rate or bitrate, and reduce FFmpeg's
render_fps. On Raspberry Pi, also check throttling and cooling.
python3 -m unittest discover -s tests -v
python3 -m compileall -q \
rtsp_viewer_common.py \
rtsp-viewer-ffmpeg \
rtsp-viewer-vlc \
rtsp-viewer-go2rtc
cd rtsp-viewer-go2rtc/bridge
go test ./...
go vet ./...GitHub Actions validates Python 3.10, 3.12, and 3.13, the configuration schema, and the Go bridge. See CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
Release packages are produced automatically when a version tag is pushed:
git tag -a vX.Y.Z -m "rtsp-viewer vX.Y.Z"
git push origin vX.Y.ZThe release workflow builds Linux AMD64 and ARM64 packages, generates
SHA256SUMS, and creates the corresponding GitHub release with generated
notes.
rtsp-viewer is licensed under the WTFPL. go2rtc and libVLC-related notices are listed in THIRD_PARTY_LICENSES.md.


