livekit-client 2.13.4 → 2.13.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +11 -3
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +329 -76
- 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 +5 -5
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/connectionHelper/checks/publishVideo.d.ts.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +1 -0
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +2 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +3 -2
- package/dist/src/room/PCTransport.d.ts.map +1 -1
- package/dist/src/room/PCTransportManager.d.ts +3 -3
- package/dist/src/room/PCTransportManager.d.ts.map +1 -1
- package/dist/src/room/RTCEngine.d.ts +8 -0
- package/dist/src/room/RTCEngine.d.ts.map +1 -1
- package/dist/src/room/Room.d.ts +1 -1
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/utils/dataPacketBuffer.d.ts +15 -0
- package/dist/src/utils/dataPacketBuffer.d.ts.map +1 -0
- package/dist/src/utils/ttlmap.d.ts +20 -0
- package/dist/src/utils/ttlmap.d.ts.map +1 -0
- package/dist/ts4.2/src/api/SignalClient.d.ts +5 -5
- package/dist/ts4.2/src/e2ee/types.d.ts +1 -0
- package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +2 -1
- package/dist/ts4.2/src/room/PCTransport.d.ts +3 -2
- package/dist/ts4.2/src/room/PCTransportManager.d.ts +3 -3
- package/dist/ts4.2/src/room/RTCEngine.d.ts +8 -0
- package/dist/ts4.2/src/room/Room.d.ts +1 -1
- package/dist/ts4.2/src/utils/dataPacketBuffer.d.ts +15 -0
- package/dist/ts4.2/src/utils/ttlmap.d.ts +20 -0
- package/package.json +8 -8
- package/src/api/SignalClient.ts +12 -10
- package/src/connectionHelper/checks/publishVideo.ts +1 -0
- package/src/e2ee/E2eeManager.ts +3 -0
- package/src/e2ee/types.ts +1 -0
- package/src/e2ee/worker/FrameCryptor.ts +15 -0
- package/src/e2ee/worker/e2ee.worker.ts +2 -0
- package/src/room/PCTransport.ts +30 -4
- package/src/room/PCTransportManager.ts +10 -7
- package/src/room/RTCEngine.ts +78 -9
- package/src/room/Room.ts +11 -11
- package/src/room/track/LocalVideoTrack.ts +14 -15
- package/src/utils/dataPacketBuffer.ts +52 -0
- package/src/utils/ttlmap.ts +96 -0
@@ -7,12 +7,11 @@ import {
|
|
7
7
|
} from '@livekit/protocol';
|
8
8
|
import type { SignalClient } from '../../api/SignalClient';
|
9
9
|
import type { StructuredLogger } from '../../logger';
|
10
|
-
import { getBrowser } from '../../utils/browserParser';
|
11
10
|
import { ScalabilityMode } from '../participant/publishUtils';
|
12
11
|
import type { VideoSenderStats } from '../stats';
|
13
12
|
import { computeBitrate, monitorFrequency } from '../stats';
|
14
13
|
import type { LoggerOptions } from '../types';
|
15
|
-
import {
|
14
|
+
import { isFireFox, isMobile, isSVCCodec, isWeb } from '../utils';
|
16
15
|
import LocalTrack from './LocalTrack';
|
17
16
|
import { Track, VideoQuality } from './Track';
|
18
17
|
import type { VideoCaptureOptions, VideoCodec } from './options';
|
@@ -459,15 +458,18 @@ async function setPublishingLayersForSender(
|
|
459
458
|
}
|
460
459
|
|
461
460
|
let hasChanged = false;
|
462
|
-
|
463
|
-
|
464
|
-
|
461
|
+
|
462
|
+
/* disable closable spatial layer as it has video blur / frozen issue with current server / client
|
463
|
+
1. chrome 113: when switching to up layer with scalability Mode change, it will generate a
|
464
|
+
low resolution frame and recover very quickly, but noticable
|
465
|
+
2. livekit sfu: additional pli request cause video frozen for a few frames, also noticable */
|
466
|
+
const closableSpatial = false;
|
465
467
|
/* @ts-ignore */
|
466
468
|
if (closableSpatial && encodings[0].scalabilityMode) {
|
467
469
|
// svc dynacast encodings
|
468
470
|
const encoding = encodings[0];
|
469
471
|
/* @ts-ignore */
|
470
|
-
const mode = new ScalabilityMode(encoding.scalabilityMode);
|
472
|
+
// const mode = new ScalabilityMode(encoding.scalabilityMode);
|
471
473
|
let maxQuality = ProtoVideoQuality.OFF;
|
472
474
|
qualities.forEach((q) => {
|
473
475
|
if (q.enabled && (maxQuality === ProtoVideoQuality.OFF || q.quality > maxQuality)) {
|
@@ -480,25 +482,22 @@ async function setPublishingLayersForSender(
|
|
480
482
|
encoding.active = false;
|
481
483
|
hasChanged = true;
|
482
484
|
}
|
483
|
-
} else if (!encoding.active || mode.spatial !== maxQuality + 1) {
|
485
|
+
} else if (!encoding.active /* || mode.spatial !== maxQuality + 1*/) {
|
484
486
|
hasChanged = true;
|
485
487
|
encoding.active = true;
|
486
|
-
/*
|
487
|
-
|
488
|
+
/*
|
489
|
+
@ts-ignore
|
490
|
+
const originalMode = new ScalabilityMode(senderEncodings[0].scalabilityMode)
|
488
491
|
mode.spatial = maxQuality + 1;
|
489
492
|
mode.suffix = originalMode.suffix;
|
490
493
|
if (mode.spatial === 1) {
|
491
494
|
// no suffix for L1Tx
|
492
495
|
mode.suffix = undefined;
|
493
496
|
}
|
494
|
-
|
497
|
+
@ts-ignore
|
495
498
|
encoding.scalabilityMode = mode.toString();
|
496
499
|
encoding.scaleResolutionDownBy = 2 ** (2 - maxQuality);
|
497
|
-
|
498
|
-
encoding.maxBitrate =
|
499
|
-
senderEncodings[0].maxBitrate /
|
500
|
-
(encoding.scaleResolutionDownBy * encoding.scaleResolutionDownBy);
|
501
|
-
}
|
500
|
+
*/
|
502
501
|
}
|
503
502
|
} else {
|
504
503
|
if (isSVC) {
|
@@ -0,0 +1,52 @@
|
|
1
|
+
export interface DataPacketItem {
|
2
|
+
data: Uint8Array;
|
3
|
+
sequence: number;
|
4
|
+
}
|
5
|
+
|
6
|
+
export class DataPacketBuffer {
|
7
|
+
private buffer: DataPacketItem[] = [];
|
8
|
+
|
9
|
+
private _totalSize = 0;
|
10
|
+
|
11
|
+
push(item: DataPacketItem) {
|
12
|
+
this.buffer.push(item);
|
13
|
+
this._totalSize += item.data.byteLength;
|
14
|
+
}
|
15
|
+
|
16
|
+
pop(): DataPacketItem | undefined {
|
17
|
+
const item = this.buffer.shift();
|
18
|
+
if (item) {
|
19
|
+
this._totalSize -= item.data.byteLength;
|
20
|
+
}
|
21
|
+
return item;
|
22
|
+
}
|
23
|
+
|
24
|
+
getAll(): DataPacketItem[] {
|
25
|
+
return this.buffer.slice();
|
26
|
+
}
|
27
|
+
|
28
|
+
popToSequence(sequence: number) {
|
29
|
+
while (this.buffer.length > 0) {
|
30
|
+
const first = this.buffer[0];
|
31
|
+
if (first.sequence <= sequence) {
|
32
|
+
this.pop();
|
33
|
+
} else {
|
34
|
+
break;
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
alignBufferedAmount(bufferedAmount: number) {
|
40
|
+
while (this.buffer.length > 0) {
|
41
|
+
const first = this.buffer[0];
|
42
|
+
if (this._totalSize - first.data.byteLength <= bufferedAmount) {
|
43
|
+
break;
|
44
|
+
}
|
45
|
+
this.pop();
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
get length(): number {
|
50
|
+
return this.buffer.length;
|
51
|
+
}
|
52
|
+
}
|
@@ -0,0 +1,96 @@
|
|
1
|
+
export class TTLMap<K, V> {
|
2
|
+
private _map = new Map<K, { value: V; expiresAt: number }>();
|
3
|
+
|
4
|
+
private ttl: number;
|
5
|
+
|
6
|
+
private _lastCleanup = 0;
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @param ttl ttl of the key (ms)
|
10
|
+
*/
|
11
|
+
constructor(ttl: number) {
|
12
|
+
this.ttl = ttl;
|
13
|
+
}
|
14
|
+
|
15
|
+
set(key: K, value: V) {
|
16
|
+
const now = Date.now();
|
17
|
+
if (now - this._lastCleanup > this.ttl / 2) {
|
18
|
+
this.cleanup();
|
19
|
+
}
|
20
|
+
const expiresAt = now + this.ttl;
|
21
|
+
this._map.set(key, { value, expiresAt });
|
22
|
+
return this;
|
23
|
+
}
|
24
|
+
|
25
|
+
get(key: K): V | undefined {
|
26
|
+
const entry = this._map.get(key);
|
27
|
+
if (!entry) return undefined;
|
28
|
+
if (entry.expiresAt < Date.now()) {
|
29
|
+
this._map.delete(key);
|
30
|
+
return undefined;
|
31
|
+
}
|
32
|
+
return entry.value;
|
33
|
+
}
|
34
|
+
|
35
|
+
has(key: K): boolean {
|
36
|
+
const entry = this._map.get(key);
|
37
|
+
if (!entry) return false;
|
38
|
+
if (entry.expiresAt < Date.now()) {
|
39
|
+
this._map.delete(key);
|
40
|
+
return false;
|
41
|
+
}
|
42
|
+
return true;
|
43
|
+
}
|
44
|
+
|
45
|
+
delete(key: K): boolean {
|
46
|
+
return this._map.delete(key);
|
47
|
+
}
|
48
|
+
|
49
|
+
clear() {
|
50
|
+
this._map.clear();
|
51
|
+
}
|
52
|
+
|
53
|
+
cleanup() {
|
54
|
+
const now = Date.now();
|
55
|
+
for (const [key, entry] of this._map.entries()) {
|
56
|
+
if (entry.expiresAt < now) {
|
57
|
+
this._map.delete(key);
|
58
|
+
}
|
59
|
+
}
|
60
|
+
this._lastCleanup = now;
|
61
|
+
}
|
62
|
+
|
63
|
+
get size() {
|
64
|
+
this.cleanup();
|
65
|
+
return this._map.size;
|
66
|
+
}
|
67
|
+
|
68
|
+
forEach(callback: (value: V, key: K, map: Map<K, V>) => void) {
|
69
|
+
this.cleanup();
|
70
|
+
for (const [key, entry] of this._map.entries()) {
|
71
|
+
if (entry.expiresAt >= Date.now()) {
|
72
|
+
callback(entry.value, key, this.asValueMap());
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
map<U>(callback: (value: V, key: K, map: Map<K, V>) => U): U[] {
|
78
|
+
this.cleanup();
|
79
|
+
const result: U[] = [];
|
80
|
+
const valueMap = this.asValueMap();
|
81
|
+
for (const [key, value] of valueMap.entries()) {
|
82
|
+
result.push(callback(value, key, valueMap));
|
83
|
+
}
|
84
|
+
return result;
|
85
|
+
}
|
86
|
+
|
87
|
+
private asValueMap(): Map<K, V> {
|
88
|
+
const result = new Map<K, V>();
|
89
|
+
for (const [key, entry] of this._map.entries()) {
|
90
|
+
if (entry.expiresAt >= Date.now()) {
|
91
|
+
result.set(key, entry.value);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
return result;
|
95
|
+
}
|
96
|
+
}
|