MoQ is under active development. APIs and protocols may change between releases.

Skip to content

Standards

The IETF MoQ working group standardizes Media over QUIC. This project tracks that work and interoperates with it, while shipping a simpler profile you can use today.

SpecScopeHere
moq-transportThe IETF pub/sub protocolDrafts 14 through 20 negotiated by ALPN; moq-lite is a forward-compatible subset
MSFThe IETF catalog formatRead and written; broadcasts ending in .msf select it
LOCThe IETF low-overhead containerSupported as a hang container kind
moq-lite, hang, and friendsThis project's own draftsNormative for the implementation, published to the datatracker from drafts/

moq-transport

moq-transport is the full protocol: namespaces (broadcasts) that several publishers may share, sub-groups for layered codecs, object-level metadata and gaps, FETCH for ranges of history, joining fetches, PUBLISH push, and pausing. moq-lite keeps the parts a CDN can implement without conflicts and maps everything else to "not supported" or a harmless equivalent. The moq-lite page lists the differences.

Several project drafts extend the IETF wire without breaking it, since SETUP ignores unknown parameters: cluster routing hop lists, solicit to make announcements opt-in, and probe for bandwidth estimation.

MSF

The MoQ Streaming Format is a catalog, playing the role HLS playlists and SDP do elsewhere. It overlaps with the hang catalog and the two will likely converge. The tools track draft-01 and hide the version on the wire, so draft-00 catalogs still decode and init data always arrives inline. The stalled rendition hint is shared between the two formats.

LOC

The Low Overhead Container carries a timestamp and a few properties per frame with none of CMAF's per-frame moof cost. It is close to hang's legacy container and is selectable per track (container=loc in the GStreamer plugin).

Interop testing

moq-cli speaks every listed draft, picks the newest one the relay also supports, and prints it in the logs. Publish a test pattern and play it back:

bash
ffmpeg -re -f lavfi -i testsrc=size=1280x720:rate=30 -f lavfi -i sine=frequency=440 \
    -c:v libx264 -preset ultrafast -tune zerolatency -g 60 -c:a aac \
    -f mp4 -movflags cmaf+frag_keyframe+empty_moov+default_base_moof - \
| moq --client-connect https://relay.example.com --broadcast test.hang import fmp4

moq --client-connect https://relay.example.com --broadcast test.hang export fmp4 | ffplay -

Add --client-tls-disable-verify for a self-signed relay on your own test network (it accepts any certificate, so never point it at a remote relay) and RUST_LOG=info,moq_net=debug to see the negotiated version. Behavior worth knowing when pointing another implementation at ours: we announce every namespace we can offer unsolicited and ask for every prefix we may discover; set the solicit SETUP option to make us wait to be asked. Single-track PUBLISH offers are declined; announce a namespace and serve the resulting SUBSCRIBEs instead.

Licensed under MIT or Apache-2.0