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.
| Spec | Scope | Here |
|---|---|---|
| moq-transport | The IETF pub/sub protocol | Drafts 14 through 20 negotiated by ALPN; moq-lite is a forward-compatible subset |
| MSF | The IETF catalog format | Read and written; broadcasts ending in .msf select it |
| LOC | The IETF low-overhead container | Supported as a hang container kind |
| moq-lite, hang, and friends | This project's own drafts | Normative 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:
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.