Simulcast lets a publisher send multiple encodings of one video source. Subscribers can select different quality levels for their display and network conditions.
A publisher can encode one video source at multiple qualities. Each encoding has an RTP Stream Identifier (RID), such as f, h, or q, advertised in its session description.
The publisher advertises its encodings. Each subscriber chooses a layer through the simulcast object on its remote track request. Each subscription has its own configuration.
Your backend makes the SFU API requests. Keep the App Secret there, check individual track results, and follow per-session mutation ordering throughout these tasks.
Configure the publishing endpoint before creating its offer. Its SDP advertises the simulcast encodings; the SFU uses those attributes for the local publication. For example, the SDP contains:
a=simulcast:send f;h;q
a=rid:f send
a=rid:h send
a=rid:q sendIn a browser, use this addTransceiver() call in place of the one in Publish audio or video. Here, track is a video MediaStreamTrack and peerConnection is the publishing connection:
const transceiver = peerConnection.addTransceiver(track, {
direction: "sendonly",
sendEncodings: [
{ scaleResolutionDownBy: 1, rid: "f" },
{ scaleResolutionDownBy: 2, rid: "h" },
{ scaleResolutionDownBy: 4, rid: "q" },
],
});Continue the publication recipe from offer creation on that same PeerConnection and its SFU session. The generated SDP contains a=simulcast:send. After publication succeeds, share the publisher's session ID, track name, and available RIDs with authorized subscribers.
Start with an existing publication that advertises simulcast encodings. Obtain its publisher session ID, track name, and available RIDs through your application. Prepare the receiving PeerConnection and its own SFU session using Receive a published track, but do not request the track yet.
-
On your backend, call
POST /apps/{appId}/sessions/{sessionId}/tracks/new. The URL identifies the receiving session. The request body identifies the publisher's session and publication:{ "tracks": [ { "location": "remote", "sessionId": "<PUBLISHER_SESSION_ID>", "trackName": "camera", "simulcast": { "preferredRid": "f", "priorityOrdering": "asciibetical", "ridNotAvailable": "asciibetical" } } ] }This example prefers
fand enables alphabetical fallback throughhandq. Use RIDs advertised by your publisher and choose the layer policy for your application. -
Check the track result and retain its receiving
midto identify this subscription. On the receiving endpoint, complete the returned SFU offer. Confirm that the publication plays there.
To change an existing subscription, update preferredRid through PUT /apps/{appId}/sessions/{sessionId}/tracks/update on your backend. The URL identifies the receiving session. Use that subscription's receiving mid in the request and select a RID advertised by the publisher.
Check the track result before advancing application state. Refer to the OpenAPI schema for the complete update body.
The simulcast object selects a layer and its fallback policy:
preferredRid: The preferred encoding's RID, as specified by the publisher ↗.priorityOrdering: Controls how the SFU handles bandwidth constraints.none: Keep sending the layer selected bypreferredRid, even if there is not enough bandwidth.asciibetical: Use alphabetical ordering (atoz) to determine priority.ais most desirable andzis least desirable.
ridNotAvailable: Controls what happens when the preferred RID is unavailable, for example when the publisher stops sending it.none: Do not select an alternative layer.asciibetical: Switch to the next available RID in alphabetical priority order.
Both priorityOrdering and ridNotAvailable default to none. Neither selects an alternative layer automatically with that default. When using asciibetical, assign RIDs in your desired priority order, such as highest resolution to lowest.
The video-room example demonstrates the publication and subscription lifecycle you would extend with simulcast. Use the publisher configuration on this page when adding video encodings.
The simulcast echo sample ↗ is a legacy reference. It places an SFU token in browser code and is not a recommended application starting point. Keep SFU API calls on your backend when adapting the sample.