livekit-client 2.18.9 → 2.19.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 +5609 -644
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +3553 -2813
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.pt.worker.js +2 -0
- package/dist/livekit-client.pt.worker.js.map +1 -0
- package/dist/livekit-client.pt.worker.mjs +5834 -0
- package/dist/livekit-client.pt.worker.mjs.map +1 -0
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/api/SignalClient.d.ts +2 -1
- package/dist/src/api/SignalClient.d.ts.map +1 -1
- package/dist/src/e2ee/E2eeManager.d.ts +8 -7
- package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
- package/dist/src/e2ee/types.d.ts +35 -8
- package/dist/src/e2ee/types.d.ts.map +1 -1
- package/dist/src/e2ee/utils.d.ts +5 -5
- package/dist/src/e2ee/utils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/DataCryptor.d.ts +5 -5
- package/dist/src/e2ee/worker/DataCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts +21 -4
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts +1 -1
- package/dist/src/e2ee/worker/naluUtils.d.ts.map +1 -1
- package/dist/src/e2ee/worker/sifPayload.d.ts +7 -7
- package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/options.d.ts +7 -0
- package/dist/src/options.d.ts.map +1 -1
- package/dist/src/packetTrailer/PacketTrailerManager.d.ts +49 -0
- package/dist/src/packetTrailer/PacketTrailerManager.d.ts.map +1 -0
- package/dist/src/packetTrailer/packetTrailer.d.ts +32 -0
- package/dist/src/packetTrailer/packetTrailer.d.ts.map +1 -0
- package/dist/src/packetTrailer/types.d.ts +57 -0
- package/dist/src/packetTrailer/types.d.ts.map +1 -0
- package/dist/src/packetTrailer/utils.d.ts +9 -0
- package/dist/src/packetTrailer/utils.d.ts.map +1 -0
- package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
- package/dist/src/packetTrailer/worker/packetTrailer.worker.d.ts.map +1 -0
- 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 +7 -3
- package/dist/src/room/Room.d.ts.map +1 -1
- package/dist/src/room/data-track/RemoteDataTrack.d.ts +5 -1
- package/dist/src/room/data-track/RemoteDataTrack.d.ts.map +1 -1
- package/dist/src/room/data-track/depacketizer.d.ts +12 -4
- package/dist/src/room/data-track/depacketizer.d.ts.map +1 -1
- package/dist/src/room/data-track/frame.d.ts +3 -3
- package/dist/src/room/data-track/frame.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
- package/dist/src/room/data-track/incoming/IncomingDataTrackManager.d.ts.map +1 -1
- package/dist/src/room/data-track/incoming/pipeline.d.ts +4 -1
- package/dist/src/room/data-track/incoming/pipeline.d.ts.map +1 -1
- package/dist/src/room/data-track/outgoing/types.d.ts +2 -2
- package/dist/src/room/data-track/outgoing/types.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/src/room/data-track/packet/extensions.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/index.d.ts +5 -5
- package/dist/src/room/data-track/packet/index.d.ts.map +1 -1
- package/dist/src/room/data-track/packet/serializable.d.ts +1 -1
- package/dist/src/room/data-track/packet/serializable.d.ts.map +1 -1
- package/dist/src/room/data-track/types.d.ts +7 -0
- package/dist/src/room/data-track/types.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +2 -2
- package/dist/src/room/participant/LocalParticipant.d.ts +8 -14
- 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/participant/RemoteParticipant.d.ts +5 -1
- package/dist/src/room/participant/RemoteParticipant.d.ts.map +1 -1
- package/dist/src/room/rpc/client/RpcClientManager.d.ts +39 -0
- package/dist/src/room/rpc/client/RpcClientManager.d.ts.map +1 -0
- package/dist/src/room/rpc/client/events.d.ts +8 -0
- package/dist/src/room/rpc/client/events.d.ts.map +1 -0
- package/dist/src/room/rpc/index.d.ts +6 -0
- package/dist/src/room/rpc/index.d.ts.map +1 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/src/room/rpc/server/RpcServerManager.d.ts.map +1 -0
- package/dist/src/room/rpc/server/events.d.ts +8 -0
- package/dist/src/room/rpc/server/events.d.ts.map +1 -0
- package/dist/src/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/src/room/rpc/utils.d.ts.map +1 -0
- package/dist/src/room/track/PacketTrailerExtractor.d.ts +19 -0
- package/dist/src/room/track/PacketTrailerExtractor.d.ts.map +1 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts +16 -0
- package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
- package/dist/src/room/track/Track.d.ts +1 -1
- package/dist/src/room/track/Track.d.ts.map +1 -1
- package/dist/src/room/track/create.d.ts.map +1 -1
- package/dist/src/room/track/options.d.ts +10 -0
- package/dist/src/room/track/options.d.ts.map +1 -1
- package/dist/src/room/track/utils.d.ts.map +1 -1
- package/dist/src/room/utils.d.ts +4 -3
- package/dist/src/room/utils.d.ts.map +1 -1
- package/dist/src/test/MockMediaStreamTrack.d.ts.map +1 -1
- package/dist/src/utils/dataPacketBuffer.d.ts +1 -1
- package/dist/src/utils/dataPacketBuffer.d.ts.map +1 -1
- package/dist/src/version.d.ts +9 -1
- package/dist/src/version.d.ts.map +1 -1
- package/dist/ts4.2/api/SignalClient.d.ts +2 -1
- package/dist/ts4.2/e2ee/E2eeManager.d.ts +8 -7
- package/dist/ts4.2/e2ee/types.d.ts +35 -8
- package/dist/ts4.2/e2ee/utils.d.ts +5 -5
- package/dist/ts4.2/e2ee/worker/DataCryptor.d.ts +5 -5
- package/dist/ts4.2/e2ee/worker/FrameCryptor.d.ts +21 -4
- package/dist/ts4.2/e2ee/worker/naluUtils.d.ts +1 -1
- package/dist/ts4.2/e2ee/worker/sifPayload.d.ts +7 -7
- package/dist/ts4.2/index.d.ts +5 -1
- package/dist/ts4.2/options.d.ts +7 -0
- package/dist/ts4.2/packetTrailer/PacketTrailerManager.d.ts +49 -0
- package/dist/ts4.2/packetTrailer/packetTrailer.d.ts +32 -0
- package/dist/ts4.2/packetTrailer/types.d.ts +57 -0
- package/dist/ts4.2/packetTrailer/utils.d.ts +9 -0
- package/dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts +2 -0
- package/dist/ts4.2/room/RTCEngine.d.ts +2 -4
- package/dist/ts4.2/room/Room.d.ts +7 -3
- package/dist/ts4.2/room/data-track/RemoteDataTrack.d.ts +5 -1
- package/dist/ts4.2/room/data-track/depacketizer.d.ts +12 -4
- package/dist/ts4.2/room/data-track/frame.d.ts +3 -3
- package/dist/ts4.2/room/data-track/incoming/IncomingDataTrackManager.d.ts +3 -1
- package/dist/ts4.2/room/data-track/incoming/pipeline.d.ts +4 -1
- package/dist/ts4.2/room/data-track/outgoing/types.d.ts +2 -2
- package/dist/ts4.2/room/data-track/packet/extensions.d.ts +4 -4
- package/dist/ts4.2/room/data-track/packet/index.d.ts +5 -5
- package/dist/ts4.2/room/data-track/packet/serializable.d.ts +1 -1
- package/dist/ts4.2/room/data-track/types.d.ts +7 -0
- package/dist/ts4.2/room/events.d.ts +2 -2
- package/dist/ts4.2/room/participant/LocalParticipant.d.ts +8 -14
- package/dist/ts4.2/room/participant/Participant.d.ts +1 -1
- package/dist/ts4.2/room/participant/RemoteParticipant.d.ts +5 -1
- package/dist/ts4.2/room/rpc/client/RpcClientManager.d.ts +43 -0
- package/dist/ts4.2/room/rpc/client/events.d.ts +8 -0
- package/dist/ts4.2/room/rpc/index.d.ts +7 -0
- package/dist/ts4.2/room/rpc/server/RpcServerManager.d.ts +44 -0
- package/dist/ts4.2/room/rpc/server/events.d.ts +8 -0
- package/dist/ts4.2/room/{rpc.d.ts → rpc/utils.d.ts} +34 -4
- package/dist/ts4.2/room/track/PacketTrailerExtractor.d.ts +19 -0
- package/dist/ts4.2/room/track/RemoteVideoTrack.d.ts +16 -0
- package/dist/ts4.2/room/track/Track.d.ts +1 -1
- package/dist/ts4.2/room/track/options.d.ts +10 -0
- package/dist/ts4.2/room/utils.d.ts +4 -3
- package/dist/ts4.2/utils/dataPacketBuffer.d.ts +1 -1
- package/dist/ts4.2/version.d.ts +9 -1
- package/package.json +24 -16
- package/src/api/SignalClient.test.ts +102 -10
- package/src/api/SignalClient.ts +4 -2
- package/src/api/WebSocketStream.test.ts +0 -1
- package/src/e2ee/E2eeManager.ts +82 -30
- package/src/e2ee/types.ts +37 -8
- package/src/e2ee/utils.ts +7 -6
- package/src/e2ee/worker/DataCryptor.ts +6 -6
- package/src/e2ee/worker/FrameCryptor.test.ts +177 -4
- package/src/e2ee/worker/FrameCryptor.ts +94 -14
- package/src/e2ee/worker/ParticipantKeyHandler.test.ts +4 -4
- package/src/e2ee/worker/e2ee.worker.ts +13 -5
- package/src/e2ee/worker/naluUtils.ts +4 -4
- package/src/e2ee/worker/sifPayload.ts +10 -8
- package/src/index.ts +7 -0
- package/src/options.ts +8 -0
- package/src/packetTrailer/PacketTrailerManager.test.ts +172 -0
- package/src/packetTrailer/PacketTrailerManager.ts +250 -0
- package/src/packetTrailer/packetTrailer.test.ts +174 -0
- package/src/packetTrailer/packetTrailer.ts +276 -0
- package/src/packetTrailer/types.ts +75 -0
- package/src/packetTrailer/utils.test.ts +105 -0
- package/src/packetTrailer/utils.ts +50 -0
- package/src/packetTrailer/worker/packetTrailer.worker.ts +155 -0
- package/src/packetTrailer/worker/tsconfig.json +14 -0
- package/src/room/BackOffStrategy.test.ts +1 -1
- package/src/room/RTCEngine.test.ts +219 -0
- package/src/room/RTCEngine.ts +86 -46
- package/src/room/Room.test.ts +62 -1
- package/src/room/Room.ts +111 -86
- package/src/room/data-track/RemoteDataTrack.ts +8 -1
- package/src/room/data-track/depacketizer.test.ts +433 -1
- package/src/room/data-track/depacketizer.ts +79 -61
- package/src/room/data-track/frame.ts +2 -2
- package/src/room/data-track/incoming/IncomingDataTrackManager.test.ts +194 -0
- package/src/room/data-track/incoming/IncomingDataTrackManager.ts +21 -1
- package/src/room/data-track/incoming/pipeline.ts +13 -2
- package/src/room/data-track/outgoing/types.ts +3 -2
- package/src/room/data-track/packet/extensions.ts +2 -2
- package/src/room/data-track/packet/index.ts +6 -6
- package/src/room/data-track/packet/serializable.ts +1 -1
- package/src/room/data-track/types.ts +8 -0
- package/src/room/events.ts +2 -2
- package/src/room/participant/LocalParticipant.test.ts +81 -0
- package/src/room/participant/LocalParticipant.ts +64 -187
- package/src/room/participant/Participant.ts +1 -1
- package/src/room/participant/RemoteParticipant.ts +9 -0
- package/src/room/participant/publishUtils.ts +1 -1
- package/src/room/rpc/client/RpcClientManager.test.ts +430 -0
- package/src/room/rpc/client/RpcClientManager.ts +269 -0
- package/src/room/rpc/client/events.ts +9 -0
- package/src/room/rpc/index.ts +14 -0
- package/src/room/rpc/server/RpcServerManager.test.ts +471 -0
- package/src/room/rpc/server/RpcServerManager.ts +293 -0
- package/src/room/rpc/server/events.ts +9 -0
- package/src/room/{rpc.ts → rpc/utils.ts} +49 -8
- package/src/room/track/PacketTrailerExtractor.ts +43 -0
- package/src/room/track/RemoteVideoTrack.ts +23 -2
- package/src/room/track/Track.ts +1 -1
- package/src/room/track/create.ts +0 -4
- package/src/room/track/options.ts +11 -0
- package/src/room/track/record.ts +1 -1
- package/src/room/track/utils.ts +4 -1
- package/src/room/utils.test.ts +14 -1
- package/src/room/utils.ts +19 -4
- package/src/test/MockMediaStreamTrack.ts +0 -1
- package/src/type-polyfills/non-shared-typed-arrays.d.ts +6 -0
- package/src/utils/dataPacketBuffer.ts +1 -1
- package/src/version.ts +11 -1
- package/dist/src/room/rpc.d.ts.map +0 -1
- package/src/room/rpc.test.ts +0 -301
|
@@ -148,7 +148,7 @@ export type TrackEventCallbacks = {
|
|
|
148
148
|
timestamp: number;
|
|
149
149
|
rtpTimestamp: number;
|
|
150
150
|
}) => void;
|
|
151
|
-
preConnectBufferFlushed: (buffer:
|
|
151
|
+
preConnectBufferFlushed: (buffer: NonSharedUint8Array[]) => void;
|
|
152
152
|
cpuConstrained: () => void;
|
|
153
153
|
};
|
|
154
154
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PacketTrailerPublishOptions } from '../../packetTrailer/types';
|
|
1
2
|
import type { Track } from './Track';
|
|
2
3
|
import type { AudioProcessorOptions, TrackProcessor, VideoProcessorOptions } from './processor/types';
|
|
3
4
|
export interface TrackPublishDefaults {
|
|
@@ -111,6 +112,15 @@ export interface TrackPublishDefaults {
|
|
|
111
112
|
* Defaults to false.
|
|
112
113
|
*/
|
|
113
114
|
preConnectBuffer?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Packet trailer metadata to append to published video frames.
|
|
117
|
+
*
|
|
118
|
+
* Requires either room-level packet trailer worker configuration or E2EE,
|
|
119
|
+
* because encoded frame transforms are used to write the trailer.
|
|
120
|
+
*
|
|
121
|
+
* @experimental
|
|
122
|
+
*/
|
|
123
|
+
packetTrailer?: PacketTrailerPublishOptions;
|
|
114
124
|
}
|
|
115
125
|
/**
|
|
116
126
|
* Options when publishing tracks
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChatMessage as ChatMessageModel, ClientInfo, DisconnectReason, Transcription as TranscriptionModel } from '@livekit/protocol';
|
|
1
|
+
import { ChatMessage as ChatMessageModel, ClientInfo, ClientInfo_Capability, DisconnectReason, Transcription as TranscriptionModel } from '@livekit/protocol';
|
|
2
2
|
import type { Throws } from '@livekit/throws-transformer/throws';
|
|
3
3
|
import TypedPromise from '../utils/TypedPromise';
|
|
4
4
|
import type { BrowserDetails } from '../utils/browserParser';
|
|
@@ -40,6 +40,7 @@ export declare function supportsAudioOutputSelection(): boolean;
|
|
|
40
40
|
export declare function isBrowserSupported(): boolean;
|
|
41
41
|
export declare function isFireFox(): boolean;
|
|
42
42
|
export declare function isChromiumBased(): boolean;
|
|
43
|
+
export declare function isScriptTransformSupportedForWorker(): boolean;
|
|
43
44
|
export declare function isSafari(): boolean;
|
|
44
45
|
export declare function isSafariBased(): boolean;
|
|
45
46
|
export declare function isSafari17Based(): boolean;
|
|
@@ -67,7 +68,7 @@ export interface ObservableMediaElement extends HTMLMediaElement {
|
|
|
67
68
|
handleResize: (entry: ResizeObserverEntry) => void;
|
|
68
69
|
handleVisibilityChanged: (entry: IntersectionObserverEntry) => void;
|
|
69
70
|
}
|
|
70
|
-
export declare function getClientInfo(): ClientInfo;
|
|
71
|
+
export declare function getClientInfo(capabilities?: ClientInfo_Capability[]): ClientInfo;
|
|
71
72
|
export declare function getEmptyVideoStreamTrack(): MediaStreamTrack;
|
|
72
73
|
export declare function createDummyVideoStreamTrack(width?: number, height?: number, enabled?: boolean, paintContent?: boolean): MediaStreamTrack;
|
|
73
74
|
export declare function getEmptyAudioStreamTrack(): MediaStreamTrack;
|
|
@@ -143,7 +144,7 @@ export declare function isLocalPub(pub: TrackPublication | undefined): pub is Lo
|
|
|
143
144
|
export declare function isRemoteVideoTrack(track: Track | undefined): track is RemoteVideoTrack;
|
|
144
145
|
export declare function isLocalParticipant(p: Participant): p is LocalParticipant;
|
|
145
146
|
export declare function isRemoteParticipant(p: Participant): p is RemoteParticipant;
|
|
146
|
-
export declare function splitUtf8(s: string, n: number):
|
|
147
|
+
export declare function splitUtf8(s: string, n: number): NonSharedUint8Array[];
|
|
147
148
|
export declare function extractMaxAgeFromRequestHeaders(headers: Headers): number | undefined;
|
|
148
149
|
export declare function isCompressionStreamSupported(): boolean;
|
|
149
150
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/ts4.2/version.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
export declare const version: string;
|
|
2
|
-
export declare const protocolVersion =
|
|
2
|
+
export declare const protocolVersion = 17;
|
|
3
|
+
/** Initial client protocol. */
|
|
4
|
+
export declare const CLIENT_PROTOCOL_DEFAULT = 0;
|
|
5
|
+
/** Replaces RPC v1 protocol with a v2 data streams based one to support unlimited request /
|
|
6
|
+
* response payload length. */
|
|
7
|
+
export declare const CLIENT_PROTOCOL_DATA_STREAM_RPC = 1;
|
|
8
|
+
/** The client protocol version indicates what level of support that the client has for
|
|
9
|
+
* client <-> client api interactions. */
|
|
10
|
+
export declare const clientProtocol = 1;
|
|
3
11
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "livekit-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.19.0",
|
|
4
4
|
"description": "JavaScript/TypeScript client SDK for LiveKit",
|
|
5
5
|
"main": "./dist/livekit-client.umd.js",
|
|
6
6
|
"unpkg": "./dist/livekit-client.umd.js",
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
"types": "./dist/src/e2ee/worker/e2ee.worker.d.ts",
|
|
16
16
|
"import": "./dist/livekit-client.e2ee.worker.mjs",
|
|
17
17
|
"require": "./dist/livekit-client.e2ee.worker.js"
|
|
18
|
+
},
|
|
19
|
+
"./packet-trailer-worker": {
|
|
20
|
+
"types": "./dist/src/packetTrailer/worker/packetTrailer.worker.d.ts",
|
|
21
|
+
"import": "./dist/livekit-client.pt.worker.mjs",
|
|
22
|
+
"require": "./dist/livekit-client.pt.worker.js"
|
|
18
23
|
}
|
|
19
24
|
},
|
|
20
25
|
"files": [
|
|
@@ -29,6 +34,9 @@
|
|
|
29
34
|
],
|
|
30
35
|
"./dist/src/e2ee/worker/e2ee.worker.d.ts": [
|
|
31
36
|
"./dist/ts4.2/e2ee/worker/e2ee.worker.d.ts"
|
|
37
|
+
],
|
|
38
|
+
"./dist/src/packetTrailer/worker/packetTrailer.worker.d.ts": [
|
|
39
|
+
"./dist/ts4.2/packetTrailer/worker/packetTrailer.worker.d.ts"
|
|
32
40
|
]
|
|
33
41
|
}
|
|
34
42
|
},
|
|
@@ -37,7 +45,7 @@
|
|
|
37
45
|
"license": "Apache-2.0",
|
|
38
46
|
"dependencies": {
|
|
39
47
|
"@livekit/mutex": "1.1.1",
|
|
40
|
-
"@livekit/protocol": "1.45.
|
|
48
|
+
"@livekit/protocol": "1.45.8",
|
|
41
49
|
"events": "^3.3.0",
|
|
42
50
|
"jose": "^6.1.0",
|
|
43
51
|
"loglevel": "^1.9.2",
|
|
@@ -51,28 +59,28 @@
|
|
|
51
59
|
},
|
|
52
60
|
"devDependencies": {
|
|
53
61
|
"@babel/core": "7.29.0",
|
|
54
|
-
"@babel/preset-env": "7.29.
|
|
62
|
+
"@babel/preset-env": "7.29.2",
|
|
55
63
|
"@bufbuild/protoc-gen-es": "^1.10.0",
|
|
56
|
-
"@changesets/cli": "2.
|
|
57
|
-
"@eslint/js": "
|
|
64
|
+
"@changesets/cli": "2.31.0",
|
|
65
|
+
"@eslint/js": "10.0.1",
|
|
58
66
|
"@livekit/changesets-changelog-github": "^0.0.4",
|
|
59
67
|
"@livekit/throws-transformer": "^0.1.3",
|
|
60
68
|
"@rollup/plugin-babel": "7.0.0",
|
|
61
|
-
"@rollup/plugin-commonjs": "
|
|
69
|
+
"@rollup/plugin-commonjs": "29.0.2",
|
|
62
70
|
"@rollup/plugin-json": "6.1.0",
|
|
63
71
|
"@rollup/plugin-node-resolve": "16.0.3",
|
|
64
72
|
"@rollup/plugin-terser": "^0.4.4",
|
|
65
73
|
"@size-limit/file": "^11.2.0",
|
|
66
74
|
"@size-limit/webpack": "^11.2.0",
|
|
67
|
-
"@stylistic/eslint-plugin": "^
|
|
75
|
+
"@stylistic/eslint-plugin": "^5.10.0",
|
|
68
76
|
"@trivago/prettier-plugin-sort-imports": "^5.0.0",
|
|
69
77
|
"@types/events": "^3.0.3",
|
|
70
78
|
"@types/sdp-transform": "2.15.0",
|
|
71
79
|
"@types/ua-parser-js": "0.7.39",
|
|
72
|
-
"@typescript-eslint/eslint-plugin": "
|
|
73
|
-
"@typescript-eslint/parser": "
|
|
80
|
+
"@typescript-eslint/eslint-plugin": "8.59.2",
|
|
81
|
+
"@typescript-eslint/parser": "8.59.2",
|
|
74
82
|
"downlevel-dts": "^0.11.0",
|
|
75
|
-
"eslint": "
|
|
83
|
+
"eslint": "10.2.1",
|
|
76
84
|
"eslint-config-airbnb-extended": "^2.3.2",
|
|
77
85
|
"eslint-config-prettier": "10.1.8",
|
|
78
86
|
"eslint-plugin-compat": "^6.0.2",
|
|
@@ -83,20 +91,20 @@
|
|
|
83
91
|
"happy-dom": "^20.0.0",
|
|
84
92
|
"jsdom": "^26.1.0",
|
|
85
93
|
"prettier": "^3.4.2",
|
|
86
|
-
"rollup": "4.
|
|
94
|
+
"rollup": "4.60.2",
|
|
87
95
|
"rollup-plugin-delete": "^2.1.0",
|
|
88
|
-
"rollup-plugin-typescript2": "0.
|
|
96
|
+
"rollup-plugin-typescript2": "0.37.0",
|
|
89
97
|
"size-limit": "^11.2.0",
|
|
90
98
|
"tsx": "^4.21.0",
|
|
91
|
-
"typedoc": "0.28.
|
|
99
|
+
"typedoc": "0.28.19",
|
|
92
100
|
"typedoc-plugin-no-inherit": "1.6.1",
|
|
93
|
-
"typescript": "5.
|
|
101
|
+
"typescript": "5.9.3",
|
|
94
102
|
"typescript-eslint": "^8.47.0",
|
|
95
|
-
"vite": "7.3.
|
|
103
|
+
"vite": "7.3.2",
|
|
96
104
|
"vitest": "^3.0.0"
|
|
97
105
|
},
|
|
98
106
|
"scripts": {
|
|
99
|
-
"build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && pnpm downlevel-dts",
|
|
107
|
+
"build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && rollup --config rollup.config.pt-worker.js --bundleConfigAsCjs && pnpm downlevel-dts",
|
|
100
108
|
"build:clean": "rm -rf ./dist && pnpm build",
|
|
101
109
|
"build:watch": "rollup --watch --config --bundleConfigAsCjs",
|
|
102
110
|
"build:worker:watch": "rollup --watch --config rollup.config.worker.js --bundleConfigAsCjs",
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
ClientInfo_Capability,
|
|
2
3
|
DisconnectReason,
|
|
4
|
+
JoinRequest,
|
|
3
5
|
JoinResponse,
|
|
4
6
|
LeaveRequest,
|
|
5
7
|
ReconnectResponse,
|
|
6
8
|
SignalRequest,
|
|
7
9
|
SignalResponse,
|
|
10
|
+
WrappedJoinRequest,
|
|
11
|
+
WrappedJoinRequest_Compression,
|
|
8
12
|
} from '@livekit/protocol';
|
|
9
13
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
10
14
|
import { ConnectionError, ConnectionErrorReason } from '../room/errors';
|
|
@@ -60,6 +64,7 @@ interface MockWebSocketStreamOptions {
|
|
|
60
64
|
connection?: WebSocketConnection;
|
|
61
65
|
opened?: Promise<WebSocketConnection>;
|
|
62
66
|
closed?: Promise<WebSocketCloseInfo>;
|
|
67
|
+
onUrl?: (url: string) => void;
|
|
63
68
|
readyState?: number;
|
|
64
69
|
}
|
|
65
70
|
|
|
@@ -69,18 +74,19 @@ function mockWebSocketStream(options: MockWebSocketStreamOptions = {}) {
|
|
|
69
74
|
opened = connection ? Promise.resolve(connection) : new Promise(() => {}),
|
|
70
75
|
closed = new Promise(() => {}),
|
|
71
76
|
readyState = 1,
|
|
77
|
+
onUrl,
|
|
72
78
|
} = options;
|
|
73
79
|
|
|
74
|
-
return vi.mocked(WebSocketStream).mockImplementationOnce(
|
|
75
|
-
()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
);
|
|
80
|
+
return vi.mocked(WebSocketStream).mockImplementationOnce((url) => {
|
|
81
|
+
onUrl?.(url);
|
|
82
|
+
return {
|
|
83
|
+
url: 'wss://test.livekit.io',
|
|
84
|
+
opened,
|
|
85
|
+
closed,
|
|
86
|
+
close: vi.fn(),
|
|
87
|
+
readyState,
|
|
88
|
+
} as any;
|
|
89
|
+
});
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
describe('SignalClient.connect', () => {
|
|
@@ -99,6 +105,47 @@ describe('SignalClient.connect', () => {
|
|
|
99
105
|
signalClient = new SignalClient(false);
|
|
100
106
|
});
|
|
101
107
|
|
|
108
|
+
async function decodeJoinRequestFromUrl(url: string): Promise<JoinRequest> {
|
|
109
|
+
const joinRequestParam = new URL(url).searchParams.get('join_request');
|
|
110
|
+
expect(joinRequestParam).toBeTruthy();
|
|
111
|
+
|
|
112
|
+
const paddedBase64Url = joinRequestParam!.padEnd(
|
|
113
|
+
joinRequestParam!.length + ((4 - (joinRequestParam!.length % 4)) % 4),
|
|
114
|
+
'=',
|
|
115
|
+
);
|
|
116
|
+
const binaryString = atob(paddedBase64Url.replace(/-/g, '+').replace(/_/g, '/'));
|
|
117
|
+
const wrappedBytes = new Uint8Array(binaryString.length);
|
|
118
|
+
for (let i = 0; i < binaryString.length; i += 1) {
|
|
119
|
+
wrappedBytes[i] = binaryString.charCodeAt(i);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const wrappedJoinRequest = WrappedJoinRequest.fromBinary(wrappedBytes);
|
|
123
|
+
if (wrappedJoinRequest.compression === WrappedJoinRequest_Compression.NONE) {
|
|
124
|
+
return JoinRequest.fromBinary(wrappedJoinRequest.joinRequest);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const stream = new DecompressionStream('gzip');
|
|
128
|
+
const writer = stream.writable.getWriter();
|
|
129
|
+
writer.write(wrappedJoinRequest.joinRequest);
|
|
130
|
+
writer.close();
|
|
131
|
+
|
|
132
|
+
const chunks: Uint8Array[] = [];
|
|
133
|
+
const reader = stream.readable.getReader();
|
|
134
|
+
while (true) {
|
|
135
|
+
const { done, value } = await reader.read();
|
|
136
|
+
if (done) break;
|
|
137
|
+
chunks.push(value);
|
|
138
|
+
}
|
|
139
|
+
const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
140
|
+
const bytes = new Uint8Array(totalLength);
|
|
141
|
+
let offset = 0;
|
|
142
|
+
for (const chunk of chunks) {
|
|
143
|
+
bytes.set(chunk, offset);
|
|
144
|
+
offset += chunk.length;
|
|
145
|
+
}
|
|
146
|
+
return JoinRequest.fromBinary(bytes);
|
|
147
|
+
}
|
|
148
|
+
|
|
102
149
|
describe('Happy Path - Initial Join', () => {
|
|
103
150
|
it('should successfully connect and receive join response', async () => {
|
|
104
151
|
const joinResponse = createJoinResponse();
|
|
@@ -113,6 +160,51 @@ describe('SignalClient.connect', () => {
|
|
|
113
160
|
expect(result).toEqual(joinResponse);
|
|
114
161
|
expect(signalClient.currentState).toBe(SignalConnectionState.CONNECTED);
|
|
115
162
|
});
|
|
163
|
+
|
|
164
|
+
it('does not advertise packet trailer capability by default', async () => {
|
|
165
|
+
const joinResponse = createJoinResponse();
|
|
166
|
+
const signalResponse = createSignalResponse('join', joinResponse);
|
|
167
|
+
const mockReadable = createMockReadableStream([signalResponse]);
|
|
168
|
+
const mockConnection = createMockConnection(mockReadable);
|
|
169
|
+
let capturedUrl = '';
|
|
170
|
+
|
|
171
|
+
mockWebSocketStream({
|
|
172
|
+
connection: mockConnection,
|
|
173
|
+
onUrl: (url) => {
|
|
174
|
+
capturedUrl = url;
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
await signalClient.join('wss://test.livekit.io', 'test-token', defaultOptions);
|
|
179
|
+
|
|
180
|
+
const joinRequest = await decodeJoinRequestFromUrl(capturedUrl);
|
|
181
|
+
expect(joinRequest.clientInfo?.capabilities).toEqual([]);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('advertises packet trailer capability when provided', async () => {
|
|
185
|
+
const joinResponse = createJoinResponse();
|
|
186
|
+
const signalResponse = createSignalResponse('join', joinResponse);
|
|
187
|
+
const mockReadable = createMockReadableStream([signalResponse]);
|
|
188
|
+
const mockConnection = createMockConnection(mockReadable);
|
|
189
|
+
let capturedUrl = '';
|
|
190
|
+
|
|
191
|
+
mockWebSocketStream({
|
|
192
|
+
connection: mockConnection,
|
|
193
|
+
onUrl: (url) => {
|
|
194
|
+
capturedUrl = url;
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
await signalClient.join('wss://test.livekit.io', 'test-token', {
|
|
199
|
+
...defaultOptions,
|
|
200
|
+
clientInfoCapabilities: [ClientInfo_Capability.CAP_PACKET_TRAILER],
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const joinRequest = await decodeJoinRequestFromUrl(capturedUrl);
|
|
204
|
+
expect(joinRequest.clientInfo?.capabilities).toEqual([
|
|
205
|
+
ClientInfo_Capability.CAP_PACKET_TRAILER,
|
|
206
|
+
]);
|
|
207
|
+
});
|
|
116
208
|
});
|
|
117
209
|
|
|
118
210
|
describe('Happy Path - Reconnect', () => {
|
package/src/api/SignalClient.ts
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AddTrackRequest,
|
|
4
4
|
AudioTrackFeature,
|
|
5
5
|
ClientInfo,
|
|
6
|
+
ClientInfo_Capability,
|
|
6
7
|
ConnectionQualityUpdate,
|
|
7
8
|
ConnectionSettings,
|
|
8
9
|
DataTrackSubscriberHandles,
|
|
@@ -83,6 +84,7 @@ interface ConnectOpts extends SignalOptions {
|
|
|
83
84
|
export interface SignalOptions {
|
|
84
85
|
autoSubscribe: boolean;
|
|
85
86
|
adaptiveStream?: boolean;
|
|
87
|
+
clientInfoCapabilities?: ClientInfo_Capability[];
|
|
86
88
|
maxRetries: number;
|
|
87
89
|
e2eeEnabled: boolean;
|
|
88
90
|
websocketTimeout: number;
|
|
@@ -320,7 +322,7 @@ export class SignalClient {
|
|
|
320
322
|
this.connectOptions = opts;
|
|
321
323
|
this.useV0SignalPath = useV0Path;
|
|
322
324
|
|
|
323
|
-
const clientInfo = getClientInfo();
|
|
325
|
+
const clientInfo = getClientInfo(opts.clientInfoCapabilities);
|
|
324
326
|
const params = useV0Path
|
|
325
327
|
? createConnectionParams(token, clientInfo, opts)
|
|
326
328
|
: await createJoinRequestConnectionParams(token, clientInfo, opts, publisherOffer);
|
|
@@ -771,7 +773,7 @@ export class SignalClient {
|
|
|
771
773
|
if (this.useJSON) {
|
|
772
774
|
await this.streamWriter.write(req.toJsonString());
|
|
773
775
|
} else {
|
|
774
|
-
await this.streamWriter.write(req.toBinary());
|
|
776
|
+
await this.streamWriter.write((req.toBinary() as NonSharedUint8Array).buffer);
|
|
775
777
|
}
|
|
776
778
|
} catch (e) {
|
|
777
779
|
this.log.error('error sending signal message', { error: e });
|
package/src/e2ee/E2eeManager.ts
CHANGED
|
@@ -2,16 +2,24 @@ import { Encryption_Type, TrackInfo } from '@livekit/protocol';
|
|
|
2
2
|
import { EventEmitter } from 'events';
|
|
3
3
|
import type TypedEventEmitter from 'typed-emitter';
|
|
4
4
|
import log, { LogLevel, workerLogger } from '../logger';
|
|
5
|
+
import { hasPacketTrailerPublishOptions } from '../packetTrailer/utils';
|
|
5
6
|
import type RTCEngine from '../room/RTCEngine';
|
|
6
7
|
import type Room from '../room/Room';
|
|
7
8
|
import { ConnectionState } from '../room/Room';
|
|
8
9
|
import { DeviceUnsupportedError } from '../room/errors';
|
|
9
10
|
import { EngineEvent, ParticipantEvent, RoomEvent } from '../room/events';
|
|
10
11
|
import type RemoteTrack from '../room/track/RemoteTrack';
|
|
12
|
+
import RemoteVideoTrack from '../room/track/RemoteVideoTrack';
|
|
11
13
|
import type { Track } from '../room/track/Track';
|
|
12
|
-
import type { VideoCodec } from '../room/track/options';
|
|
14
|
+
import type { TrackPublishOptions, VideoCodec } from '../room/track/options';
|
|
13
15
|
import { mimeTypeToVideoCodecString } from '../room/track/utils';
|
|
14
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
Future,
|
|
18
|
+
isLocalTrack,
|
|
19
|
+
isSafariBased,
|
|
20
|
+
isScriptTransformSupportedForWorker,
|
|
21
|
+
isVideoTrack,
|
|
22
|
+
} from '../room/utils';
|
|
15
23
|
import type { BaseKeyProvider } from './KeyProvider';
|
|
16
24
|
import { E2EE_FLAG } from './constants';
|
|
17
25
|
import { type E2EEManagerCallbacks, EncryptionEvent, KeyProviderEvent } from './events';
|
|
@@ -34,7 +42,7 @@ import type {
|
|
|
34
42
|
SifTrailerMessage,
|
|
35
43
|
UpdateCodecMessage,
|
|
36
44
|
} from './types';
|
|
37
|
-
import { isE2EESupported
|
|
45
|
+
import { isE2EESupported } from './utils';
|
|
38
46
|
|
|
39
47
|
export interface BaseE2EEManager {
|
|
40
48
|
setup(room: Room): void;
|
|
@@ -42,11 +50,11 @@ export interface BaseE2EEManager {
|
|
|
42
50
|
isEnabled: boolean;
|
|
43
51
|
isDataChannelEncryptionEnabled: boolean;
|
|
44
52
|
setParticipantCryptorEnabled(enabled: boolean, participantIdentity: string): void;
|
|
45
|
-
setSifTrailer(trailer:
|
|
46
|
-
encryptData(data:
|
|
53
|
+
setSifTrailer(trailer: NonSharedUint8Array): void;
|
|
54
|
+
encryptData(data: NonSharedUint8Array): Promise<EncryptDataResponseMessage['data']>;
|
|
47
55
|
handleEncryptedData(
|
|
48
|
-
payload:
|
|
49
|
-
iv:
|
|
56
|
+
payload: NonSharedUint8Array,
|
|
57
|
+
iv: NonSharedUint8Array,
|
|
50
58
|
participantIdentity: string,
|
|
51
59
|
keyIndex: number,
|
|
52
60
|
): Promise<DecryptDataResponseMessage['data']>;
|
|
@@ -133,7 +141,7 @@ export class E2EEManager
|
|
|
133
141
|
/**
|
|
134
142
|
* @internal
|
|
135
143
|
*/
|
|
136
|
-
setSifTrailer(trailer:
|
|
144
|
+
setSifTrailer(trailer: NonSharedUint8Array) {
|
|
137
145
|
if (!trailer || trailer.length === 0) {
|
|
138
146
|
log.warn("ignoring server sent trailer as it's empty");
|
|
139
147
|
} else {
|
|
@@ -221,6 +229,9 @@ export class E2EEManager
|
|
|
221
229
|
encryptFuture.resolve(data as EncryptDataResponseMessage['data']);
|
|
222
230
|
}
|
|
223
231
|
break;
|
|
232
|
+
case 'packetTrailerMetadata':
|
|
233
|
+
this.handlePacketTrailerMetadata(data.trackId, data.rtpTimestamp, data.ssrc, data.metadata);
|
|
234
|
+
break;
|
|
224
235
|
default:
|
|
225
236
|
break;
|
|
226
237
|
}
|
|
@@ -231,6 +242,33 @@ export class E2EEManager
|
|
|
231
242
|
this.emit(EncryptionEvent.EncryptionError, ev.error, undefined);
|
|
232
243
|
};
|
|
233
244
|
|
|
245
|
+
private handlePacketTrailerMetadata(
|
|
246
|
+
trackId: string,
|
|
247
|
+
rtpTimestamp: number,
|
|
248
|
+
ssrc: number,
|
|
249
|
+
metadata: { userTimestamp: bigint; frameId: number },
|
|
250
|
+
) {
|
|
251
|
+
if (!this.room) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
for (const participant of [
|
|
255
|
+
this.room.localParticipant,
|
|
256
|
+
...this.room.remoteParticipants.values(),
|
|
257
|
+
]) {
|
|
258
|
+
for (const pub of participant.trackPublications.values()) {
|
|
259
|
+
if (
|
|
260
|
+
pub.track &&
|
|
261
|
+
pub.track.mediaStreamID === trackId &&
|
|
262
|
+
pub.track instanceof RemoteVideoTrack &&
|
|
263
|
+
pub.track.packetTrailerExtractor
|
|
264
|
+
) {
|
|
265
|
+
pub.track.packetTrailerExtractor.storeMetadata(rtpTimestamp, ssrc, metadata);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
234
272
|
public setupEngine(engine: RTCEngine) {
|
|
235
273
|
engine.on(EngineEvent.RTPVideoMapUpdate, (rtpMap) => {
|
|
236
274
|
this.postRTPMap(rtpMap);
|
|
@@ -299,6 +337,7 @@ export class E2EEManager
|
|
|
299
337
|
trackId: publication.track!.mediaStreamID,
|
|
300
338
|
codec: mimeTypeToVideoCodecString(publication.trackInfo!.codecs[0].mimeType),
|
|
301
339
|
participantIdentity: this.room!.localParticipant.identity,
|
|
340
|
+
hasPacketTrailer: false,
|
|
302
341
|
},
|
|
303
342
|
};
|
|
304
343
|
|
|
@@ -314,7 +353,7 @@ export class E2EEManager
|
|
|
314
353
|
);
|
|
315
354
|
}
|
|
316
355
|
|
|
317
|
-
async encryptData(data:
|
|
356
|
+
async encryptData(data: NonSharedUint8Array): Promise<EncryptDataResponseMessage['data']> {
|
|
318
357
|
if (!this.worker) {
|
|
319
358
|
throw Error('could not encrypt data, worker is missing');
|
|
320
359
|
}
|
|
@@ -337,8 +376,8 @@ export class E2EEManager
|
|
|
337
376
|
}
|
|
338
377
|
|
|
339
378
|
handleEncryptedData(
|
|
340
|
-
payload:
|
|
341
|
-
iv:
|
|
379
|
+
payload: NonSharedUint8Array,
|
|
380
|
+
iv: NonSharedUint8Array,
|
|
342
381
|
participantIdentity: string,
|
|
343
382
|
keyIndex: number,
|
|
344
383
|
) {
|
|
@@ -428,7 +467,7 @@ export class E2EEManager
|
|
|
428
467
|
this.worker.postMessage(msg);
|
|
429
468
|
}
|
|
430
469
|
|
|
431
|
-
private postSifTrailer(trailer:
|
|
470
|
+
private postSifTrailer(trailer: NonSharedUint8Array) {
|
|
432
471
|
if (!this.worker) {
|
|
433
472
|
throw Error('could not post SIF trailer, worker is missing');
|
|
434
473
|
}
|
|
@@ -448,11 +487,16 @@ export class E2EEManager
|
|
|
448
487
|
if (!trackInfo?.mimeType || trackInfo.mimeType === '') {
|
|
449
488
|
throw new TypeError('MimeType missing from trackInfo, cannot set up E2EE cryptor');
|
|
450
489
|
}
|
|
490
|
+
const hasPacketTrailer =
|
|
491
|
+
track.kind === 'video' &&
|
|
492
|
+
!!trackInfo.packetTrailerFeatures &&
|
|
493
|
+
trackInfo.packetTrailerFeatures.length > 0;
|
|
451
494
|
this.handleReceiver(
|
|
452
495
|
track.receiver,
|
|
453
496
|
track.mediaStreamID,
|
|
454
497
|
remoteId,
|
|
455
498
|
track.kind === 'video' ? mimeTypeToVideoCodecString(trackInfo.mimeType) : undefined,
|
|
499
|
+
hasPacketTrailer,
|
|
456
500
|
);
|
|
457
501
|
}
|
|
458
502
|
|
|
@@ -461,7 +505,12 @@ export class E2EEManager
|
|
|
461
505
|
if (!sender) log.warn('early return because sender is not ready');
|
|
462
506
|
return;
|
|
463
507
|
}
|
|
464
|
-
this.handleSender(
|
|
508
|
+
this.handleSender(
|
|
509
|
+
sender,
|
|
510
|
+
track.mediaStreamID,
|
|
511
|
+
undefined,
|
|
512
|
+
isVideoTrack(track) ? track.publishOptions?.packetTrailer : undefined,
|
|
513
|
+
);
|
|
465
514
|
}
|
|
466
515
|
|
|
467
516
|
/**
|
|
@@ -473,35 +522,33 @@ export class E2EEManager
|
|
|
473
522
|
receiver: RTCRtpReceiver,
|
|
474
523
|
trackId: string,
|
|
475
524
|
participantIdentity: string,
|
|
476
|
-
codec
|
|
525
|
+
codec: VideoCodec | undefined,
|
|
526
|
+
hasPacketTrailer: boolean,
|
|
477
527
|
) {
|
|
478
528
|
if (!this.worker) {
|
|
479
529
|
return;
|
|
480
530
|
}
|
|
481
531
|
|
|
482
|
-
if (
|
|
483
|
-
isScriptTransformSupported() &&
|
|
484
|
-
// Chrome occasionally throws an `InvalidState` error when using script transforms directly after introducing this API in 141.
|
|
485
|
-
// Disabling it for Chrome based browsers until the API has stabilized
|
|
486
|
-
!isChromiumBased()
|
|
487
|
-
) {
|
|
532
|
+
if (isScriptTransformSupportedForWorker()) {
|
|
488
533
|
const options: ScriptTransformOptions = {
|
|
489
534
|
kind: 'decode',
|
|
490
535
|
participantIdentity,
|
|
491
536
|
trackId,
|
|
492
537
|
codec,
|
|
538
|
+
hasPacketTrailer,
|
|
493
539
|
};
|
|
494
540
|
// @ts-ignore
|
|
495
541
|
receiver.transform = new RTCRtpScriptTransform(this.worker, options);
|
|
496
542
|
} else {
|
|
497
543
|
if (E2EE_FLAG in receiver && codec) {
|
|
498
|
-
//
|
|
544
|
+
// update track-specific state when the transceiver is reused
|
|
499
545
|
const msg: UpdateCodecMessage = {
|
|
500
546
|
kind: 'updateCodec',
|
|
501
547
|
data: {
|
|
502
548
|
trackId,
|
|
503
549
|
codec,
|
|
504
|
-
participantIdentity
|
|
550
|
+
participantIdentity,
|
|
551
|
+
hasPacketTrailer,
|
|
505
552
|
},
|
|
506
553
|
};
|
|
507
554
|
this.worker.postMessage(msg);
|
|
@@ -532,6 +579,7 @@ export class E2EEManager
|
|
|
532
579
|
codec,
|
|
533
580
|
participantIdentity: participantIdentity,
|
|
534
581
|
isReuse: E2EE_FLAG in receiver,
|
|
582
|
+
hasPacketTrailer,
|
|
535
583
|
},
|
|
536
584
|
};
|
|
537
585
|
this.worker.postMessage(msg, [readable, writable]);
|
|
@@ -546,7 +594,12 @@ export class E2EEManager
|
|
|
546
594
|
* a frame encoder.
|
|
547
595
|
*
|
|
548
596
|
*/
|
|
549
|
-
private handleSender(
|
|
597
|
+
private handleSender(
|
|
598
|
+
sender: RTCRtpSender,
|
|
599
|
+
trackId: string,
|
|
600
|
+
codec?: VideoCodec,
|
|
601
|
+
packetTrailer?: TrackPublishOptions['packetTrailer'],
|
|
602
|
+
) {
|
|
550
603
|
if (E2EE_FLAG in sender || !this.worker) {
|
|
551
604
|
return;
|
|
552
605
|
}
|
|
@@ -555,18 +608,15 @@ export class E2EEManager
|
|
|
555
608
|
throw TypeError('local identity needs to be known in order to set up encrypted sender');
|
|
556
609
|
}
|
|
557
610
|
|
|
558
|
-
if (
|
|
559
|
-
isScriptTransformSupported() &&
|
|
560
|
-
// Chrome occasionally throws an `InvalidState` error when using script transforms directly after introducing this API in 141.
|
|
561
|
-
// Disabling it for Chrome based browsers until the API has stabilized
|
|
562
|
-
!isChromiumBased()
|
|
563
|
-
) {
|
|
611
|
+
if (isScriptTransformSupportedForWorker()) {
|
|
564
612
|
log.info('initialize script transform');
|
|
565
|
-
const options = {
|
|
613
|
+
const options: ScriptTransformOptions = {
|
|
566
614
|
kind: 'encode',
|
|
567
615
|
participantIdentity: this.room.localParticipant.identity,
|
|
568
616
|
trackId,
|
|
569
617
|
codec,
|
|
618
|
+
hasPacketTrailer: hasPacketTrailerPublishOptions(packetTrailer),
|
|
619
|
+
packetTrailer,
|
|
570
620
|
};
|
|
571
621
|
// @ts-ignore
|
|
572
622
|
sender.transform = new RTCRtpScriptTransform(this.worker, options);
|
|
@@ -583,6 +633,8 @@ export class E2EEManager
|
|
|
583
633
|
trackId,
|
|
584
634
|
participantIdentity: this.room.localParticipant.identity,
|
|
585
635
|
isReuse: false,
|
|
636
|
+
hasPacketTrailer: hasPacketTrailerPublishOptions(packetTrailer),
|
|
637
|
+
packetTrailer,
|
|
586
638
|
},
|
|
587
639
|
};
|
|
588
640
|
this.worker.postMessage(msg, [senderStreams.readable, senderStreams.writable]);
|