Media over QUIC (MoQ) is a live (media) delivery protocol utilizing QUIC. It utilizes new browser technologies such as WebTransport and WebCodecs to provide WebRTC-like functionality. Despite the focus on media, the transport is generic and designed to scale to enormous viewership via clustered relay servers (aka a CDN). See quic.video for more information.
Note: this project is a fork of the IETF specification. The principles are the same but the implementation is exponentially simpler given a narrower focus (and no politics).
Too many words, here's a quick start:
Requirements:
just setup
just all
For the non-vibe coders, let's talk about how the protocol works. Unlike WebRTC, MoQ is purposely split into multiple layers to allow for maximum flexibility:
- QUIC: The network layer, providing a semi-reliable transport over UDP.
- WebTransport: QUIC but with a HTTP/3 handshake for browser compatibility.
- moq-lite: A pub/sub protocol used to serve "broadcasts", "tracks", "groups", and "frames".
- hang: Media-specific encoding based on the WebCodecs API. It's designed primarily for real-time conferencing.
- application: Any stuff you want to build on top of moq/hang.
For more information, check out the blog.
If you're extra curious, check out the specification.
If you want to make changes (or argue about anything), ping @kixelated
on Discord.
This repository is split based on the language and environment:
- rs: Rust libraries for native platforms. (and WASM)
- js: Typescript libraries for web only. (not node)
Unfortunately, this means that there are two implementations of moq
and hang
.
They use the same concepts and have a similar API but of course there are language differences.
Originally, this repository was called moq-rs
with the aim of using Rust to target all platforms.
Unfortunately, it turns out that much of the code is platform specific, so it resulted in a tiny Rust core and a lot of convoluted wrappers.
For example, a MoQ web player MUST use browser APIs for networking, encoding, decoding, rendering, capture, etc. The web is a sandbox, and with no low level hardware access we have to jump through the APIs designed for Javascript. wasm-bindgen and web-sys help, and you can see an example in hang-wasm, but it's a lot of boilerplate and language juggling for little gain.
Anyway, enough ranting, let's get to the code.
- moq: The underlying pub/sub protocol providing real-time latency and scale. This is a simplified fork of the IETF moq-transport draft called
moq-lite
. - moq-relay: A server that forwards content from publishers to any interested subscribers. It can be clustered, allowing multiple servers to be run (around the world!) that will proxy content to each other.
- moq-clock: A dumb clock client/server just to prove MoQ can be used for more than media.
- moq-native: Helpers to configure QUIC on native platforms.
- hang: Media-specific components built on top of MoQ.
- hang-cli: A CLI for publishing and subscribing to media.
- hang-gst: A gstreamer plugin for publishing and subscribing to media.
- web-transport: A Rust implementation of the WebTransport API powered by Quinn.
The hang-wasm crate is currently unmaintained and depends on some other unmaintained crates. Notably:
- web-transport-wasm: A wrapper around the WebTransport API.
- web-codecs: A wrapper around the WebCodecs API.
- web-streams: A wrapper around the WebStreams API.
- You get the idea; it's wrappers all the way down.
- @kixelated/moq: The underlying pub/sub protocol providing real-time latency and scale.
- @kixelated/hang: Media-specific components built on top of MoQ. Can be embedded on a web page via a Web Component.
Documentation is sparse as the API is still a work in progress. Check out the demos and quic.video for examples.
We use just to simplify the development process.
Check out the justfile or run just
to see the available commands.
Install any other required tools:
just setup
# Run the relay, a demo movie, and web server:
just all
# Or run each individually in separate terminals:
just relay
just pub bbb
just web
Then, visit https://localhost:8080 to watch the simple demo.
When you're ready to submit a PR, make sure the tests pass or face the wrath of CI:
just check
# Optional: Automatically fix easy lint issues.
just fix
Licensed under either:
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)