Media over QUIC (MoQ) Player
Media over QUIC (MoQ) is a live media delivery protocol utilizing QUIC streams.
See the MoQ working group for more information.
This repository provides a web library for MoQ. It uses browser APIs such as WebTransport and WebCodecs to support both contribution and distribution over MoQ.
Note: This library currently focuses on the client side. You’ll need a MoQ server or relay, such as moq-rs (for local usage).
This library offers two main approaches to playing MoQ streams in a browser:
- Web Component –
<video-moq> with simple built-in controls.
- Simple Player – A
Player class that handles rendering and playback logic without built-in UI.
Installation
Install the library from npm:
npm install @moq-js/player
Or include via a <script> tag (for the IIFE build):
<script src="https://cdn.jsdelivr.net/npm/@moq-js/player@latest/dist/moq-player.iife.js"></script>
Usage
Web Component: <video-moq>
<video-moq
src="https://example.com/my-moq-stream?namespace=demo"
fingerprint="https://example.com/fingerprint"
width="640"
muted
controls
></video-moq>
The built-in controls are basic. If you want more advanced controls or custom styling, see the Styling & Media Chrome section or our samples.
Simple Player
If you’d prefer to implement your own UI or integrate the player logic differently, use the class-based Player:
import { Player } from "moq-player";
async function initPlayer() {
const canvas = document.getElementById("my-canvas");
const player = await Player.create({
url: "https://example.com/my-moq-stream",
fingerprint: "https://example.com/fingerprint",
namespace: "demo",
canvas,
});
player.play();
}
Events
Both the Web Component and the Class-Based Player emit a series of events to help track playback state:
play
pause
loadeddata
volumechange
unsubscribestared
unsubscribedone
subscribestared
subscribedone
waitingforkeyframe
timeupdate
You can listen to these events in the usual way. For example:
const videoMoq = document.querySelector("video-moq");
videoMoq.addEventListener("play", () => {
console.log("Playback started!");
});
See samples/event-handling for complete examples.
Styling & Media Chrome
When using the <video-moq> element, you can style it in various ways:
- Media Chrome: Integrate
<video-moq> inside a <media-controller> and use <media-play-button>, <media-time-range>, and other controls. See samples/media-chrome for an example.
<script type="module" src="https://cdn.jsdelivr.net/npm/media-chrome@4/+esm"></script>
<media-controller>
<video-moq slot="media" src="..." controls></video-moq>
<media-play-button></media-play-button>
<media-mute-button></media-mute-button>
</media-controller>
- player.style: You can also use custom themes from player.style to style the player. See
samples/media-chrome for a working example.
<script type="module" src="https://cdn.jsdelivr.net/npm/player.style/x-mas/+esm"></script>
<media-theme-x-mas>
<video-moq
src="https://localhost:4443?namespace=bbb"
fingerprint="https://localhost:4443/fingerprint"
width="640px"
slot="media"
></video-moq>
</media-theme-x-mas>
Samples
The samples/ directory demonstrates:
- Web Component Basic – A simple
<video-moq> usage.
- Web Component Advanced – Using the component as an ES module.
- Media Chrome – Integrating
<video-moq> with player.style custom themes.
- Simple Player – Using the class-based Player without built-in controls.
- Event Handling – Listening for playback and subscription events in detail.
Development
npm install
- Run the dev server for local testing:
npm run dev
Open localhost:3000 in a browser to see the samples running.
License
Licensed under either:
- Join our Discord for updates and discussion.
- File issues or suggestions via GitHub Issues.
- Pull requests are welcome!