rtsp-rs 0.1.8

RTSP server library for live media streaming
Documentation

rtsp-rs

Lint Test Release

A Rust library for publishing live encoded video over RTSP. Push frames and play the stream with any standard client (VLC, ffplay, GStreamer).

Usable from Rust, Python, or GStreamer.


⚠️ Please read before using

This is a personal, hobby project I built to learn about RTP, RTSP, and streaming. I’m actively evolving it and use it only for my own projects. I have no plans to use or support it in production right now, though I might rely on it there someday if the need arises — so treat it as use at your own risk.

Some of the tests, examples, and documentation in this repo were generated or assisted by AI tools. Treat them as reference material rather than guarantees of correctness.


Status: Pre-release (v0.x). API may change between versions.

Project structure

crates/
├── core/        # rtsp-rs (crates.io) — core library, use rtsp:: in Rust
├── python/      # rtsp-python  — PyO3 bindings → PyPI package rtsp-rs
└── gst/         # gst-rtsp-sink — GStreamer sink plugin

examples/
└── python/      # Python demo (numpy + PyAV)

Quick start

Rust

Add to Cargo.toml: rtsp = { package = "rtsp-rs", version = "0.1" } (the crate is published as rtsp-rs on crates.io; the library is still rtsp in code).

use rtsp::Server;

let mut server = Server::new("0.0.0.0:8554");
server.start().unwrap();

// Push H.264 Annex B frames — packetization and delivery are handled internally.
// Timestamp increment = 90000 / fps (e.g. 3000 for 30 fps).
// server.send_frame(&h264_data, 3000).unwrap();

Python

pip install maturin
maturin develop -m crates/python/Cargo.toml
import rtsp

server = rtsp.Server("0.0.0.0:8554")
server.start()

# Push encoded H.264 frames directly — no manual packetization needed.
server.send_frame(h264_bytes, 3000)

See examples/python/test.py for a full demo that encodes a test pattern with PyAV.

GStreamer

Build and install the plugin:

cargo build -p gst-rtsp-sink --release

# Point GStreamer at the built library
export GST_PLUGIN_PATH=$PWD/target/release

Stream a test pattern:

gst-launch-1.0 videotestsrc \
  ! video/x-raw,width=640,height=480,framerate=30/1 \
  ! x264enc tune=zerolatency bitrate=2000 key-int-max=30 \
  ! video/x-h264,stream-format=byte-stream \
  ! rtspserversink port=8554

Stream from a webcam (macOS):

gst-launch-1.0 avfvideosrc \
  ! videoconvert \
  ! x264enc tune=zerolatency bitrate=2000 \
  ! video/x-h264,stream-format=byte-stream \
  ! rtspserversink port=8554

Stream from a webcam (Linux):

gst-launch-1.0 v4l2src device=/dev/video0 \
  ! videoconvert \
  ! x264enc tune=zerolatency bitrate=2000 \
  ! video/x-h264,stream-format=byte-stream \
  ! rtspserversink port=8554

Stream from a file:

gst-launch-1.0 filesrc location=video.mp4 \
  ! qtdemux ! h264parse \
  ! video/x-h264,stream-format=byte-stream \
  ! rtspserversink port=8554

Then connect with any RTSP client:

ffplay rtsp://localhost:8554/stream
vlc rtsp://localhost:8554/stream

Building

Requires Rust 1.92+ (latest stable). The GStreamer plugin requires libunwind-dev and libgstreamer1.0-dev (Ubuntu/Debian: sudo apt install libunwind-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev).

cargo build -p rtsp-rs             # Core library
cargo build -p gst-rtsp-sink       # GStreamer plugin
cargo build -p rtsp-python         # Python bindings (needs maturin)
cargo test  --workspace            # All tests
cargo clippy --workspace           # Lint