
Streams data flow: ingest (RTMP/SRT/WHIP/TUS2) → transcode → CMAF over MoQT → signed playback to browsers and native SDKs.
Streamsmanages your live inputs, signing keys, API keys, assets, and analytics over plain HTTPS. It is stateless request/response.BroadcastPublisher+BroadcastViewermove CMAF segments over a persistent MoQT (Media over QUIC Transport) connection.
Live broadcast
Push once and fan out to thousands. Glass-to-glass is sub-second on a
warm path.
VOD
Resumable uploads via TUS2, packaged to CMAF, and played from the same
catalog that the live path uses.
Four ingest protocols
RTMP, SRT, WHIP (WebRTC-HTTP ingest), and TUS2. Pick the protocol that
your encoder or browser already uses.
Signed playback
Mint a JWT-bearing playback URL. The relay checks it inside the subscribe
handler. The URL is the auth.
When to use it
Use streams when one producer feeds many consumers and you want adaptive, buffered media rather than a tight interactive loop:- Live events, sports, town halls, product launches, IRL streaming.
- Low-latency “watch parties” where every viewer needs the same timeline.
- VOD libraries built from the same packaging pipeline as your live streams.
- Embedded playback in a browser without a separate plugin. WebTransport is the playback path.
Ingest
The publish side accepts four ingest protocols. Each live input declares itsingest kind (rtmp, srt, whip, or fmp4). VOD uses TUS2.
- RTMP
- SRT
- WHIP
- TUS2 (VOD)
Classic encoder ingest (OBS, hardware encoders, mobile broadcasters).
Point the encoder at the RTMP endpoint and authenticate with the
per-input stream key. The engine ingests, transcodes, and CMAF-packages
on the fly.
The browser
BroadcastPublisher in the SDK is a WHIP-style alternative. It
fragments a MediaStream to CMAF in the page and sends each fragment as a
MoQT object. For server-class contribution, prefer RTMP/SRT/WHIP into the
engine. Let the transcoder do the packaging.Wire model
The SDK connects over one of two URL paths, both of which resolve to the same MoQT namespace on the relay:/publish/… and /playback/… are URL paths, not namespaces. The relay’s
stream resolver maps them to stream/<org>/<id>. VOD reuses the same
stream/<org>/… namespace, so live and on-demand playback are uniform.
The broadcast capability tag is media.broadcast. The relay writes a
per-broadcast analytics row keyed on that tag.
The catalog
Every stream carries a catalog (a subset ofdraft-ietf-moq-catalog)
that declares its tracks: name, RFC 6381 codec string, and (for VOD) the
CMAF init segment. A live input publishes the catalog in-band on the
.catalog track. Thus the catalog can update mid-stream (a rendition added,
a codec switched). VOD ships the catalog as catalog.json over HTTPS.
The viewer parses the catalog. It opens a MediaSource buffer per track and
feeds CMAF segments into it.
Lanes & QoS
Streams use MoQT’s group/object model. Each CMAF fragment is one MoQT object. An init/keyframe fragment opens a new group, so a late joiner can start at a group boundary. Objects carry a priority. The init segment is highest priority, because it must arrive before media decodes. Media segments follow. Under loss, the relay drops by priority and group age. It does not block the whole stream. This is buffered, adaptive delivery, not a frame-perfect interactive lane.Codecs & packaging
- Video: H.264/AVC (
avc1.*) on the broad-compatibility path. The catalog declares the codec string per track. - Audio: Opus or AAC (
mp4a.40.2). - Container: CMAF / fragmented MP4 (fMP4):
ftyp+moovinit segment, thenmoof+mdatmedia fragments. The viewer feeds them directly into the browser’sMediaSource. - Fallback: LL-HLS (Low-Latency HLS) over HTTPS for environments where WebTransport is not available. The CMAF segments are the same bytes. Only the delivery framing changes.
Signed playback (JWT)
A short-lived JWT authorizes playback. The JWT is minted from one of the org’s signing keys (Ed25519 by default, RS256 optional). The control plane returns a playback URL with the token already attached as?tok=. The
relay checks the JWT inside the SUBSCRIBE handler. A bad or expired token
closes the session with auth_failed. The server clamps tokens (30 s – 24 h,
default 1 h). Re-mint and re-open before expiry to keep long viewers alive.
How it works
A million-viewer fan-out costs you, the publisher, exactly one upload. It does not cost one copy per viewer. The relay mesh does the fan-out. One QUIC connection multiplexes every track. The relay replicates each group out to subscribers at the edge.Related
- Realtime Tracks — the MoQT publish/subscribe primitive underneath every modality.
- Streams — SDK Methods
- Streams — Cookbook
- Streams — Recipes

