livekit-client 2.22.4 → 2.23.0
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 +69 -7
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +1133 -289
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.fm.worker.js.map +1 -1
- package/dist/livekit-client.fm.worker.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.map +1 -1
- package/dist/src/api/WebSocketStream.d.ts +1 -0
- package/dist/src/api/WebSocketStream.d.ts.map +1 -1
- package/dist/src/api/utils.d.ts +1 -1
- package/dist/src/api/utils.d.ts.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts +12 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/room/DefaultReconnectPolicy.d.ts.map +1 -1
- package/dist/src/room/PCTransport.d.ts +26 -4
- package/dist/src/room/PCTransport.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 +53 -0
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-channel/DataChannelManager.d.ts +9 -8
- package/dist/src/room/data-channel/DataChannelManager.d.ts.map +1 -1
- package/dist/src/room/data-channel/FlowControlledDataChannel.d.ts +25 -12
- package/dist/src/room/data-channel/FlowControlledDataChannel.d.ts.map +1 -1
- package/dist/src/room/data-channel/LossyDataChannel.d.ts.map +1 -1
- package/dist/src/room/data-channel/ReliableDataChannel.d.ts.map +1 -1
- package/dist/src/room/data-stream/incoming/IncomingDataStreamManager.d.ts.map +1 -1
- package/dist/src/room/participant/LocalParticipant.d.ts +4 -0
- package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
- package/dist/src/room/participant/Participant.d.ts +1 -1
- package/dist/src/room/participant/Participant.d.ts.map +1 -1
- package/dist/src/room/rpc/utils.d.ts.map +1 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts +24 -1
- package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalTrack.d.ts +18 -0
- package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
- package/dist/src/room/track/LocalVideoTrack.d.ts +7 -0
- package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/RemoteAudioTrack.d.ts +6 -0
- package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
- package/dist/src/room/track/processor/types.d.ts +11 -0
- package/dist/src/room/track/processor/types.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +28 -1
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/ts4.2/api/WebSocketStream.d.ts +1 -0
- package/dist/ts4.2/api/utils.d.ts +1 -1
- package/dist/ts4.2/e2ee/worker/naluUtils.d.ts +12 -1
- package/dist/ts4.2/index.d.ts +2 -2
- package/dist/ts4.2/room/PCTransport.d.ts +26 -4
- package/dist/ts4.2/room/RTCEngine.d.ts +8 -0
- package/dist/ts4.2/room/Room.d.ts +53 -0
- package/dist/ts4.2/room/data-channel/DataChannelManager.d.ts +9 -8
- package/dist/ts4.2/room/data-channel/FlowControlledDataChannel.d.ts +25 -12
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +4 -0
- package/dist/ts4.2/room/participant/Participant.d.ts +1 -1
- package/dist/ts4.2/room/track/LocalAudioTrack.d.ts +24 -1
- package/dist/ts4.2/room/track/LocalTrack.d.ts +18 -0
- package/dist/ts4.2/room/track/LocalVideoTrack.d.ts +7 -0
- package/dist/ts4.2/room/track/RemoteAudioTrack.d.ts +6 -0
- package/dist/ts4.2/room/track/processor/types.d.ts +11 -0
- package/dist/ts4.2/room/utils.d.ts +28 -1
- package/package.json +1 -1
- package/src/api/SignalClient.test.ts +234 -0
- package/src/api/SignalClient.ts +58 -23
- package/src/api/WebSocketStream.test.ts +11 -0
- package/src/api/WebSocketStream.ts +22 -1
- package/src/api/utils.ts +1 -1
- package/src/e2ee/E2eeManager.test.ts +43 -0
- package/src/e2ee/E2eeManager.ts +6 -2
- package/src/e2ee/worker/FrameCryptor.test.ts +212 -90
- package/src/e2ee/worker/FrameCryptor.ts +21 -4
- package/src/e2ee/worker/naluUtils.test.ts +123 -0
- package/src/e2ee/worker/naluUtils.ts +57 -2
- package/src/index.ts +2 -0
- package/src/room/DefaultReconnectPolicy.test.ts +58 -0
- package/src/room/DefaultReconnectPolicy.ts +14 -2
- package/src/room/PCTransport.test.ts +144 -2
- package/src/room/PCTransport.ts +151 -9
- package/src/room/RTCEngine.test.ts +234 -2
- package/src/room/RTCEngine.ts +102 -7
- package/src/room/Room.test.ts +116 -0
- package/src/room/Room.ts +286 -74
- package/src/room/data-channel/DataChannelManager.test.ts +24 -7
- package/src/room/data-channel/DataChannelManager.ts +43 -38
- package/src/room/data-channel/FlowControlledDataChannel.test.ts +60 -18
- package/src/room/data-channel/FlowControlledDataChannel.ts +40 -22
- package/src/room/data-channel/LossyDataChannel.test.ts +38 -0
- package/src/room/data-channel/LossyDataChannel.ts +10 -1
- package/src/room/data-channel/ReliableDataChannel.test.ts +72 -0
- package/src/room/data-channel/ReliableDataChannel.ts +16 -5
- package/src/room/data-stream/incoming/IncomingDataStreamManager.test.ts +31 -0
- package/src/room/data-stream/incoming/IncomingDataStreamManager.ts +11 -0
- package/src/room/participant/LocalParticipant.test.ts +136 -1
- package/src/room/participant/LocalParticipant.ts +66 -17
- package/src/room/participant/Participant.ts +6 -3
- package/src/room/participant/restartOnDefaultAudioDevice.test.ts +177 -0
- package/src/room/rpc/utils.test.ts +32 -0
- package/src/room/rpc/utils.ts +7 -0
- package/src/room/track/LocalAudioTrack.ts +101 -10
- package/src/room/track/LocalTrack.ts +70 -13
- package/src/room/track/LocalVideoTrack.ts +7 -0
- package/src/room/track/RemoteAudioTrack.ts +56 -11
- package/src/room/track/processor/types.ts +11 -0
- package/src/room/track/utils.test.ts +5 -0
- package/src/room/track/utils.ts +29 -5
- package/src/room/utils.test.ts +126 -0
- package/src/room/utils.ts +84 -21
|
@@ -6586,8 +6586,14 @@ function isH265SliceNALU(naluType) {
|
|
|
6586
6586
|
* @returns Detected codec type
|
|
6587
6587
|
*/
|
|
6588
6588
|
function detectCodecFromNALUs(data, naluIndices) {
|
|
6589
|
+
// h264 runs to completion first. Several non-slice h264 NALUs read as h265 slice types
|
|
6590
|
+
// (AUD 0x09 -> STSA_N, SEI 0x06 -> TSA_R), so interleaving the two checks lets one of
|
|
6591
|
+
// those outrank the real h264 slice that follows it. The reverse cannot happen: h265
|
|
6592
|
+
// header bytes are even at nuh_layer_id 0, so they never mask to an h264 slice type.
|
|
6589
6593
|
for (const naluIndex of naluIndices) {
|
|
6590
6594
|
if (isH264SliceNALU(parseH264NALUType(data[naluIndex]))) return 'h264';
|
|
6595
|
+
}
|
|
6596
|
+
for (const naluIndex of naluIndices) {
|
|
6591
6597
|
if (isH265SliceNALU(parseH265NALUType(data[naluIndex]))) return 'h265';
|
|
6592
6598
|
}
|
|
6593
6599
|
return 'unknown';
|
|
@@ -6665,12 +6671,21 @@ function findNALUIndices(stream) {
|
|
|
6665
6671
|
/**
|
|
6666
6672
|
* Process NALU data for frame encryption, detecting codec and finding unencrypted bytes
|
|
6667
6673
|
* @param data Frame data
|
|
6668
|
-
* @param knownCodec
|
|
6674
|
+
* @param knownCodec Codec from other sources, used only when the bytes are inconclusive (optional)
|
|
6669
6675
|
* @returns NALU processing result
|
|
6670
6676
|
*/
|
|
6671
6677
|
function processNALUsForEncryption(data, knownCodec) {
|
|
6672
6678
|
const naluIndices = findNALUIndices(data);
|
|
6673
|
-
|
|
6679
|
+
// The bytes outrank knownCodec, which can be the codec the client asked for rather than the
|
|
6680
|
+
// one that was negotiated. Parsing the wrong one mis-slices without raising anything: the
|
|
6681
|
+
// offset lands before the real slice header, so the header itself gets encrypted.
|
|
6682
|
+
// That holds in one direction only. An h264 access unit carrying no slice NALU but carrying
|
|
6683
|
+
// an AUD or SEI that reads as an h265 slice now slices there instead of throwing. No real
|
|
6684
|
+
// WebRTC access unit can reach it, because every one of them carries a type 1 or 5 slice.
|
|
6685
|
+
let detectedCodec = detectCodecFromNALUs(data, naluIndices);
|
|
6686
|
+
if (detectedCodec === 'unknown') {
|
|
6687
|
+
detectedCodec = knownCodec !== null && knownCodec !== void 0 ? knownCodec : 'unknown';
|
|
6688
|
+
}
|
|
6674
6689
|
if (detectedCodec === 'unknown') {
|
|
6675
6690
|
return {
|
|
6676
6691
|
unencryptedBytes: 0,
|
|
@@ -6688,6 +6703,44 @@ function processNALUsForEncryption(data, knownCodec) {
|
|
|
6688
6703
|
requiresNALUProcessing: true
|
|
6689
6704
|
};
|
|
6690
6705
|
}
|
|
6706
|
+
/**
|
|
6707
|
+
* Rewrite every 3-byte Annex B start code (00 00 01) in `data` to the 4-byte form (00 00 00 01).
|
|
6708
|
+
*
|
|
6709
|
+
* WebRTC's H.264/H.265 depacketizer always reconstructs NALUs with 4-byte start codes, regardless
|
|
6710
|
+
* of what the encoder emitted. Some encoders (e.g. Intel Quick Sync) emit 3-byte start codes, so
|
|
6711
|
+
* the unencrypted header a receiver sees would differ from what the sender authenticated as
|
|
6712
|
+
* AES-GCM additionalData. Normalizing on the sender makes both sides agree.
|
|
6713
|
+
*
|
|
6714
|
+
* Returns `data` unchanged (same instance) when it contains no 3-byte start codes.
|
|
6715
|
+
*/
|
|
6716
|
+
function normalizeAnnexBStartCodes(data) {
|
|
6717
|
+
const shortStartCodes = [];
|
|
6718
|
+
for (let i = 0; i + 2 < data.length;) {
|
|
6719
|
+
if (data[i + 2] === 0) {
|
|
6720
|
+
i += 1;
|
|
6721
|
+
continue;
|
|
6722
|
+
}
|
|
6723
|
+
if (data[i + 2] === 1 && data[i] === 0 && data[i + 1] === 0 && (i === 0 || data[i - 1] !== 0)) {
|
|
6724
|
+
shortStartCodes.push(i);
|
|
6725
|
+
}
|
|
6726
|
+
// data[i + 2] is non-zero, so no start code can begin at i + 1 or i + 2 either.
|
|
6727
|
+
i += 3;
|
|
6728
|
+
}
|
|
6729
|
+
if (shortStartCodes.length === 0) {
|
|
6730
|
+
return data;
|
|
6731
|
+
}
|
|
6732
|
+
// The new array is zero-filled, so the one-byte gap left before each short start code becomes
|
|
6733
|
+
// the inserted leading 00.
|
|
6734
|
+
const result = new Uint8Array(data.length + shortStartCodes.length);
|
|
6735
|
+
let from = 0;
|
|
6736
|
+
for (let inserted = 0; inserted < shortStartCodes.length; inserted++) {
|
|
6737
|
+
const to = shortStartCodes[inserted];
|
|
6738
|
+
result.set(data.subarray(from, to), from + inserted);
|
|
6739
|
+
from = to;
|
|
6740
|
+
}
|
|
6741
|
+
result.set(data.subarray(from), from + shortStartCodes.length);
|
|
6742
|
+
return result;
|
|
6743
|
+
}
|
|
6691
6744
|
|
|
6692
6745
|
/**
|
|
6693
6746
|
* Create a crypto hash using Web Crypto API for secure comparison operations
|
|
@@ -7061,7 +7114,12 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
|
7061
7114
|
const iv = this.makeIV((_a = encodedFrame.getMetadata().synchronizationSource) !== null && _a !== void 0 ? _a : -1, encodedFrame.timestamp);
|
|
7062
7115
|
let frameInfo = this.getUnencryptedBytes(encodedFrame);
|
|
7063
7116
|
// Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.
|
|
7064
|
-
|
|
7117
|
+
let frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);
|
|
7118
|
+
if (frameInfo.requiresNALUProcessing) {
|
|
7119
|
+
// The receiver's depacketizer rebuilds NALUs with 4-byte start codes, so authenticate (and
|
|
7120
|
+
// send) the header in that form or decryption fails for encoders emitting 3-byte ones.
|
|
7121
|
+
frameHeader = normalizeAnnexBStartCodes(frameHeader);
|
|
7122
|
+
}
|
|
7065
7123
|
// Frame trailer contains the R|IV_LENGTH and key index
|
|
7066
7124
|
const frameTrailer = new Uint8Array(2);
|
|
7067
7125
|
frameTrailer[0] = IV_LENGTH;
|
|
@@ -7077,7 +7135,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
|
7077
7135
|
const cipherText = yield crypto.subtle.encrypt({
|
|
7078
7136
|
name: ENCRYPTION_ALGORITHM,
|
|
7079
7137
|
iv,
|
|
7080
|
-
additionalData:
|
|
7138
|
+
additionalData: frameHeader
|
|
7081
7139
|
}, encryptionKey, new Uint8Array(encodedFrame.data, frameInfo.unencryptedBytes));
|
|
7082
7140
|
let newDataWithoutHeader = new Uint8Array(cipherText.byteLength + iv.byteLength + frameTrailer.byteLength);
|
|
7083
7141
|
newDataWithoutHeader.set(new Uint8Array(cipherText)); // add ciphertext.
|
|
@@ -7386,7 +7444,7 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
|
7386
7444
|
};
|
|
7387
7445
|
}
|
|
7388
7446
|
} catch (e) {
|
|
7389
|
-
this.logNALUFallbackOnce(fallbackKey, payloadType, e);
|
|
7447
|
+
this.logNALUFallbackOnce(fallbackKey, frame, payloadType, detectedCodec, e);
|
|
7390
7448
|
}
|
|
7391
7449
|
// Fallback to VP8 handling
|
|
7392
7450
|
return {
|
|
@@ -7398,14 +7456,18 @@ class FrameCryptor extends BaseFrameCryptor {
|
|
|
7398
7456
|
* Logs a NALU processing fallback at most once per (participant, trackId, payloadType) tuple,
|
|
7399
7457
|
* so a persistent bad state doesn't flood the console (Firefox doesn't filter debug).
|
|
7400
7458
|
*/
|
|
7401
|
-
logNALUFallbackOnce(fallbackKey, payloadType, error) {
|
|
7459
|
+
logNALUFallbackOnce(fallbackKey, frame, payloadType, detectedCodec, error) {
|
|
7402
7460
|
if (this.loggedNALUFallbacks.has(fallbackKey)) {
|
|
7403
7461
|
return;
|
|
7404
7462
|
}
|
|
7405
7463
|
this.loggedNALUFallbacks.add(fallbackKey);
|
|
7406
7464
|
workerLogger.warn('NALU processing failed, falling back to VP8 handling', Object.assign({
|
|
7407
7465
|
error,
|
|
7408
|
-
payloadType
|
|
7466
|
+
payloadType,
|
|
7467
|
+
detectedCodec,
|
|
7468
|
+
frameType: frame.type,
|
|
7469
|
+
byteLength: frame.data.byteLength,
|
|
7470
|
+
firstBytes: Array.from(new Uint8Array(frame.data, 0, Math.min(16, frame.data.byteLength))).map(b => b.toString(16).padStart(2, '0')).join(' ')
|
|
7409
7471
|
}, this.logContext));
|
|
7410
7472
|
}
|
|
7411
7473
|
/**
|