Low Overhead CMAF for MoQ
A new wire format for CMAF over MoQ โ including DRM โ with the overhead of LOC
โจ Why LOCMAF
CMAF carries the metadata that DRM needs (per-sample IVs, subsample maps,
tenc defaults). LOC is compact but strips this away. LOCMAF keeps
the CMAF structure intact and compresses the redundant moof bytes
out of the wire โ so the standard MSE / EME path on the receiver plays
protected content as if it had arrived as plain CMAF.
- Sample-level objects (one frame per MoQ object)
- Delta
moofas small as 2 bytes - Functionally lossless reconstruction
- Works with Widevine, PlayReady, FairPlay, ClearKey
๐ Measured Compression
On a 250-fragment AVC group from the moqlivemock test asset:
- CMAF
mooftotal: 26 040 B - LOCMAF object total: 592 B
moof-header ratio: 45 : 1- 128 kbps AAC wire bitrate: 171.5 โ 131.9 kbps (โ23 %)
- 128 kbps AAC under
cbcsDRM: 191.4 โ 131.9 kbps (โ31 %)
LOCMAF saves more relative to CMAF under DRM than in clear,
because senc / saio / saiz make
the CMAF moof grow while LOCMAF only emits what it needs.
See it yourself: after connecting MOQ Player to the server,
click the Show catalog toggle to inspect each track's total wire
bitrate (framing included) and compare a CMAF track to its
LOCMAF counterpart โ both renditions live in the same cmsf/* catalog.
๐ LOCMAF Resources
Everything you need to understand and implement LOCMAF:
-
locmaf.devoverview, diagrams, measurements
-
draft-einarsson-moq-locmafIETF Internet-Draft โ normative LOCMAF v0.2 spec
-
LOCMAF.md (v0.1)frozen v0.1 wire format, versioning, fidelity rules
-
Slide deck20-slide MARP deck adapted from the spec
-
Eyevinn/moqlivemockGo reference encoder/decoder
-
Eyevinn/warp-playerbrowser MoQ player with LOCMAF + EME
Catalog signal: "packaging": "locmaf" with
"locmafVersion": "0.2" in the CMSF Track entry. The matching
"packaging": "cmaf" rendition shares the same init data through an
initRef, so both variants sit side by side in one draft-01 catalog.
Try LOCMAF Live
Both the publisher and the browser player ship LOCMAF in v0.11.0. Open MOQ Player,
connect to a cmsf/* namespace and pick a LOCMAF track from the catalog,
and the receiver will rebuild the CMAF chunks and feed them to MSE / EME for you โ
clear, ClearKey/ECCP, and commercial DRM all work side by side.
Why Use MoqLiveMock?
Test your MoQ client implementations against a reliable, always-available server supporting both draft-14 and draft-16 with automatic version negotiation. MoqLiveMock simulates a true live MoQ streaming service with UTC-aligned content delivery โ all clients receive synchronized streams regardless of join time. Stream 10-second loops of synchronized multi-bitrate content across CMAF, LOCMAF, LOC, and moq-mi packaging modes, with clear and DRM-protected variants of each.
Available Streams
Specially prepared relatively low-bitrate content for testing
๐ฅ Video Tracks
H.264 (AVC) and HEVC encoded video streams at multiple bitrates for adaptive streaming
- 400 kbps AVC
- 600 kbps AVC
- 900 kbps AVC
- 400 kbps HEVC
- 600 kbps HEVC
- 900 kbps HEVC
๐ต Audio Tracks
Easily discernable audio tracks in AAC, Opus, and AC-3 with synchronized second beeps
- Monotonic AAC (128 kbps)
- Scale AAC (128 kbps)
- Monotonic Opus (128 kbps)
- Scale Opus (128 kbps)
- Monotonic AC-3 (128 kbps)
- Scale AC-3 (128 kbps)
๐ Subtitle Tracks
Subtitle tracks in CMAF-compatible formats for testing text rendering
- WVTT (WebVTT in CMAF)
- STPP (TTML in CMAF)
๐ Content Protection
Multiple content protection modes served as separate namespaces, each catalog carrying both CMAF and LOCMAF packaging
cmsf/clearโ unencryptedcmsf/drm-cbcsโ Widevine, PlayReady, FairPlaycmsf/eccp-cbcsโ ClearKey (ECCP)
Each namespace has its own CMSF draft-01 catalog, with every rendition in both CMAF and LOCMAF packaging. LOCMAF carries the same per-sample encryption metadata as CMAF, so the same EME / CDM path works for either.
Signaling follows the released CMSF draft-01 specification, also supported by Shaka Player.
๐ฆ Packaging Modes
Side-by-side packaging modes so clients can compare wire-cost and pipelines
cmsf/*โ CMAF and LOCMAF (v0.2) in one catalog, sharing init data viainitRefmsf/clearโ LOC, raw codec frames per objectmoq-mi/clearโ moq-mi, catalogless interop
LOCMAF gives near-LOC overhead while keeping CMAF's metadata path, so DRM survives the round-trip. LOC and moq-mi carry raw codec frames played via WebCodecs.
โก Technical Specs
Modern streaming protocols and formats
- MoQ Transport draft-14 and draft-16
- ALPN-based version negotiation
- CMAF chunks, LOCMAF delta moofs, LOC raw frames
- MSE / EME and WebCodecs render pipelines in MOQ Player
- 10-second loops, wall-clock synchronized
- MSF / CMSF catalog per namespace
- moq-mi catalogless namespace
- Multiple namespaces announced from one publisher
Live Streaming Simulation
UTC-aligned streaming for consistent playback across all clients
๐ Wall-clock Alignment
MoqLiveMock simulates a live MOQ streaming service with precise UTC time alignment. This ensures all subscribers receive synchronized content regardless of when they join or when the publisher was started.
Two-Level Time Alignment
seconds % 10 == 0.
This ensures every subscriber joining at the same wall-clock time receives the same content.
Unix_epoch_ms / 1000,
so group boundaries fall on exact second boundaries.
How to Use
Multiple ways to connect and stream content
๐ Browser Player (Recommended)
Use MOQ Player (warp-player v0.11.0) for instant playback in Chrome, Edge, Firefox, or Safari 26.4+. No installation required. It supports MoQ Transport draft-14 and draft-16 with automatic version negotiation, and ships an MSE / EME engine that plays both CMAF and LOCMAF tracks (the LOCMAF decoder reconstructs CMAF chunks before they reach MSE) plus a WebCodecs engine for LOC and moq-mi tracks โ selectable from the UI.
๐ป Command Line Client
For developers and advanced users, use mlmsub to stream from the terminal:
# Install the client go install github.com/Eyevinn/moqlivemock/cmd/mlmsub@latest # Stream clear CMAF (default namespace: cmsf/clear) mlmsub -addr moqlivemock.demo.osaas.io -videoname _avc -audioname _aac -muxout - | ffplay - # Dump the unified cmsf/clear catalog โ each rendition appears as a CMAF track # and a LOCMAF track (the '_locmaf' suffix), sharing init data via initRef mlmsub -addr moqlivemock.demo.osaas.io -namespace cmsf/clear -catalogout - # Stream the LOCMAF variant โ chunks are reconstructed into CMAF on the receiver mlmsub -addr moqlivemock.demo.osaas.io -namespace cmsf/clear -videoname _avc_locmaf -audioname _aac_locmaf -muxout - | ffplay - # Stream LOCMAF under ClearKey/ECCP (cbcs) mlmsub -addr moqlivemock.demo.osaas.io -namespace cmsf/eccp-cbcs -videoname _eccp_locmaf -audioname _eccp_locmaf -muxout - | ffplay - # Stream LOC-packaged content (raw frames, AVC + AAC) and write to files mlmsub -addr moqlivemock.demo.osaas.io -namespace msf/clear -videoout video.h264 -audioout audio.aac # Discover announced namespaces on a relay mlmsub -addr moqlivemock.demo.osaas.io -discover # Stream with WebTransport and debug logging mlmsub -wt -addr https://moqlivemock.demo.osaas.io:443 -loglevel debug -muxout - | ffplay - # Connect using a specific draft version (14 or 16, default: 16) mlmsub -draft 14 -addr moqlivemock.demo.osaas.io -muxout - | ffplay -
The cmd/locmaf tool in moqlivemock includes a roundtrip subcommand
that encodes a fragmented MP4 through the LOCMAF encoder/decoder and verifies sample-level
fidelity โ handy for running the LOCMAF wire-cost measurements yourself.
๐ง Run Your Own Server
Clone the repository and run your own MoqLiveMock instance:
# Clone and build git clone https://github.com/Eyevinn/moqlivemock cd moqlivemock go build ./cmd/mlmpub # Option 1: Using mkcert (recommended for development) mkcert -key-file key.pem -cert-file cert.pem localhost 127.0.0.1 ::1 mkcert -install ./mlmpub -cert cert.pem -key key.pem -addr localhost:4443 # Option 2: Using fingerprint (no cert installation needed) ./mlmpub -sideport 8081 # With ClearKey/ECCP encryption ./mlmpub -sideport 8081 \ -kid 00112233445566778899aabbccddeeff \ -iv 00000000000000000000000000000001 \ -scheme cbcs -laurl http://localhost:8081/clearkey
When using fingerprint mode, connect with MOQ Player using:
โข Server URL: https://localhost:4443/moq
โข Fingerprint URL: http://localhost:8081/fingerprint
The -sideport enables an HTTP server for both /fingerprint and /clearkey endpoints.