multimux — live RTSP → LL-HLS just-in-time repackaging origin
A thin client + server wrap around two existing workspace crates —
rtsp-runtime (RTSP pull) and transmux (RTP depayload + LL-HLS CMAF
segmentation) — that pulls one or more live RTSP sources and serves each as
Low-Latency HLS (RFC 8216bis, #EXT-X-PART + blocking playlist reload)
from an in-process tokio + axum HTTP origin. Muxing only: samples are opaque
and are never transcoded.
Quick start
Single-route quick start (one camera, no config file):
Multi-route JSON config file:
Every flag/field has a default (see multimux --help or
multimux::config::Config::default()); --rtsp/--name and --config are
mutually exclusive — pass one or the other.
Served endpoints
One route ("stream") is served per configured name, under /{stream}/...:
| Endpoint | Description |
|---|---|
GET /{stream}/master.m3u8 |
Minimal single-variant HLS master playlist. |
GET /{stream}/media.m3u8[?_HLS_msn=&_HLS_part=] |
LL-HLS media playlist. With _HLS_msn/_HLS_part present, blocks (bounded) until that segment/part is available — RFC 8216bis §6.2.5.2 Blocking Playlist Reload. |
GET /{stream}/init-{track}.mp4 |
fMP4 init segment (moov). |
GET /{stream}/seg-{track}-{seq}.m4s |
A closed full media segment. |
GET /{stream}/part-{track}-{seq}.{part}.m4s |
An LL-HLS part of the in-progress segment. |
An unknown stream name, or a filename multimux doesn't recognize, returns
404.
v1 scope and limits
multimux wraps already-authored library crates and carries no media/transport
spec logic of its own — any missing RTP/RTSP/SDP/codec capability is a library
gap fixed upstream, in transmux or rtsp-runtime, never in this crate. See
docs/superpowers/specs/2026-07-14-multimux-design.md
in the workspace root for the full design.
In scope (v1):
- Ingest: RTSP pull only, interleaved RTP/RTCP over TCP.
- Codecs: H.264 video + AAC audio.
- Output: LL-HLS only — one global output protocol per instance.
- Routing: N independent
rtsp_url -> stream nameroutes per instance. - Config: CLI-first (clap), with an optional JSON config file for multiple routes.
- Serving: standalone tokio + axum listener; an in-RAM rolling window per stream (N full segments + the in-progress segment's live parts), oldest segment evicted on roll. Live-only — nothing is retained after eviction.
Explicitly out of scope for v1 (deferred):
- DASH / LL-DASH — planned as v1.1;
transmux's DASH packager is already built, multimux just doesn't wire it up yet. - SRT/TS/file inputs (RTSP pull only).
- Per-viewer sessions, server-side ad insertion, manifest rewrites.
- DVR / VOD / disk spill (the window is RAM-only and rolls forward).
- TLS + auth (run a reverse proxy in front for either).
- Trick-play.
Additional documented limits inherited from the underlying streaming
depayloader (transmux's RtpStreamDepacketizer, issue #700): low-delay
H.264 only (no B-frame reordering), one AAC access unit per RTP packet, and
packets must arrive in order — all true of a direct RTSP pull over TCP.
Examples
# Serve a synthetic stream with no camera / network required.
# Serve one real RTSP source.
Spec
RFC 8216bis (HTTP Live Streaming, 2nd edition) — Low-Latency HLS: #EXT-X-PART
(§4.4.4.9), #EXT-X-PART-INF/#EXT-X-SERVER-CONTROL (§4.4.3.7/§4.4.3.8), and
Blocking Playlist Reload (§6.2.5.2). RTSP 1.0 (RFC 2326) for ingest, via
rtsp-runtime.
License
MIT OR Apache-2.0