livekit-client 1.10.0 → 1.11.0
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.esm.mjs +457 -478
- 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/connectionHelper/ConnectionCheck.d.ts +2 -3
- package/dist/src/connectionHelper/ConnectionCheck.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/Checker.d.ts +2 -3
- package/dist/src/connectionHelper/checks/Checker.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +1 -1
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +2 -4
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +3 -4
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +2 -4
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts +2 -1
- 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/LocalTrack.d.ts +1 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteVideoTrack.d.ts +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +2 -4
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/TrackPublication.d.ts +2 -4
- package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +13 -4
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/types.d.ts +2 -1
- package/dist/src/room/track/types.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/src/connectionHelper/ConnectionCheck.d.ts +2 -3
- package/dist/ts4.2/src/connectionHelper/checks/Checker.d.ts +2 -3
- package/dist/ts4.2/src/room/PCTransport.d.ts +1 -1
- package/dist/ts4.2/src/room/RTCEngine.d.ts +2 -4
- package/dist/ts4.2/src/room/Room.d.ts +3 -4
- package/dist/ts4.2/src/room/participant/Participant.d.ts +2 -4
- package/dist/ts4.2/src/room/participant/RemoteParticipant.d.ts +2 -1
- package/dist/ts4.2/src/room/track/LocalTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +1 -1
- package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +1 -0
- package/dist/ts4.2/src/room/track/Track.d.ts +2 -4
- package/dist/ts4.2/src/room/track/TrackPublication.d.ts +2 -4
- package/dist/ts4.2/src/room/track/options.d.ts +13 -4
- package/dist/ts4.2/src/room/track/types.d.ts +2 -1
- package/package.json +2 -3
- package/src/connectionHelper/ConnectionCheck.ts +2 -3
- package/src/connectionHelper/checks/Checker.ts +2 -3
- package/src/logger.ts +4 -4
- package/src/room/PCTransport.ts +1 -1
- package/src/room/RTCEngine.ts +4 -4
- package/src/room/Room.ts +41 -11
- package/src/room/participant/LocalParticipant.ts +11 -3
- package/src/room/participant/Participant.ts +2 -4
- package/src/room/participant/RemoteParticipant.ts +4 -3
- package/src/room/participant/publishUtils.ts +16 -18
- package/src/room/track/LocalTrack.ts +61 -42
- package/src/room/track/LocalVideoTrack.ts +9 -7
- package/src/room/track/RemoteVideoTrack.ts +23 -6
- package/src/room/track/Track.ts +2 -4
- package/src/room/track/TrackPublication.ts +2 -4
- package/src/room/track/options.ts +13 -4
- package/src/room/track/types.ts +2 -1
- package/src/room/utils.ts +6 -3
@@ -351,8 +351,13 @@ async function setPublishingLayersForSender(
|
|
351
351
|
|
352
352
|
let hasChanged = false;
|
353
353
|
|
354
|
+
/* disable closable spatial layer as it has video blur / frozen issue with current server / client
|
355
|
+
1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
|
356
|
+
low resolution frame and recover very quickly, but noticable
|
357
|
+
2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable */
|
358
|
+
const closableSpatial = false;
|
354
359
|
/* @ts-ignore */
|
355
|
-
if (
|
360
|
+
if (closableSpatial && encodings[0].scalabilityMode) {
|
356
361
|
// svc dynacast encodings
|
357
362
|
const encoding = encodings[0];
|
358
363
|
/* @ts-ignore */
|
@@ -372,10 +377,7 @@ async function setPublishingLayersForSender(
|
|
372
377
|
} else if (!encoding.active /* || mode.spatial !== maxQuality + 1*/) {
|
373
378
|
hasChanged = true;
|
374
379
|
encoding.active = true;
|
375
|
-
/*
|
376
|
-
1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
|
377
|
-
low resolution frame and recover very quickly, but noticable
|
378
|
-
2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable
|
380
|
+
/*
|
379
381
|
@ts-ignore
|
380
382
|
const originalMode = new ScalabilityMode(senderEncodings[0].scalabilityMode)
|
381
383
|
mode.spatial = maxQuality + 1;
|
@@ -456,6 +458,7 @@ export function videoLayersFromEncodings(
|
|
456
458
|
width: number,
|
457
459
|
height: number,
|
458
460
|
encodings?: RTCRtpEncodingParameters[],
|
461
|
+
svc?: boolean,
|
459
462
|
): VideoLayer[] {
|
460
463
|
// default to a single layer, HQ
|
461
464
|
if (!encodings) {
|
@@ -470,8 +473,7 @@ export function videoLayersFromEncodings(
|
|
470
473
|
];
|
471
474
|
}
|
472
475
|
|
473
|
-
|
474
|
-
if (encodings.length === 1 && encodings[0].scalabilityMode) {
|
476
|
+
if (svc) {
|
475
477
|
// svc layers
|
476
478
|
/* @ts-ignore */
|
477
479
|
const sm = new ScalabilityMode(encodings[0].scalabilityMode);
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { debounce } from 'ts-debounce';
|
2
2
|
import log from '../../logger';
|
3
3
|
import { TrackEvent } from '../events';
|
4
|
-
import { computeBitrate } from '../stats';
|
5
4
|
import type { VideoReceiverStats } from '../stats';
|
5
|
+
import { computeBitrate } from '../stats';
|
6
6
|
import CriticalTimers from '../timers';
|
7
|
-
import { getDevicePixelRatio, getIntersectionObserver, getResizeObserver, isWeb } from '../utils';
|
8
7
|
import type { ObservableMediaElement } from '../utils';
|
8
|
+
import { getDevicePixelRatio, getIntersectionObserver, getResizeObserver, isWeb } from '../utils';
|
9
9
|
import RemoteTrack from './RemoteTrack';
|
10
10
|
import { Track, attachToElement, detachTrack } from './Track';
|
11
11
|
import type { AdaptiveStreamSettings } from './types';
|
@@ -248,11 +248,10 @@ export default class RemoteVideoTrack extends RemoteTrack {
|
|
248
248
|
private updateDimensions() {
|
249
249
|
let maxWidth = 0;
|
250
250
|
let maxHeight = 0;
|
251
|
+
const pixelDensity = this.getPixelDensity();
|
251
252
|
for (const info of this.elementInfos) {
|
252
|
-
const
|
253
|
-
const
|
254
|
-
const currentElementWidth = info.width() * pixelDensityValue;
|
255
|
-
const currentElementHeight = info.height() * pixelDensityValue;
|
253
|
+
const currentElementWidth = info.width() * pixelDensity;
|
254
|
+
const currentElementHeight = info.height() * pixelDensity;
|
256
255
|
if (currentElementWidth + currentElementHeight > maxWidth + maxHeight) {
|
257
256
|
maxWidth = currentElementWidth;
|
258
257
|
maxHeight = currentElementHeight;
|
@@ -270,6 +269,24 @@ export default class RemoteVideoTrack extends RemoteTrack {
|
|
270
269
|
|
271
270
|
this.emit(TrackEvent.VideoDimensionsChanged, this.lastDimensions, this);
|
272
271
|
}
|
272
|
+
|
273
|
+
private getPixelDensity(): number {
|
274
|
+
const pixelDensity = this.adaptiveStreamSettings?.pixelDensity;
|
275
|
+
if (pixelDensity === 'screen') {
|
276
|
+
return getDevicePixelRatio();
|
277
|
+
} else if (!pixelDensity) {
|
278
|
+
// when unset, we'll pick a sane default here.
|
279
|
+
// for higher pixel density devices (mobile phones, etc), we'll use 2
|
280
|
+
// otherwise it defaults to 1
|
281
|
+
const devicePixelRatio = getDevicePixelRatio();
|
282
|
+
if (devicePixelRatio > 2) {
|
283
|
+
return 2;
|
284
|
+
} else {
|
285
|
+
return 1;
|
286
|
+
}
|
287
|
+
}
|
288
|
+
return pixelDensity;
|
289
|
+
}
|
273
290
|
}
|
274
291
|
|
275
292
|
export interface ElementInfo {
|
package/src/room/track/Track.ts
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import type TypedEventEmitter from 'typed-emitter';
|
1
|
+
import EventEmitter from 'eventemitter3';
|
3
2
|
import type { SignalClient } from '../../api/SignalClient';
|
4
3
|
import log from '../../logger';
|
5
4
|
import { TrackSource, TrackType } from '../../proto/livekit_models';
|
@@ -13,7 +12,7 @@ const BACKGROUND_REACTION_DELAY = 5000;
|
|
13
12
|
// Safari tracks which audio elements have been "blessed" by the user.
|
14
13
|
const recycledElements: Array<HTMLAudioElement> = [];
|
15
14
|
|
16
|
-
export abstract class Track extends
|
15
|
+
export abstract class Track extends EventEmitter<TrackEventCallbacks> {
|
17
16
|
kind: Track.Kind;
|
18
17
|
|
19
18
|
attachedElements: HTMLMediaElement[] = [];
|
@@ -52,7 +51,6 @@ export abstract class Track extends (EventEmitter as new () => TypedEventEmitter
|
|
52
51
|
|
53
52
|
protected constructor(mediaTrack: MediaStreamTrack, kind: Track.Kind) {
|
54
53
|
super();
|
55
|
-
this.setMaxListeners(100);
|
56
54
|
this.kind = kind;
|
57
55
|
this._mediaStreamTrack = mediaTrack;
|
58
56
|
this._mediaStreamID = mediaTrack.id;
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import type TypedEventEmitter from 'typed-emitter';
|
1
|
+
import EventEmitter from 'eventemitter3';
|
3
2
|
import log from '../../logger';
|
4
3
|
import type { SubscriptionError, TrackInfo } from '../../proto/livekit_models';
|
5
4
|
import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc';
|
@@ -11,7 +10,7 @@ import type RemoteTrack from './RemoteTrack';
|
|
11
10
|
import RemoteVideoTrack from './RemoteVideoTrack';
|
12
11
|
import { Track } from './Track';
|
13
12
|
|
14
|
-
export class TrackPublication extends
|
13
|
+
export class TrackPublication extends EventEmitter<PublicationEventCallbacks> {
|
15
14
|
kind: Track.Kind;
|
16
15
|
|
17
16
|
trackName: string;
|
@@ -38,7 +37,6 @@ export class TrackPublication extends (EventEmitter as new () => TypedEventEmitt
|
|
38
37
|
|
39
38
|
constructor(kind: Track.Kind, id: string, name: string) {
|
40
39
|
super();
|
41
|
-
this.setMaxListeners(100);
|
42
40
|
this.kind = kind;
|
43
41
|
this.trackSid = id;
|
44
42
|
this.trackName = name;
|
@@ -63,10 +63,19 @@ export interface TrackPublishDefaults {
|
|
63
63
|
scalabilityMode?: ScalabilityMode;
|
64
64
|
|
65
65
|
/**
|
66
|
-
*
|
67
|
-
*
|
68
|
-
*
|
69
|
-
*
|
66
|
+
* Up to two additional simulcast layers to publish in addition to the original
|
67
|
+
* Track.
|
68
|
+
* When left blank, it defaults to h180, h360.
|
69
|
+
* If a SVC codec is used (VP9 or AV1), this field has no effect.
|
70
|
+
*
|
71
|
+
* To publish three total layers, you would specify:
|
72
|
+
* {
|
73
|
+
* videoEncoding: {...}, // encoding of the primary layer
|
74
|
+
* videoSimulcastLayers: [
|
75
|
+
* VideoPresets.h540,
|
76
|
+
* VideoPresets.h216,
|
77
|
+
* ],
|
78
|
+
* }
|
70
79
|
*/
|
71
80
|
videoSimulcastLayers?: Array<VideoPreset>;
|
72
81
|
|
package/src/room/track/types.ts
CHANGED
@@ -8,7 +8,8 @@ export type VideoTrack = RemoteVideoTrack | LocalVideoTrack;
|
|
8
8
|
|
9
9
|
export type AdaptiveStreamSettings = {
|
10
10
|
/**
|
11
|
-
* Set a custom pixel density
|
11
|
+
* Set a custom pixel density. Defaults to 2 for high density screens (3+) or
|
12
|
+
* 1 otherwise.
|
12
13
|
* When streaming videos on a ultra high definition screen this setting
|
13
14
|
* let's you account for the devicePixelRatio of those screens.
|
14
15
|
* Set it to `screen` to use the actual pixel density of the screen
|
package/src/room/utils.ts
CHANGED
@@ -261,7 +261,7 @@ export function getEmptyVideoStreamTrack() {
|
|
261
261
|
if (!emptyVideoStreamTrack) {
|
262
262
|
emptyVideoStreamTrack = createDummyVideoStreamTrack();
|
263
263
|
}
|
264
|
-
return emptyVideoStreamTrack;
|
264
|
+
return emptyVideoStreamTrack.clone();
|
265
265
|
}
|
266
266
|
|
267
267
|
export function createDummyVideoStreamTrack(
|
@@ -301,8 +301,11 @@ export function getEmptyAudioStreamTrack() {
|
|
301
301
|
// implementation adapted from https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/
|
302
302
|
const ctx = new AudioContext();
|
303
303
|
const oscillator = ctx.createOscillator();
|
304
|
+
const gain = ctx.createGain();
|
305
|
+
gain.gain.setValueAtTime(0, 0);
|
304
306
|
const dst = ctx.createMediaStreamDestination();
|
305
|
-
oscillator.connect(
|
307
|
+
oscillator.connect(gain);
|
308
|
+
gain.connect(dst);
|
306
309
|
oscillator.start();
|
307
310
|
[emptyAudioStreamTrack] = dst.stream.getAudioTracks();
|
308
311
|
if (!emptyAudioStreamTrack) {
|
@@ -310,7 +313,7 @@ export function getEmptyAudioStreamTrack() {
|
|
310
313
|
}
|
311
314
|
emptyAudioStreamTrack.enabled = false;
|
312
315
|
}
|
313
|
-
return emptyAudioStreamTrack;
|
316
|
+
return emptyAudioStreamTrack.clone();
|
314
317
|
}
|
315
318
|
|
316
319
|
export class Future<T> {
|