livekit-client 1.8.0 → 1.9.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +9 -7
- package/dist/livekit-client.esm.mjs +13550 -13342
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +11 -10
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts +1 -1
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/Checker.d.ts +1 -1
- package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
- package/dist/src/index.d.ts +5 -7
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/proto/livekit_models.d.ts +5 -0
- package/dist/src/proto/livekit_models.d.ts.map +1 -1
- package/dist/src/proto/livekit_rtc.d.ts +32 -0
- package/dist/src/proto/livekit_rtc.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +5 -3
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +20 -15
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +15 -0
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +14 -2
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +4 -2
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +2 -2
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +1 -1
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts +1 -1
- package/dist/src/room/track/LocalTrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +7 -1
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/types.d.ts +1 -0
- package/dist/src/room/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +3 -0
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/api/SignalClient.d.ts +14 -10
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +1 -1
- package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +1 -1
- package/dist/ts4.2/src/index.d.ts +6 -7
- package/dist/ts4.2/src/proto/livekit_models.d.ts +5 -0
- package/dist/ts4.2/src/proto/livekit_rtc.d.ts +32 -0
- package/dist/ts4.2/src/room/RTCEngine.d.ts +5 -3
- package/dist/ts4.2/src/room/Room.d.ts +20 -15
- package/dist/ts4.2/src/room/events.d.ts +15 -0
- package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +14 -2
- package/dist/ts4.2/src/room/participant/Participant.d.ts +4 -2
- package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +2 -2
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/LocalTrackPublication.d.ts +1 -1
- package/dist/ts4.2/src/room/track/RemoteAudioTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/options.d.ts +7 -0
- package/dist/ts4.2/src/room/types.d.ts +1 -0
- package/dist/ts4.2/src/room/utils.d.ts +3 -0
- package/package.json +4 -3
- package/src/api/SignalClient.ts +38 -26
- package/src/connectionHelper/ConnectionCheck.ts +1 -2
- package/src/connectionHelper/checks/Checker.ts +1 -1
- package/src/connectionHelper/checks/reconnect.ts +1 -1
- package/src/index.ts +8 -10
- package/src/proto/livekit_models.ts +15 -0
- package/src/room/PCTransport.ts +40 -1
- package/src/room/RTCEngine.ts +32 -11
- package/src/room/RegionUrlProvider.ts +1 -1
- package/src/room/Room.ts +114 -70
- package/src/room/events.ts +17 -0
- package/src/room/participant/LocalParticipant.ts +65 -11
- package/src/room/participant/Participant.ts +27 -3
- package/src/room/participant/RemoteParticipant.ts +6 -3
- package/src/room/participant/publishUtils.test.ts +1 -1
- package/src/room/participant/publishUtils.ts +14 -6
- package/src/room/track/LocalAudioTrack.ts +1 -1
- package/src/room/track/LocalTrack.ts +2 -2
- package/src/room/track/LocalTrackPublication.ts +1 -1
- package/src/room/track/LocalVideoTrack.ts +3 -3
- package/src/room/track/RemoteAudioTrack.ts +1 -1
- package/src/room/track/RemoteVideoTrack.test.ts +1 -1
- package/src/room/track/RemoteVideoTrack.ts +3 -3
- package/src/room/track/create.ts +2 -2
- package/src/room/track/options.ts +14 -1
- package/src/room/types.ts +11 -0
- package/src/room/utils.ts +18 -8
@@ -2,10 +2,10 @@ import { EventEmitter } from 'events';
|
|
2
2
|
import type TypedEmitter from 'typed-emitter';
|
3
3
|
import log from '../../logger';
|
4
4
|
import {
|
5
|
-
ConnectionQuality as ProtoQuality,
|
6
5
|
DataPacket_Kind,
|
7
6
|
ParticipantInfo,
|
8
7
|
ParticipantPermission,
|
8
|
+
ConnectionQuality as ProtoQuality,
|
9
9
|
} from '../../proto/livekit_models';
|
10
10
|
import { ParticipantEvent, TrackEvent } from '../events';
|
11
11
|
import type LocalTrackPublication from '../track/LocalTrackPublication';
|
@@ -144,10 +144,23 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
|
|
144
144
|
}
|
145
145
|
|
146
146
|
/** @internal */
|
147
|
-
updateInfo(info: ParticipantInfo) {
|
147
|
+
updateInfo(info: ParticipantInfo): boolean {
|
148
|
+
// it's possible the update could be applied out of order due to await
|
149
|
+
// during reconnect sequences. when that happens, it's possible for server
|
150
|
+
// to have sent more recent version of participant info while JS is waiting
|
151
|
+
// to process the existing payload.
|
152
|
+
// when the participant sid remains the same, and we already have a later version
|
153
|
+
// of the payload, they can be safely skipped
|
154
|
+
if (
|
155
|
+
this.participantInfo &&
|
156
|
+
this.participantInfo.sid === info.sid &&
|
157
|
+
this.participantInfo.version > info.version
|
158
|
+
) {
|
159
|
+
return false;
|
160
|
+
}
|
148
161
|
this.identity = info.identity;
|
149
162
|
this.sid = info.sid;
|
150
|
-
this.
|
163
|
+
this.setName(info.name);
|
151
164
|
this.setMetadata(info.metadata);
|
152
165
|
if (info.permission) {
|
153
166
|
this.setPermissions(info.permission);
|
@@ -155,6 +168,7 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
|
|
155
168
|
// set this last so setMetadata can detect changes
|
156
169
|
this.participantInfo = info;
|
157
170
|
log.trace('update participant info', { info });
|
171
|
+
return true;
|
158
172
|
}
|
159
173
|
|
160
174
|
/** @internal */
|
@@ -168,6 +182,15 @@ export default class Participant extends (EventEmitter as new () => TypedEmitter
|
|
168
182
|
}
|
169
183
|
}
|
170
184
|
|
185
|
+
protected setName(name: string) {
|
186
|
+
const changed = this.name !== name;
|
187
|
+
this.name = name;
|
188
|
+
|
189
|
+
if (changed) {
|
190
|
+
this.emit(ParticipantEvent.ParticipantNameChanged, name);
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
171
194
|
/** @internal */
|
172
195
|
setPermissions(permissions: ParticipantPermission): boolean {
|
173
196
|
const prevPermissions = this.permissions;
|
@@ -250,6 +273,7 @@ export type ParticipantEventCallbacks = {
|
|
250
273
|
localTrackPublished: (publication: LocalTrackPublication) => void;
|
251
274
|
localTrackUnpublished: (publication: LocalTrackPublication) => void;
|
252
275
|
participantMetadataChanged: (prevMetadata: string | undefined, participant?: any) => void;
|
276
|
+
participantNameChanged: (name: string) => void;
|
253
277
|
dataReceived: (payload: Uint8Array, kind: DataPacket_Kind) => void;
|
254
278
|
isSpeakingChanged: (speaking: boolean) => void;
|
255
279
|
connectionQualityChanged: (connectionQuality: ConnectionQuality) => void;
|
@@ -3,13 +3,13 @@ import log from '../../logger';
|
|
3
3
|
import type { ParticipantInfo } from '../../proto/livekit_models';
|
4
4
|
import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc';
|
5
5
|
import { ParticipantEvent, TrackEvent } from '../events';
|
6
|
-
import type { AudioOutputOptions } from '../track/options';
|
7
6
|
import RemoteAudioTrack from '../track/RemoteAudioTrack';
|
8
7
|
import type RemoteTrack from '../track/RemoteTrack';
|
9
8
|
import RemoteTrackPublication from '../track/RemoteTrackPublication';
|
10
9
|
import RemoteVideoTrack from '../track/RemoteVideoTrack';
|
11
10
|
import { Track } from '../track/Track';
|
12
11
|
import type { TrackPublication } from '../track/TrackPublication';
|
12
|
+
import type { AudioOutputOptions } from '../track/options';
|
13
13
|
import type { AdaptiveStreamSettings } from '../track/types';
|
14
14
|
import Participant, { ParticipantEventCallbacks } from './Participant';
|
15
15
|
|
@@ -215,8 +215,10 @@ export default class RemoteParticipant extends Participant {
|
|
215
215
|
}
|
216
216
|
|
217
217
|
/** @internal */
|
218
|
-
updateInfo(info: ParticipantInfo) {
|
219
|
-
super.updateInfo(info)
|
218
|
+
updateInfo(info: ParticipantInfo): boolean {
|
219
|
+
if (!super.updateInfo(info)) {
|
220
|
+
return false;
|
221
|
+
}
|
220
222
|
|
221
223
|
// we are getting a list of all available tracks, reconcile in here
|
222
224
|
// and send out events for changes
|
@@ -277,6 +279,7 @@ export default class RemoteParticipant extends Participant {
|
|
277
279
|
newTracks.forEach((publication) => {
|
278
280
|
this.emit(ParticipantEvent.TrackPublished, publication);
|
279
281
|
});
|
282
|
+
return true;
|
280
283
|
}
|
281
284
|
|
282
285
|
/** @internal */
|
@@ -2,6 +2,7 @@ import log from '../../logger';
|
|
2
2
|
import { TrackInvalidError } from '../errors';
|
3
3
|
import LocalAudioTrack from '../track/LocalAudioTrack';
|
4
4
|
import LocalVideoTrack from '../track/LocalVideoTrack';
|
5
|
+
import { Track } from '../track/Track';
|
5
6
|
import {
|
6
7
|
BackupVideoCodec,
|
7
8
|
ScreenSharePresets,
|
@@ -12,7 +13,7 @@ import {
|
|
12
13
|
VideoPresets,
|
13
14
|
VideoPresets43,
|
14
15
|
} from '../track/options';
|
15
|
-
import {
|
16
|
+
import { isSVCCodec } from '../utils';
|
16
17
|
|
17
18
|
/** @internal */
|
18
19
|
export function mediaTrackToLocalTrack(
|
@@ -121,7 +122,7 @@ export function computeVideoEncodings(
|
|
121
122
|
videoEncoding.maxFramerate,
|
122
123
|
);
|
123
124
|
|
124
|
-
if (scalabilityMode && videoCodec
|
125
|
+
if (scalabilityMode && isSVCCodec(videoCodec)) {
|
125
126
|
log.debug(`using svc with scalabilityMode ${scalabilityMode}`);
|
126
127
|
|
127
128
|
const encodings: RTCRtpEncodingParameters[] = [];
|
@@ -248,8 +249,13 @@ export function determineAppropriateEncoding(
|
|
248
249
|
if (codec) {
|
249
250
|
switch (codec) {
|
250
251
|
case 'av1':
|
252
|
+
encoding = { ...encoding };
|
251
253
|
encoding.maxBitrate = encoding.maxBitrate * 0.7;
|
252
254
|
break;
|
255
|
+
case 'vp9':
|
256
|
+
encoding = { ...encoding };
|
257
|
+
encoding.maxBitrate = encoding.maxBitrate * 0.85;
|
258
|
+
break;
|
253
259
|
default:
|
254
260
|
break;
|
255
261
|
}
|
@@ -303,13 +309,15 @@ function encodingsFromPresets(
|
|
303
309
|
}
|
304
310
|
const size = Math.min(width, height);
|
305
311
|
const rid = videoRids[idx];
|
306
|
-
|
312
|
+
const encoding: RTCRtpEncodingParameters = {
|
307
313
|
rid,
|
308
314
|
scaleResolutionDownBy: Math.max(1, size / Math.min(preset.width, preset.height)),
|
309
315
|
maxBitrate: preset.encoding.maxBitrate,
|
310
|
-
|
311
|
-
|
312
|
-
|
316
|
+
};
|
317
|
+
if (preset.encoding.maxFramerate) {
|
318
|
+
encoding.maxFramerate = preset.encoding.maxFramerate;
|
319
|
+
}
|
320
|
+
encodings.push(encoding);
|
313
321
|
});
|
314
322
|
return encodings;
|
315
323
|
}
|
@@ -3,8 +3,8 @@ import { TrackEvent } from '../events';
|
|
3
3
|
import { AudioSenderStats, computeBitrate, monitorFrequency } from '../stats';
|
4
4
|
import { isWeb } from '../utils';
|
5
5
|
import LocalTrack from './LocalTrack';
|
6
|
-
import type { AudioCaptureOptions } from './options';
|
7
6
|
import { Track } from './Track';
|
7
|
+
import type { AudioCaptureOptions } from './options';
|
8
8
|
import { constraintsForOptions, detectSilence } from './utils';
|
9
9
|
|
10
10
|
export default class LocalAudioTrack extends LocalTrack {
|
@@ -3,14 +3,14 @@ import DeviceManager from '../DeviceManager';
|
|
3
3
|
import { TrackInvalidError } from '../errors';
|
4
4
|
import { TrackEvent } from '../events';
|
5
5
|
import {
|
6
|
+
Mutex,
|
6
7
|
getEmptyAudioStreamTrack,
|
7
8
|
getEmptyVideoStreamTrack,
|
8
9
|
isMobile,
|
9
|
-
Mutex,
|
10
10
|
sleep,
|
11
11
|
} from '../utils';
|
12
|
+
import { Track, attachToElement, detachTrack } from './Track';
|
12
13
|
import type { VideoCodec } from './options';
|
13
|
-
import { attachToElement, detachTrack, Track } from './Track';
|
14
14
|
|
15
15
|
const defaultDimensionsTimeout = 2 * 1000;
|
16
16
|
|
@@ -3,9 +3,9 @@ import { TrackEvent } from '../events';
|
|
3
3
|
import type LocalAudioTrack from './LocalAudioTrack';
|
4
4
|
import type LocalTrack from './LocalTrack';
|
5
5
|
import type LocalVideoTrack from './LocalVideoTrack';
|
6
|
-
import type { TrackPublishOptions } from './options';
|
7
6
|
import type { Track } from './Track';
|
8
7
|
import { TrackPublication } from './TrackPublication';
|
8
|
+
import type { TrackPublishOptions } from './options';
|
9
9
|
|
10
10
|
export default class LocalTrackPublication extends TrackPublication {
|
11
11
|
track?: LocalTrack = undefined;
|
@@ -2,11 +2,11 @@ import type { SignalClient } from '../../api/SignalClient';
|
|
2
2
|
import log from '../../logger';
|
3
3
|
import { VideoLayer, VideoQuality } from '../../proto/livekit_models';
|
4
4
|
import type { SubscribedCodec, SubscribedQuality } from '../../proto/livekit_rtc';
|
5
|
-
import { computeBitrate, monitorFrequency
|
6
|
-
import { isFireFox, isMobile, isWeb
|
5
|
+
import { VideoSenderStats, computeBitrate, monitorFrequency } from '../stats';
|
6
|
+
import { Mutex, isFireFox, isMobile, isWeb } from '../utils';
|
7
7
|
import LocalTrack from './LocalTrack';
|
8
|
-
import type { VideoCaptureOptions, VideoCodec } from './options';
|
9
8
|
import { Track } from './Track';
|
9
|
+
import type { VideoCaptureOptions, VideoCodec } from './options';
|
10
10
|
import { constraintsForOptions } from './utils';
|
11
11
|
|
12
12
|
export class SimulcastTrackInfo {
|
@@ -2,9 +2,9 @@ import log from '../../logger';
|
|
2
2
|
import { TrackEvent } from '../events';
|
3
3
|
import { AudioReceiverStats, computeBitrate } from '../stats';
|
4
4
|
import { supportsSetSinkId } from '../utils';
|
5
|
-
import type { AudioOutputOptions } from './options';
|
6
5
|
import RemoteTrack from './RemoteTrack';
|
7
6
|
import { Track } from './Track';
|
7
|
+
import type { AudioOutputOptions } from './options';
|
8
8
|
|
9
9
|
export default class RemoteAudioTrack extends RemoteTrack {
|
10
10
|
private prevStats?: AudioReceiverStats;
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import MockMediaStreamTrack from '../../test/MockMediaStreamTrack';
|
1
2
|
import { TrackEvent } from '../events';
|
2
3
|
import RemoteVideoTrack, { ElementInfo } from './RemoteVideoTrack';
|
3
|
-
import MockMediaStreamTrack from '../../test/MockMediaStreamTrack';
|
4
4
|
import type { Track } from './Track';
|
5
5
|
|
6
6
|
jest.useFakeTimers();
|
@@ -1,17 +1,17 @@
|
|
1
1
|
import { debounce } from 'ts-debounce';
|
2
2
|
import log from '../../logger';
|
3
3
|
import { TrackEvent } from '../events';
|
4
|
-
import {
|
4
|
+
import { VideoReceiverStats, computeBitrate } from '../stats';
|
5
5
|
import CriticalTimers from '../timers';
|
6
6
|
import {
|
7
|
+
ObservableMediaElement,
|
7
8
|
getDevicePixelRatio,
|
8
9
|
getIntersectionObserver,
|
9
10
|
getResizeObserver,
|
10
11
|
isWeb,
|
11
|
-
ObservableMediaElement,
|
12
12
|
} from '../utils';
|
13
13
|
import RemoteTrack from './RemoteTrack';
|
14
|
-
import { attachToElement, detachTrack
|
14
|
+
import { Track, attachToElement, detachTrack } from './Track';
|
15
15
|
import type { AdaptiveStreamSettings } from './types';
|
16
16
|
|
17
17
|
const REACTION_DELAY = 100;
|
package/src/room/track/create.ts
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
import DeviceManager from '../DeviceManager';
|
2
|
+
import { audioDefaults, videoDefaults } from '../defaults';
|
2
3
|
import { DeviceUnsupportedError, TrackInvalidError } from '../errors';
|
3
4
|
import { mediaTrackToLocalTrack } from '../participant/publishUtils';
|
4
|
-
import { audioDefaults, videoDefaults } from '../defaults';
|
5
5
|
import LocalAudioTrack from './LocalAudioTrack';
|
6
6
|
import type LocalTrack from './LocalTrack';
|
7
7
|
import LocalVideoTrack from './LocalVideoTrack';
|
8
|
+
import { Track } from './Track';
|
8
9
|
import {
|
9
10
|
AudioCaptureOptions,
|
10
11
|
CreateLocalTracksOptions,
|
@@ -12,7 +13,6 @@ import {
|
|
12
13
|
VideoCaptureOptions,
|
13
14
|
VideoPresets,
|
14
15
|
} from './options';
|
15
|
-
import { Track } from './Track';
|
16
16
|
import { constraintsForOptions, mergeDefaultOptions } from './utils';
|
17
17
|
|
18
18
|
/**
|
@@ -145,6 +145,12 @@ export interface ScreenShareCaptureOptions {
|
|
145
145
|
|
146
146
|
/** specifies whether the browser should include the system audio among the possible audio sources offered to the user */
|
147
147
|
systemAudio?: 'include' | 'exclude';
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Experimental option to control whether the audio playing in a tab will continue to be played out of a user's
|
151
|
+
* local speakers when the tab is captured.
|
152
|
+
*/
|
153
|
+
suppressLocalAudioPlayback?: boolean;
|
148
154
|
}
|
149
155
|
|
150
156
|
export interface AudioCaptureOptions {
|
@@ -241,7 +247,7 @@ export interface AudioPreset {
|
|
241
247
|
maxBitrate: number;
|
242
248
|
}
|
243
249
|
|
244
|
-
const codecs = ['vp8', 'h264', 'av1'] as const;
|
250
|
+
const codecs = ['vp8', 'h264', 'vp9', 'av1'] as const;
|
245
251
|
const backupCodecs = ['vp8', 'h264'] as const;
|
246
252
|
|
247
253
|
export type VideoCodec = (typeof codecs)[number];
|
@@ -252,6 +258,13 @@ export function isBackupCodec(codec: string): codec is BackupVideoCodec {
|
|
252
258
|
return !!backupCodecs.find((backup) => backup === codec);
|
253
259
|
}
|
254
260
|
|
261
|
+
export function isCodecEqual(c1: string | undefined, c2: string | undefined): boolean {
|
262
|
+
return (
|
263
|
+
c1?.toLowerCase().replace(/audio\/|video\//y, '') ===
|
264
|
+
c2?.toLowerCase().replace(/audio\/|video\//y, '')
|
265
|
+
);
|
266
|
+
}
|
267
|
+
|
255
268
|
/**
|
256
269
|
* scalability modes for svc, only supprot l3t3 now.
|
257
270
|
*/
|
package/src/room/types.ts
CHANGED
@@ -26,3 +26,14 @@ export type LiveKitReactNativeInfo = {
|
|
26
26
|
platform: 'ios' | 'android' | 'windows' | 'macos' | 'web' | 'native';
|
27
27
|
devicePixelRatio: number;
|
28
28
|
};
|
29
|
+
|
30
|
+
export type SimulationScenario =
|
31
|
+
| 'signal-reconnect'
|
32
|
+
| 'speaker'
|
33
|
+
| 'node-failure'
|
34
|
+
| 'server-leave'
|
35
|
+
| 'migration'
|
36
|
+
| 'resume-reconnect'
|
37
|
+
| 'force-tcp'
|
38
|
+
| 'force-tls'
|
39
|
+
| 'full-reconnect';
|
package/src/room/utils.ts
CHANGED
@@ -7,6 +7,8 @@ import { getNewAudioContext } from './track/utils';
|
|
7
7
|
import type { LiveKitReactNativeInfo } from './types';
|
8
8
|
|
9
9
|
const separator = '|';
|
10
|
+
export const ddExtensionURI =
|
11
|
+
'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
|
10
12
|
|
11
13
|
export function unpackStreamId(packed: string): string[] {
|
12
14
|
const parts = packed.split(separator);
|
@@ -41,7 +43,6 @@ export function supportsDynacast() {
|
|
41
43
|
export function supportsAV1(): boolean {
|
42
44
|
const capabilities = RTCRtpReceiver.getCapabilities('video');
|
43
45
|
let hasAV1 = false;
|
44
|
-
let hasDDExt = false;
|
45
46
|
if (capabilities) {
|
46
47
|
for (const codec of capabilities.codecs) {
|
47
48
|
if (codec.mimeType === 'video/AV1') {
|
@@ -49,17 +50,26 @@ export function supportsAV1(): boolean {
|
|
49
50
|
break;
|
50
51
|
}
|
51
52
|
}
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
53
|
+
}
|
54
|
+
return hasAV1;
|
55
|
+
}
|
56
|
+
|
57
|
+
export function supportsVP9(): boolean {
|
58
|
+
const capabilities = RTCRtpReceiver.getCapabilities('video');
|
59
|
+
let hasVP9 = false;
|
60
|
+
if (capabilities) {
|
61
|
+
for (const codec of capabilities.codecs) {
|
62
|
+
if (codec.mimeType === 'video/VP9') {
|
63
|
+
hasVP9 = true;
|
58
64
|
break;
|
59
65
|
}
|
60
66
|
}
|
61
67
|
}
|
62
|
-
return
|
68
|
+
return hasVP9;
|
69
|
+
}
|
70
|
+
|
71
|
+
export function isSVCCodec(codec?: string): boolean {
|
72
|
+
return codec === 'av1' || codec === 'vp9';
|
63
73
|
}
|
64
74
|
|
65
75
|
export function supportsSetSinkId(elm?: HTMLMediaElement): boolean {
|