Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/honest-hornets-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'livekit-client': minor
---

Add backupCodecPolicy to TrackPublishDefaults
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like we should call it out in more detail in here that this is changing a default behaviour.

Copy link
Contributor Author

@cnderrauber cnderrauber Feb 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use the comment of codec policy as the detail and describe the behavior change, is there any format requirement here in the changeset file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, no there's no format required

6 changes: 6 additions & 0 deletions examples/demo/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
VideoCodec,
} from '../../src/index';
import {
BackupCodecPolicy,
ConnectionQuality,
ConnectionState,
DisconnectReason,
Expand Down Expand Up @@ -98,6 +99,10 @@ const appActions = {
const autoSubscribe = (<HTMLInputElement>$('auto-subscribe')).checked;
const e2eeEnabled = (<HTMLInputElement>$('e2ee')).checked;
const audioOutputId = (<HTMLSelectElement>$('audio-output')).value;
let backupCodecPolicy: BackupCodecPolicy | undefined;
if ((<HTMLInputElement>$('multicodec-simulcast')).checked) {
backupCodecPolicy = BackupCodecPolicy.SIMULCAST;
}

updateSearchParams(url, token, cryptoKey);

Expand All @@ -116,6 +121,7 @@ const appActions = {
forceStereo: false,
screenShareEncoding: ScreenSharePresets.h1080fps30.encoding,
scalabilityMode: 'L3T3_KEY',
backupCodecPolicy: backupCodecPolicy,
},
videoCaptureDefaults: {
resolution: VideoPresets.h720.resolution,
Expand Down
4 changes: 4 additions & 0 deletions examples/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ <h2>Livekit Sample App</h2>
disabled="true"
></select>
</div>
<div>
<input type="checkbox" class="form-check-input" id="multicodec-simulcast" />
<label for="multicodec-simulcast" class="form-check-label">MultiCodec-Simulcast </label>
</div>
</div>

<!-- actions -->
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
},
"dependencies": {
"@livekit/mutex": "1.1.1",
"@livekit/protocol": "1.32.0",
"@livekit/protocol": "1.33.0",
"events": "^3.3.0",
"loglevel": "^1.8.0",
"sdp-transform": "^2.14.1",
Expand Down
18 changes: 9 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/room/participant/LocalParticipant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ export default class LocalParticipant extends Participant {
stereo: isStereo,
disableRed: this.isE2EEEnabled || !(opts.red ?? true),
stream: opts?.stream,
backupCodecPolicy: opts?.backupCodecPolicy,
});

// compute encodings and layers for video
Expand Down
22 changes: 20 additions & 2 deletions src/room/track/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export interface TrackPublishDefaults {
videoEncoding?: VideoEncoding;

/**
* Multi-codec Simulcast
* VP9 and AV1 are not supported by all browser clients. When backupCodec is
* Advanced codecs (VP9/AV1/H265) are not supported by all browser clients. When backupCodec is
* set, when an incompatible client attempts to subscribe to the track, LiveKit
* will automatically publish a secondary track encoded with the backup codec.
*
Expand All @@ -24,6 +23,20 @@ export interface TrackPublishDefaults {
*/
backupCodec?: true | false | { codec: BackupVideoCodec; encoding?: VideoEncoding };

/**
* When backup codec is enabled, there are two options to decide whether to
* send the primary codec at the same time:
* * codec regression: publisher stops sending primary codec and all subscribers
* will receive backup codec even if the primary codec is supported on their browser. It is the default
* behavior and provides maximum compatibility. It also reduces CPU
* and bandwidth consumption for publisher.
* * multi-codec simulcast: publisher encodes and sends both codecs at same time,
* subscribers will get most efficient codec. It will provide most bandwidth
* efficiency, especially in the large 1:N room but requires more device performance
* and bandwidth consumption for publisher.
*/
backupCodecPolicy?: BackupCodecPolicy;

/**
* encoding parameters for screen share track
*/
Expand Down Expand Up @@ -375,6 +388,11 @@ export function isBackupCodec(codec: string): codec is BackupVideoCodec {
return !!backupCodecs.find((backup) => backup === codec);
}

export enum BackupCodecPolicy {
REGRESSION = 0,
SIMULCAST = 1,
}

/**
* scalability modes for svc.
*/
Expand Down