Point a camera at something. Get an RTSP stream out the other end.
Hardware encoders are expensive. A dedicated box that takes HDMI in and spits RTSP out will set you back £800+. They work fine, but when you've got a pile of cheap capture dongles and a spare Pi lying around, it feels like overkill.
Enter Dart.
Dart is a tiny, focused utility that takes video in and streams it out as RTSP. That's it. No frills, no bloat, no £800 price tag.
It's part of the SlingShot family of tools, but it stands on its own.
- HDMI capture cards — Any V4L2 device. Cheap USB capture dongles work fine.
- Webcams — Same deal. If Linux sees it, Dart can use it.
- RTSP streams — Transcode and re-stream existing IP cameras.
- RTSP — Connect your VMS, your NVR, your SlingShot instance, whatever.
The easiest way to get going is the config wizard:
dart --config-newIt'll scan for cameras, probe capabilities, and write a config file for you. No manual TOML wrangling required.
Or if you prefer to do things by hand:
# HDMI capture card on /dev/video0
dart --config config.hdmi.toml
# Webcam
dart --config config.webcam.toml
# Re-stream an existing RTSP source
dart --config config.rtsp.tomlThe --config-new flag walks you through setup interactively:
For V4L2 sources (webcams, capture cards):
- Scans and lists all connected video devices
- Probes supported formats and resolutions via
v4l2-ctl - Lets you pick resolution and framerate from what the hardware actually supports
- Writes a working config
For RTSP sources (IP cameras):
- Takes the RTSP URL
- Probes the stream with
ffprobeto detect codec, resolution, framerate - Asks if you want passthrough or transcode
- Writes a working config
Dependencies: v4l-utils for V4L2 probing, ffmpeg for RTSP probing.
Dart uses TOML config files. Here's an example for an HDMI capture card:
[server]
rtsp_port = 8554
bind_address = "0.0.0.0"
[[sources]]
name = "hdmi"
type = "v4l2"
device = "/dev/video0"
format = "UYVY" # For HDMI capture cards (TC358743, etc.)
width = 1280
height = 720
framerate = 30
[sources.encode]
bitrate = 2000 # kbps
keyframe_interval = 30
preset = "ultrafast"
tune = "zerolatency"For a standard webcam, you can omit the format field:
[[sources]]
name = "webcam"
type = "v4l2"
device = "/dev/video0"
width = 1920
height = 1080
framerate = 30
[sources.encode]
bitrate = 4000For relaying an existing RTSP stream:
[[sources]]
name = "camera"
type = "rtsp"
url = "rtsp://192.168.1.100:554/stream1"
latency = 200
fallback = "/path/to/fallback.jpg"Because it works. Because it's battle-tested. I know how to make RTSP servers from SlingShot, so this is a no brainer.
Dart wraps GStreamer and handles all the pipeline nonsense so you don't have to.
If it can run Linux and has a USB port, it can probably run Dart.
Tested on:
- Raspberry Pi 4 (1080p/25fps, no sweat)
- Random x86 mini PCs
- Actual servers (overkill, but sure)
Dart is a focused breakout from SlingShot. If you need:
- Ultra-low bandwidth streaming over QUIC → SlingShot
- Simple HDMI/V4L2 to RTSP → You're in the right place
This is early days. It works for my use case, but your mileage may vary.
Found a bug? Open an issue. Got a fix? PR welcome.
AGPL-3.0. See LICENSE.