Open-source MoQ (Media over QUIC) player for low-latency live streaming.
- Direct MSE rendering — no Shaka, dash.js, or HLS.js dependency
- Sub-second TTFF — ~350-550ms on nearby relays
- WebTransport + WebSocket fallback — works on Safari and restrictive networks
- Adaptive bitrate — buffer-based ABR with track switching
- Codec auto-detection — parses H.264 (avcC) and AAC (esds) from init segments
- Relay transport stats — RTT, throughput, packet loss from relay-stats track
- Stale fragment dropping — maintains target latency by dropping old data
- Live-edge seeking — stays at the live edge with configurable target latency
Open index.html in a browser, enter a relay URL and namespace, and click Play.
Or use URL parameters:
index.html?relay=https://relay.moqcdn.net&ns=my-stream
| File | Description |
|---|---|
moqt-player.js |
MoQ Transport player — WebTransport connection, MoQ protocol, ABR, track management |
fragment-appender.js |
MSE SourceBuffer management — codec detection, fragment batching, buffer append queue |
qmux.js |
WebSocket fallback — WebTransport polyfill for browsers without QUIC support (Safari) |
index.html |
Demo player page |
<video id="video" autoplay muted playsinline></video>
<script src="qmux.js"></script>
<script src="fragment-appender.js"></script>
<script src="moqt-player.js"></script>
<script>
const player = new MoqtPlayer({
relayUrl: 'https://your-relay.example.com',
namespace: 'your-stream',
video: document.getElementById('video'),
});
player.connect();
document.getElementById('video').play();
</script>| Option | Type | Description |
|---|---|---|
relayUrl |
string | MoQ relay URL (https:// or wss://) |
namespace |
string | Stream namespace to subscribe to |
video |
HTMLVideoElement | Video element for playback |
onStatus |
function | Status callback (optional) |
Connects to the relay via WebTransport (with WebSocket fallback), performs MoQ SETUP exchange, subscribes to catalog, and begins playback.
Returns current player statistics:
{
bufferHealth: '0.28',
abrState: 'stable',
abrCurrentResolution: '720p',
abrSwitchCount: 0,
abrLadder: '480p, 720p, 1080p',
targetLatency: 200,
relayRtt: 23.0, // ms (if relay supports stats track)
relaySendRate: 18.4, // Mbps estimated max
relaySendThroughput: 1.4, // Mbps actual
relayPacketsLost: 1,
framesReceived: 1500,
bytesReceived: 2500000,
transportType: 'webtransport', // or 'websocket'
}Closes the connection and cleans up resources.
| Browser | Transport | Status |
|---|---|---|
| Chrome 145+ | WebTransport (QUIC) | Full support |
| Edge 145+ | WebTransport (QUIC) | Full support |
| Firefox 139+ | WebTransport (QUIC) | Full support |
| Safari 18+ | WebSocket (fallback) | Full support via qmux.js |
MoQplay implements the MoQ Transport protocol (IETF draft-14/16) with moq-lite encoding. It connects to any compatible MoQ relay (e.g., moq-dev/moq).
Use moqpush to publish CMAF streams to a MoQ relay:
./moqpush-app --push-key mpk_YOUR_KEY --tracks 3v1a --target-latency 200MIT