Getting started with MoQ Ingest
The @vindral/publisher SDK is a practical way of providing users and operators with a browser-based workflow for publishing live streams to Vindral Live over MoQ.
There are multiple ways to integrate MoQ ingest, depending on your use-case:
- Hosted MoQ Publisher - The Vindral MoQ Publisher is hosted at publisher.vindral.com and can be used for validating and testing setups.
- Custom integration using the SDK - Follow the steps below to build your own publisher and read the Publisher SDK API reference.
Hosted MoQ Publisher
The Vindral MoQ Publisher is a web page for publishing live streams from the browser. You will find browser capabilities, connection, and media statistics to make it easier to validate setups and diagnose stability issues.
You can find the latest version of the hosted publisher at publisher.vindral.com.
Installation
Install @vindral/publisher using npm:
npm install --save @vindral/publisher
Google Chrome is recommended for the publisher SDK.
The publisher SDK relies on modern browser media APIs such as WebCodecs and WebTransport. In other browsers, API support may be partial, unavailable, or lower-performing, which can affect codec availability, hardware acceleration, and overall publishing performance.
Example usage
The Publisher constructor accepts the MoQ ingest url, the target channelId, and the authToken used for authorization. The example below uses the same publish URL as the official Publisher SDK reference. If Vindral has assigned a dedicated endpoint for your environment, use that instead.
import { Publisher } from "@vindral/publisher"
const stream = await navigator.mediaDevices.getUserMedia({
video: { width: 1280, height: 720 },
audio: { channelCount: 2, sampleRate: 48000 },
})
const publisher = new Publisher({
url: "https://moq.global.cdn.vindral.com:7001/voq/publish",
channelId: "your-channel-id",
authToken: "your-signed-token",
})
publisher.on("connection state", (state) => console.log("connection state:", state))
publisher.on("publisher state", (state) => console.log("publisher state:", state))
publisher.on("error", (error) => console.error(error))
publisher
.addTrack({
kind: "video",
track: stream.getVideoTracks()[0],
config: {
codec: "avc1.42E01E",
width: 1280,
height: 720,
bitrate: 2_000_000,
framerate: 30,
gopSize: 60,
},
})
.addTrack({
kind: "audio",
track: stream.getAudioTracks()[0],
config: {
codec: "opus",
sampleRate: 48_000,
numberOfChannels: 2,
bitrate: 128_000,
},
})
await publisher.publish()
The Publisher class exposes a simple lifecycle:
prepare()- starts encoding without connecting to the serverpublish()- connects and starts publishingunpublish()- stops the connection but keeps encoding activeclose()- shuts down the publisher completely
Connection state, publisher state, and errors can be observed through publisher.on(...). Current encoding and connection metrics can be read using publisher.stats().
Authentication
If your ingest setup uses JWT-based authorization, sign the token on your own backend and provide it as authToken. Read more in Authorizing ingress.
API reference
For full details, see the Publisher SDK API reference.