livekit-client 1.11.3 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. package/README.md +1 -3
  2. package/dist/livekit-client.e2ee.worker.js +2 -0
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -0
  4. package/dist/livekit-client.e2ee.worker.mjs +1525 -0
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -0
  6. package/dist/livekit-client.esm.mjs +1462 -660
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/api/SignalClient.d.ts +4 -1
  11. package/dist/src/api/SignalClient.d.ts.map +1 -1
  12. package/dist/src/connectionHelper/checks/turn.d.ts.map +1 -1
  13. package/dist/src/connectionHelper/checks/websocket.d.ts.map +1 -1
  14. package/dist/src/e2ee/E2eeManager.d.ts +45 -0
  15. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -0
  16. package/dist/src/e2ee/KeyProvider.d.ts +42 -0
  17. package/dist/src/e2ee/KeyProvider.d.ts.map +1 -0
  18. package/dist/src/e2ee/constants.d.ts +14 -0
  19. package/dist/src/e2ee/constants.d.ts.map +1 -0
  20. package/dist/src/e2ee/errors.d.ts +11 -0
  21. package/dist/src/e2ee/errors.d.ts.map +1 -0
  22. package/dist/src/e2ee/index.d.ts +4 -0
  23. package/dist/src/e2ee/index.d.ts.map +1 -0
  24. package/dist/src/e2ee/types.d.ts +129 -0
  25. package/dist/src/e2ee/types.d.ts.map +1 -0
  26. package/dist/src/e2ee/utils.d.ts +24 -0
  27. package/dist/src/e2ee/utils.d.ts.map +1 -0
  28. package/dist/src/e2ee/worker/FrameCryptor.d.ts +175 -0
  29. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -0
  30. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts +46 -0
  31. package/dist/src/e2ee/worker/ParticipantKeyHandler.d.ts.map +1 -0
  32. package/dist/src/e2ee/worker/e2ee.worker.d.ts +2 -0
  33. package/dist/src/e2ee/worker/e2ee.worker.d.ts.map +1 -0
  34. package/dist/src/index.d.ts +2 -0
  35. package/dist/src/index.d.ts.map +1 -1
  36. package/dist/src/logger.d.ts +4 -1
  37. package/dist/src/logger.d.ts.map +1 -1
  38. package/dist/src/options.d.ts +5 -0
  39. package/dist/src/options.d.ts.map +1 -1
  40. package/dist/src/proto/livekit_models.d.ts +2 -2
  41. package/dist/src/proto/livekit_models.d.ts.map +1 -1
  42. package/dist/src/room/PCTransport.d.ts +3 -1
  43. package/dist/src/room/PCTransport.d.ts.map +1 -1
  44. package/dist/src/room/RTCEngine.d.ts +17 -3
  45. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  46. package/dist/src/room/Room.d.ts +10 -1
  47. package/dist/src/room/Room.d.ts.map +1 -1
  48. package/dist/src/room/events.d.ts +14 -2
  49. package/dist/src/room/events.d.ts.map +1 -1
  50. package/dist/src/room/participant/LocalParticipant.d.ts +9 -2
  51. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  52. package/dist/src/room/participant/Participant.d.ts +1 -0
  53. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  54. package/dist/src/room/track/LocalAudioTrack.d.ts.map +1 -1
  55. package/dist/src/room/track/LocalTrack.d.ts +3 -2
  56. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  57. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  58. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  59. package/dist/src/room/track/TrackPublication.d.ts +3 -0
  60. package/dist/src/room/track/TrackPublication.d.ts.map +1 -1
  61. package/dist/src/room/track/facingMode.d.ts +41 -0
  62. package/dist/src/room/track/facingMode.d.ts.map +1 -0
  63. package/dist/src/room/track/options.d.ts +2 -2
  64. package/dist/src/room/track/options.d.ts.map +1 -1
  65. package/dist/src/room/track/utils.d.ts +5 -35
  66. package/dist/src/room/track/utils.d.ts.map +1 -1
  67. package/dist/src/room/utils.d.ts +2 -0
  68. package/dist/src/room/utils.d.ts.map +1 -1
  69. package/dist/src/test/MockMediaStreamTrack.d.ts.map +1 -1
  70. package/dist/ts4.2/src/api/SignalClient.d.ts +4 -1
  71. package/dist/ts4.2/src/e2ee/E2eeManager.d.ts +45 -0
  72. package/dist/ts4.2/src/e2ee/KeyProvider.d.ts +42 -0
  73. package/dist/ts4.2/src/e2ee/constants.d.ts +14 -0
  74. package/dist/ts4.2/src/e2ee/errors.d.ts +11 -0
  75. package/dist/ts4.2/src/e2ee/index.d.ts +4 -0
  76. package/dist/ts4.2/src/e2ee/types.d.ts +129 -0
  77. package/dist/ts4.2/src/e2ee/utils.d.ts +24 -0
  78. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +175 -0
  79. package/dist/ts4.2/src/e2ee/worker/ParticipantKeyHandler.d.ts +46 -0
  80. package/dist/ts4.2/src/e2ee/worker/e2ee.worker.d.ts +2 -0
  81. package/dist/ts4.2/src/index.d.ts +2 -0
  82. package/dist/ts4.2/src/logger.d.ts +4 -1
  83. package/dist/ts4.2/src/options.d.ts +5 -0
  84. package/dist/ts4.2/src/proto/livekit_models.d.ts +2 -2
  85. package/dist/ts4.2/src/room/PCTransport.d.ts +3 -1
  86. package/dist/ts4.2/src/room/RTCEngine.d.ts +17 -3
  87. package/dist/ts4.2/src/room/Room.d.ts +10 -1
  88. package/dist/ts4.2/src/room/events.d.ts +14 -2
  89. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +9 -2
  90. package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -0
  91. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +3 -2
  92. package/dist/ts4.2/src/room/track/TrackPublication.d.ts +3 -0
  93. package/dist/ts4.2/src/room/track/facingMode.d.ts +41 -0
  94. package/dist/ts4.2/src/room/track/options.d.ts +6 -6
  95. package/dist/ts4.2/src/room/track/utils.d.ts +5 -35
  96. package/dist/ts4.2/src/room/utils.d.ts +2 -0
  97. package/package.json +17 -7
  98. package/src/api/SignalClient.ts +28 -9
  99. package/src/connectionHelper/checks/turn.ts +1 -0
  100. package/src/connectionHelper/checks/websocket.ts +1 -0
  101. package/src/e2ee/E2eeManager.ts +374 -0
  102. package/src/e2ee/KeyProvider.ts +77 -0
  103. package/src/e2ee/constants.ts +40 -0
  104. package/src/e2ee/errors.ts +16 -0
  105. package/src/e2ee/index.ts +3 -0
  106. package/src/e2ee/types.ts +160 -0
  107. package/src/e2ee/utils.ts +127 -0
  108. package/src/e2ee/worker/FrameCryptor.test.ts +21 -0
  109. package/src/e2ee/worker/FrameCryptor.ts +614 -0
  110. package/src/e2ee/worker/ParticipantKeyHandler.ts +129 -0
  111. package/src/e2ee/worker/e2ee.worker.ts +217 -0
  112. package/src/e2ee/worker/tsconfig.json +6 -0
  113. package/src/index.ts +2 -0
  114. package/src/logger.ts +10 -2
  115. package/src/options.ts +6 -0
  116. package/src/proto/livekit_models.ts +12 -12
  117. package/src/room/PCTransport.ts +39 -9
  118. package/src/room/RTCEngine.ts +127 -34
  119. package/src/room/Room.ts +83 -30
  120. package/src/room/defaults.ts +1 -1
  121. package/src/room/events.ts +14 -0
  122. package/src/room/participant/LocalParticipant.ts +82 -10
  123. package/src/room/participant/Participant.ts +4 -0
  124. package/src/room/track/LocalAudioTrack.ts +11 -4
  125. package/src/room/track/LocalTrack.ts +50 -43
  126. package/src/room/track/LocalVideoTrack.ts +5 -3
  127. package/src/room/track/RemoteVideoTrack.ts +2 -2
  128. package/src/room/track/TrackPublication.ts +9 -1
  129. package/src/room/track/facingMode.test.ts +30 -0
  130. package/src/room/track/facingMode.ts +103 -0
  131. package/src/room/track/options.ts +3 -2
  132. package/src/room/track/utils.test.ts +1 -30
  133. package/src/room/track/utils.ts +16 -91
  134. package/src/room/utils.ts +5 -0
  135. package/src/room/worker.d.ts +4 -0
  136. package/src/test/MockMediaStreamTrack.ts +1 -0
@@ -0,0 +1,46 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import type { KeyProviderOptions, KeySet, ParticipantKeyHandlerCallbacks } from '../types';
3
+ /**
4
+ * ParticipantKeyHandler is responsible for providing a cryptor instance with the
5
+ * en-/decryption key of a participant. It assumes that all tracks of a specific participant
6
+ * are encrypted with the same key.
7
+ * Additionally it exposes a method to ratchet a key which can be used by the cryptor either automatically
8
+ * if decryption fails or can be triggered manually on both sender and receiver side.
9
+ *
10
+ */
11
+ export declare class ParticipantKeyHandler extends EventEmitter<ParticipantKeyHandlerCallbacks> {
12
+ private currentKeyIndex;
13
+ private cryptoKeyRing;
14
+ private enabled;
15
+ private keyProviderOptions;
16
+ private ratchetPromiseMap;
17
+ private participantId;
18
+ constructor(participantId: string | undefined, isEnabled: boolean, keyProviderOptions: KeyProviderOptions);
19
+ setEnabled(enabled: boolean): void;
20
+ /**
21
+ * Ratchets the current key (or the one at keyIndex if provided) and
22
+ * returns the ratcheted material
23
+ * if `setKey` is true (default), it will also set the ratcheted key directly on the crypto key ring
24
+ * @param keyIndex
25
+ * @param setKey
26
+ */
27
+ ratchetKey(keyIndex?: number, setKey?: boolean): Promise<CryptoKey>;
28
+ /**
29
+ * takes in a key material with `deriveBits` and `deriveKey` set as key usages
30
+ * and derives encryption keys from the material and sets it on the key ring buffer
31
+ * together with the material
32
+ * also updates the currentKeyIndex
33
+ */
34
+ setKeyFromMaterial(material: CryptoKey, keyIndex?: number, emitRatchetEvent?: boolean): Promise<void>;
35
+ setKeySet(keySet: KeySet, keyIndex: number, emitRatchetEvent?: boolean): Promise<void>;
36
+ setCurrentKeyIndex(index: number): Promise<void>;
37
+ isEnabled(): boolean;
38
+ getCurrentKeyIndex(): number;
39
+ /**
40
+ * returns currently used KeySet or the one at `keyIndex` if provided
41
+ * @param keyIndex
42
+ * @returns
43
+ */
44
+ getKeySet(keyIndex?: number): KeySet;
45
+ }
46
+ //# sourceMappingURL=ParticipantKeyHandler.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=e2ee.worker.d.ts.map
@@ -27,9 +27,11 @@ export * from './room/events';
27
27
  export * from './room/track/Track';
28
28
  export * from './room/track/create';
29
29
  export * from './room/track/options';
30
+ export { facingModeFromDeviceLabel, facingModeFromLocalTrack } from './room/track/facingMode';
30
31
  export * from './room/track/types';
31
32
  export type { DataPublishOptions, SimulationScenario } from './room/types';
32
33
  export * from './version';
34
+ export * from './e2ee';
33
35
  export * from './room/track/processor/types';
34
36
  export { setLogLevel, setLogExtension, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, isBrowserSupported, supportsAdaptiveStream, supportsDynacast, supportsAV1, supportsVP9, createAudioAnalyser, LogLevel, Room, ConnectionState, RoomState, DataPacket_Kind, DisconnectReason, Participant, RemoteParticipant, LocalParticipant, LocalAudioTrack, LocalVideoTrack, LocalTrack, LocalTrackPublication, RemoteTrack, RemoteAudioTrack, RemoteVideoTrack, RemoteTrackPublication, TrackPublication, VideoQuality, ConnectionQuality, DefaultReconnectPolicy, CriticalTimers, };
35
37
  export type { ElementInfo, ParticipantTrackPermission, AudioAnalyserOptions, LiveKitReactNativeInfo, };
@@ -1,3 +1,4 @@
1
+ import * as log from 'loglevel';
1
2
  export declare enum LogLevel {
2
3
  trace = 0,
3
4
  debug = 1,
@@ -13,14 +14,16 @@ type StructuredLogger = {
13
14
  info: (msg: string, context?: object) => void;
14
15
  warn: (msg: string, context?: object) => void;
15
16
  error: (msg: string, context?: object) => void;
17
+ setDefaultLevel: (level: log.LogLevelDesc) => void;
16
18
  };
17
19
  declare const _default: StructuredLogger;
18
20
  export default _default;
19
- export declare function setLogLevel(level: LogLevel | LogLevelString): void;
21
+ export declare function setLogLevel(level: LogLevel | LogLevelString, loggerName?: 'livekit' | 'lk-e2ee'): void;
20
22
  export type LogExtension = (level: LogLevel, msg: string, context?: object) => void;
21
23
  /**
22
24
  * use this to hook into the logging function to allow sending internal livekit logs to third party services
23
25
  * if set, the browser logs will lose their stacktrace information (see https://github.com/pimterry/loglevel#writing-plugins)
24
26
  */
25
27
  export declare function setLogExtension(extension: LogExtension): void;
28
+ export declare const workerLogger: StructuredLogger;
26
29
  //# sourceMappingURL=logger.d.ts.map
@@ -1,3 +1,4 @@
1
+ import type { E2EEOptions } from './e2ee/types';
1
2
  import type { ReconnectPolicy } from './room/ReconnectPolicy';
2
3
  import type { AudioCaptureOptions, AudioOutputOptions, TrackPublishDefaults, VideoCaptureOptions } from './room/track/options';
3
4
  import type { AdaptiveStreamSettings } from './room/track/types';
@@ -65,6 +66,10 @@ export interface InternalRoomOptions {
65
66
  * experimental flag, mix all audio tracks in web audio
66
67
  */
67
68
  expWebAudioMix: boolean | WebAudioSettings;
69
+ /**
70
+ * @experimental
71
+ */
72
+ e2ee?: E2EEOptions;
68
73
  }
69
74
  /**
70
75
  * Options for when creating a new room
@@ -75,7 +75,7 @@ export declare enum DisconnectReason {
75
75
  export declare function disconnectReasonFromJSON(object: any): DisconnectReason;
76
76
  export declare function disconnectReasonToJSON(object: DisconnectReason): string;
77
77
  export declare enum ReconnectReason {
78
- RR_UNKOWN = 0,
78
+ RR_UNKNOWN = 0,
79
79
  RR_SIGNAL_DISCONNECTED = 1,
80
80
  RR_PUBLISHER_FAILED = 2,
81
81
  RR_SUBSCRIBER_FAILED = 3,
@@ -85,7 +85,7 @@ export declare enum ReconnectReason {
85
85
  export declare function reconnectReasonFromJSON(object: any): ReconnectReason;
86
86
  export declare function reconnectReasonToJSON(object: ReconnectReason): string;
87
87
  export declare enum SubscriptionError {
88
- SE_UNKOWN = 0,
88
+ SE_UNKNOWN = 0,
89
89
  SE_CODEC_UNSUPPORTED = 1,
90
90
  SE_TRACK_NOTFOUND = 2,
91
91
  UNRECOGNIZED = -1
@@ -9,10 +9,12 @@ interface TrackBitrateInfo {
9
9
  export declare const PCEvents: {
10
10
  readonly NegotiationStarted: "negotiationStarted";
11
11
  readonly NegotiationComplete: "negotiationComplete";
12
+ readonly RTPVideoPayloadTypes: "rtpVideoPayloadTypes";
12
13
  };
13
14
  /** @internal */
14
15
  export default class PCTransport extends EventEmitter {
15
- pc: RTCPeerConnection;
16
+ private _pc;
17
+ get pc(): RTCPeerConnection;
16
18
  pendingCandidates: RTCIceCandidateInit[];
17
19
  restartingIce: boolean;
18
20
  renegotiate: boolean;
@@ -2,13 +2,14 @@ import EventEmitter from 'eventemitter3';
2
2
  import { SignalClient } from '../api/SignalClient';
3
3
  import type { SignalOptions } from '../api/SignalClient';
4
4
  import type { InternalRoomOptions } from '../options';
5
- import { DataPacket, DataPacket_Kind, DisconnectReason, SpeakerInfo, TrackInfo, UserPacket } from '../proto/livekit_models';
6
- import { AddTrackRequest, JoinResponse } from '../proto/livekit_rtc';
5
+ import { DataPacket, DataPacket_Kind, DisconnectReason, ParticipantInfo, Room as RoomModel, SpeakerInfo, TrackInfo, UserPacket } from '../proto/livekit_models';
6
+ import { AddTrackRequest, ConnectionQualityUpdate, JoinResponse, StreamStateUpdate, SubscriptionPermissionUpdate, SubscriptionResponse } from '../proto/livekit_rtc';
7
7
  import PCTransport from './PCTransport';
8
8
  import type LocalTrack from './track/LocalTrack';
9
9
  import type LocalVideoTrack from './track/LocalVideoTrack';
10
10
  import type { SimulcastTrackInfo } from './track/LocalVideoTrack';
11
- import type { TrackPublishOptions } from './track/options';
11
+ import { Track } from './track/Track';
12
+ import type { TrackPublishOptions, VideoCodec } from './track/options';
12
13
  /** @internal */
13
14
  export default class RTCEngine extends EventEmitter<EngineEventCallbacks> {
14
15
  private options;
@@ -55,6 +56,8 @@ export default class RTCEngine extends EventEmitter<EngineEventCallbacks> {
55
56
  constructor(options: InternalRoomOptions);
56
57
  join(url: string, token: string, opts: SignalOptions, abortSignal?: AbortSignal): Promise<JoinResponse>;
57
58
  close(): Promise<void>;
59
+ cleanupPeerConnections(): Promise<void>;
60
+ cleanupClient(): Promise<void>;
58
61
  addTrack(req: AddTrackRequest): Promise<TrackInfo>;
59
62
  /**
60
63
  * Removes sender from PeerConnection, returning true if it was removed successfully
@@ -67,6 +70,7 @@ export default class RTCEngine extends EventEmitter<EngineEventCallbacks> {
67
70
  get dataSubscriberReadyState(): string | undefined;
68
71
  getConnectedServerAddress(): Promise<string | undefined>;
69
72
  private configure;
73
+ private setupSignalClientCallbacks;
70
74
  private makeRTCConfiguration;
71
75
  private createDataChannels;
72
76
  private handleDataChannel;
@@ -120,6 +124,16 @@ export type EngineEventCallbacks = {
120
124
  activeSpeakersUpdate: (speakers: Array<SpeakerInfo>) => void;
121
125
  dataPacketReceived: (userPacket: UserPacket, kind: DataPacket_Kind) => void;
122
126
  transportsCreated: (publisher: PCTransport, subscriber: PCTransport) => void;
127
+ /** @internal */
128
+ trackSenderAdded: (track: Track, sender: RTCRtpSender) => void;
129
+ rtpVideoMapUpdate: (rtpMap: Map<number, VideoCodec>) => void;
123
130
  dcBufferStatusChanged: (isLow: boolean, kind: DataPacket_Kind) => void;
131
+ participantUpdate: (infos: ParticipantInfo[]) => void;
132
+ roomUpdate: (room: RoomModel) => void;
133
+ connectionQualityUpdate: (update: ConnectionQualityUpdate) => void;
134
+ speakersChanged: (speakerUpdates: SpeakerInfo[]) => void;
135
+ streamStateChanged: (update: StreamStateUpdate) => void;
136
+ subscriptionError: (resp: SubscriptionResponse) => void;
137
+ subscriptionPermissionUpdate: (update: SubscriptionPermissionUpdate) => void;
124
138
  };
125
139
  //# sourceMappingURL=RTCEngine.d.ts.map
@@ -44,6 +44,8 @@ declare class Room extends EventEmitter<RoomEventCallbacks> {
44
44
  localParticipant: LocalParticipant;
45
45
  /** options of room */
46
46
  options: InternalRoomOptions;
47
+ /** reflects the sender encryption status of the local participant */
48
+ isE2EEEnabled: boolean;
47
49
  private roomInfo?;
48
50
  private identityToSid;
49
51
  /** connect options of room */
@@ -55,14 +57,19 @@ declare class Room extends EventEmitter<RoomEventCallbacks> {
55
57
  /** future holding client initiated connection attempt */
56
58
  private connectFuture?;
57
59
  private disconnectLock;
60
+ private e2eeManager;
58
61
  private cachedParticipantSids;
59
62
  private connectionReconcileInterval?;
60
- private activeDeviceMap;
61
63
  /**
62
64
  * Creates a new Room, the primary construct for a LiveKit session.
63
65
  * @param options
64
66
  */
65
67
  constructor(options?: RoomOptions);
68
+ /**
69
+ * @experimental
70
+ */
71
+ setE2EEEnabled(enabled: boolean): Promise<void>;
72
+ private setupE2EE;
66
73
  /**
67
74
  * if the current room has a participant with `recorder: true` in its JWT grant
68
75
  **/
@@ -229,6 +236,8 @@ export type RoomEventCallbacks = {
229
236
  audioPlaybackChanged: (playing: boolean) => void;
230
237
  signalConnected: () => void;
231
238
  recordingStatusChanged: (recording: boolean) => void;
239
+ participantEncryptionStatusChanged: (encrypted: boolean, participant?: Participant) => void;
240
+ encryptionError: (error: Error) => void;
232
241
  dcBufferStatusChanged: (isLow: boolean, kind: DataPacket_Kind) => void;
233
242
  activeDeviceChanged: (kind: MediaDeviceKind, deviceId: string) => void;
234
243
  };
@@ -239,6 +239,8 @@ export declare enum RoomEvent {
239
239
  * args: (isRecording: boolean)
240
240
  */
241
241
  RecordingStatusChanged = "recordingStatusChanged",
242
+ ParticipantEncryptionStatusChanged = "participantEncryptionStatusChanged",
243
+ EncryptionError = "encryptionError",
242
244
  /**
243
245
  * Emits whenever the current buffer status of a data channel changes
244
246
  * args: (isLow: boolean, kind: [[DataPacket_Kind]])
@@ -387,7 +389,9 @@ export declare enum ParticipantEvent {
387
389
  * A participant's permission has changed. Currently only fired on LocalParticipant.
388
390
  * args: (prevPermissions: [[ParticipantPermission]])
389
391
  */
390
- ParticipantPermissionsChanged = "participantPermissionsChanged"
392
+ ParticipantPermissionsChanged = "participantPermissionsChanged",
393
+ /** @internal */
394
+ PCTrackAdded = "pcTrackAdded"
391
395
  }
392
396
  /** @internal */
393
397
  export declare enum EngineEvent {
@@ -404,7 +408,15 @@ export declare enum EngineEvent {
404
408
  MediaTrackAdded = "mediaTrackAdded",
405
409
  ActiveSpeakersUpdate = "activeSpeakersUpdate",
406
410
  DataPacketReceived = "dataPacketReceived",
407
- DCBufferStatusChanged = "dcBufferStatusChanged"
411
+ RTPVideoMapUpdate = "rtpVideoMapUpdate",
412
+ DCBufferStatusChanged = "dcBufferStatusChanged",
413
+ ParticipantUpdate = "participantUpdate",
414
+ RoomUpdate = "roomUpdate",
415
+ SpeakersChanged = "speakersChanged",
416
+ StreamStateChanged = "streamStateChanged",
417
+ ConnectionQualityUpdate = "connectionQualityUpdate",
418
+ SubscriptionError = "subscriptionError",
419
+ SubscriptionPermissionUpdate = "subscriptionPermissionUpdate"
408
420
  }
409
421
  export declare enum TrackEvent {
410
422
  Message = "message",
@@ -1,5 +1,5 @@
1
1
  import type { InternalRoomOptions } from '../../options';
2
- import { DataPacket_Kind, ParticipantInfo } from '../../proto/livekit_models';
2
+ import { DataPacket_Kind, ParticipantInfo, ParticipantPermission } from '../../proto/livekit_models';
3
3
  import { DataChannelInfo, TrackPublishedResponse } from '../../proto/livekit_rtc';
4
4
  import type RTCEngine from '../RTCEngine';
5
5
  import LocalTrack from '../track/LocalTrack';
@@ -17,6 +17,8 @@ export default class LocalParticipant extends Participant {
17
17
  tracks: Map<string, LocalTrackPublication>;
18
18
  /** @internal */
19
19
  engine: RTCEngine;
20
+ /** @internal */
21
+ activeDeviceMap: Map<MediaDeviceKind, string>;
20
22
  private pendingPublishing;
21
23
  private pendingPublishPromises;
22
24
  private cameraError;
@@ -24,6 +26,7 @@ export default class LocalParticipant extends Participant {
24
26
  private participantTrackPermissions;
25
27
  private allParticipantsAllowedToSubscribe;
26
28
  private roomOptions;
29
+ private encryptionType;
27
30
  private reconnectFuture?;
28
31
  /** @internal */
29
32
  constructor(sid: string, identity: string, engine: RTCEngine, options: InternalRoomOptions);
@@ -69,6 +72,10 @@ export default class LocalParticipant extends Participant {
69
72
  * Resolves with a `LocalTrackPublication` instance if successful and `undefined` otherwise
70
73
  */
71
74
  setScreenShareEnabled(enabled: boolean, options?: ScreenShareCaptureOptions, publishOptions?: TrackPublishOptions): Promise<LocalTrackPublication | undefined>;
75
+ /** @internal */
76
+ setPermissions(permissions: ParticipantPermission): boolean;
77
+ /** @internal */
78
+ setE2EEEnabled(enabled: boolean): Promise<void>;
72
79
  /**
73
80
  * Enable or disable publishing for a track by source. This serves as a simple
74
81
  * way to manage the common tracks (camera, mic, or screen share).
@@ -106,7 +113,7 @@ export default class LocalParticipant extends Participant {
106
113
  publishAdditionalCodecForTrack(track: LocalTrack | MediaStreamTrack, videoCodec: BackupVideoCodec, options?: TrackPublishOptions): Promise<void>;
107
114
  unpublishTrack(track: LocalTrack | MediaStreamTrack, stopOnUnpublish?: boolean): Promise<LocalTrackPublication | undefined>;
108
115
  unpublishTracks(tracks: LocalTrack[] | MediaStreamTrack[]): Promise<LocalTrackPublication[]>;
109
- republishAllTracks(options?: TrackPublishOptions): Promise<void>;
116
+ republishAllTracks(options?: TrackPublishOptions, restartTracks?: boolean): Promise<void>;
110
117
  /**
111
118
  * Publish a new data payload to the room. Data will be forwarded to each
112
119
  * participant in the room if the destination field in publishOptions is empty
@@ -32,6 +32,7 @@ export default class Participant extends EventEmitter<ParticipantEventCallbacks>
32
32
  lastSpokeAt?: Date | undefined;
33
33
  permissions?: ParticipantPermission;
34
34
  private _connectionQuality;
35
+ get isEncrypted(): boolean;
35
36
  /** @internal */
36
37
  constructor(sid: string, identity: string, name?: string, metadata?: string);
37
38
  getTracks(): TrackPublication[];
@@ -7,14 +7,15 @@ export default abstract class LocalTrack extends Track {
7
7
  sender?: RTCRtpSender;
8
8
  /** @internal */
9
9
  codec?: VideoCodec;
10
- protected constraints: MediaTrackConstraints;
10
+ get constraints(): MediaTrackConstraints;
11
+ protected _constraints: MediaTrackConstraints;
11
12
  protected reacquireTrack: boolean;
12
13
  protected providedByUser: boolean;
13
14
  protected muteLock: Mutex;
14
15
  protected pauseUpstreamLock: Mutex;
15
16
  protected processorElement?: HTMLMediaElement;
16
17
  protected processor?: TrackProcessor<typeof this.kind>;
17
- protected isSettingUpProcessor: boolean;
18
+ protected processorLock: Mutex;
18
19
  /**
19
20
  *
20
21
  * @param mediaTrack
@@ -1,4 +1,5 @@
1
1
  import EventEmitter from 'eventemitter3';
2
+ import { Encryption_Type } from '../../proto/livekit_models';
2
3
  import type { SubscriptionError, TrackInfo } from '../../proto/livekit_models';
3
4
  import type { UpdateSubscription, UpdateTrackSettings } from '../../proto/livekit_rtc';
4
5
  import LocalAudioTrack from './LocalAudioTrack';
@@ -22,12 +23,14 @@ export declare class TrackPublication extends EventEmitter<PublicationEventCallb
22
23
  /** @internal */
23
24
  trackInfo?: TrackInfo;
24
25
  protected metadataMuted: boolean;
26
+ protected encryption: Encryption_Type;
25
27
  constructor(kind: Track.Kind, id: string, name: string);
26
28
  /** @internal */
27
29
  setTrack(track?: Track): void;
28
30
  get isMuted(): boolean;
29
31
  get isEnabled(): boolean;
30
32
  get isSubscribed(): boolean;
33
+ get isEncrypted(): boolean;
31
34
  /**
32
35
  * an [AudioTrack] if this publication holds an audio track
33
36
  */
@@ -0,0 +1,41 @@
1
+ import LocalTrack from './LocalTrack';
2
+ import type { VideoCaptureOptions } from './options';
3
+ type FacingMode = NonNullable<VideoCaptureOptions['facingMode']>;
4
+ type FacingModeFromLocalTrackOptions = {
5
+ /**
6
+ * If no facing mode can be determined, this value will be used.
7
+ * @defaultValue 'user'
8
+ */
9
+ defaultFacingMode?: FacingMode;
10
+ };
11
+ type FacingModeFromLocalTrackReturnValue = {
12
+ /**
13
+ * The (probable) facingMode of the track.
14
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/facingMode | MDN docs on facingMode}
15
+ */
16
+ facingMode: FacingMode;
17
+ /**
18
+ * The confidence that the returned facingMode is correct.
19
+ */
20
+ confidence: 'high' | 'medium' | 'low';
21
+ };
22
+ /**
23
+ * Try to analyze the local track to determine the facing mode of a track.
24
+ *
25
+ * @remarks
26
+ * There is no property supported by all browsers to detect whether a video track originated from a user- or environment-facing camera device.
27
+ * For this reason, we use the `facingMode` property when available, but will fall back on a string-based analysis of the device label to determine the facing mode.
28
+ * If both methods fail, the default facing mode will be used.
29
+ *
30
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/facingMode | MDN docs on facingMode}
31
+ * @experimental
32
+ */
33
+ export declare function facingModeFromLocalTrack(localTrack: LocalTrack | MediaStreamTrack, options?: FacingModeFromLocalTrackOptions): FacingModeFromLocalTrackReturnValue;
34
+ /**
35
+ * Attempt to analyze the device label to determine the facing mode.
36
+ *
37
+ * @experimental
38
+ */
39
+ export declare function facingModeFromDeviceLabel(deviceLabel: string): FacingModeFromLocalTrackReturnValue | undefined;
40
+ export {};
41
+ //# sourceMappingURL=facingMode.d.ts.map
@@ -208,17 +208,17 @@ export interface AudioPreset {
208
208
  maxBitrate: number;
209
209
  priority?: RTCPriorityType;
210
210
  }
211
- declare const codecs: readonly [
211
+ declare const backupCodecs: readonly [
212
+ "vp8",
213
+ "h264"
214
+ ];
215
+ export declare const videoCodecs: readonly [
212
216
  "vp8",
213
217
  "h264",
214
218
  "vp9",
215
219
  "av1"
216
220
  ];
217
- declare const backupCodecs: readonly [
218
- "vp8",
219
- "h264"
220
- ];
221
- export type VideoCodec = (typeof codecs)[number];
221
+ export type VideoCodec = (typeof videoCodecs)[number];
222
222
  export type BackupVideoCodec = (typeof backupCodecs)[number];
223
223
  export declare function isBackupCodec(codec: string): codec is BackupVideoCodec;
224
224
  export declare function isCodecEqual(c1: string | undefined, c2: string | undefined): boolean;
@@ -1,4 +1,4 @@
1
- import LocalTrack from './LocalTrack';
1
+ import { Track } from './Track';
2
2
  import type { AudioCaptureOptions, CreateLocalTracksOptions, VideoCaptureOptions } from './options';
3
3
  import type { AudioTrack } from './types';
4
4
  export declare function mergeDefaultOptions(options?: CreateLocalTracksOptions, audioDefaults?: AudioCaptureOptions, videoDefaults?: VideoCaptureOptions): CreateLocalTracksOptions;
@@ -12,42 +12,12 @@ export declare function detectSilence(track: AudioTrack, timeOffset?: number): P
12
12
  * @internal
13
13
  */
14
14
  export declare function getNewAudioContext(): AudioContext | void;
15
- type FacingMode = NonNullable<VideoCaptureOptions['facingMode']>;
16
- type FacingModeFromLocalTrackOptions = {
17
- /**
18
- * If no facing mode can be determined, this value will be used.
19
- * @defaultValue 'user'
20
- */
21
- defaultFacingMode?: FacingMode;
22
- };
23
- type FacingModeFromLocalTrackReturnValue = {
24
- /**
25
- * The (probable) facingMode of the track.
26
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/facingMode | MDN docs on facingMode}
27
- */
28
- facingMode: FacingMode;
29
- /**
30
- * The confidence that the returned facingMode is correct.
31
- */
32
- confidence: 'high' | 'medium' | 'low';
33
- };
34
15
  /**
35
- * Try to analyze the local track to determine the facing mode of a track.
36
- *
37
- * @remarks
38
- * There is no property supported by all browsers to detect whether a video track originated from a user- or environment-facing camera device.
39
- * For this reason, we use the `facingMode` property when available, but will fall back on a string-based analysis of the device label to determine the facing mode.
40
- * If both methods fail, the default facing mode will be used.
41
- *
42
- * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MediaTrackConstraints/facingMode | MDN docs on facingMode}
43
- * @experimental
16
+ * @internal
44
17
  */
45
- export declare function facingModeFromLocalTrack(localTrack: LocalTrack | MediaStreamTrack, options?: FacingModeFromLocalTrackOptions): FacingModeFromLocalTrackReturnValue;
18
+ export declare function kindToSource(kind: MediaDeviceKind): Track.Source.Camera | Track.Source.Microphone | Track.Source.Unknown;
46
19
  /**
47
- * Attempt to analyze the device label to determine the facing mode.
48
- *
49
- * @experimental
20
+ * @internal
50
21
  */
51
- export declare function facingModeFromDeviceLabel(deviceLabel: string): FacingModeFromLocalTrackReturnValue | undefined;
52
- export {};
22
+ export declare function sourceToKind(source: Track.Source): MediaDeviceKind | undefined;
53
23
  //# sourceMappingURL=utils.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import { ClientInfo } from '../proto/livekit_models';
2
2
  import type LocalAudioTrack from './track/LocalAudioTrack';
3
3
  import type RemoteAudioTrack from './track/RemoteAudioTrack';
4
+ import { VideoCodec } from './track/options';
4
5
  export declare const ddExtensionURI = "https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension";
5
6
  export declare function unpackStreamId(packed: string): string[];
6
7
  export declare function sleep(duration: number): Promise<void>;
@@ -84,5 +85,6 @@ export declare class Mutex {
84
85
  isLocked(): boolean;
85
86
  lock(): Promise<() => void>;
86
87
  }
88
+ export declare function isVideoCodec(maybeCodec: string): maybeCodec is VideoCodec;
87
89
  export declare function unwrapConstraint(constraint: ConstrainDOMString): string;
88
90
  //# sourceMappingURL=utils.d.ts.map
package/package.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
2
  "name": "livekit-client",
3
- "version": "1.11.3",
3
+ "version": "1.12.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",
7
7
  "module": "./dist/livekit-client.esm.mjs",
8
8
  "exports": {
9
- "types": "./dist/src/index.d.ts",
10
- "import": "./dist/livekit-client.esm.mjs",
11
- "require": "./dist/livekit-client.umd.js"
9
+ ".": {
10
+ "types": "./dist/src/index.d.ts",
11
+ "import": "./dist/livekit-client.esm.mjs",
12
+ "require": "./dist/livekit-client.umd.js"
13
+ },
14
+ "./e2ee-worker": {
15
+ "types": "./dist/src/e2ee/worker/e2ee.worker.d.ts",
16
+ "import": "./dist/livekit-client.e2ee.worker.mjs",
17
+ "require": "./dist/livekit-client.e2ee.worker.js"
18
+ }
12
19
  },
13
20
  "files": [
14
21
  "dist",
@@ -18,7 +25,10 @@
18
25
  "typesVersions": {
19
26
  "<4.8": {
20
27
  "./dist/src/index.d.ts": [
21
- "./dist/src/ts4.2/index.d.ts"
28
+ "./dist/ts4.2/src/index.d.ts"
29
+ ],
30
+ "./dist/src/e2ee/worker/e2ee.worker.d.ts": [
31
+ "./dist/ts4.2//dist/src/e2ee/worker/e2ee.worker.d.ts"
22
32
  ]
23
33
  }
24
34
  },
@@ -26,11 +36,11 @@
26
36
  "author": "David Zhao <david@davidzhao.com>",
27
37
  "license": "Apache-2.0",
28
38
  "scripts": {
29
- "build": "rollup --config --bundleConfigAsCjs && yarn downlevel-dts",
39
+ "build": "rollup --config --bundleConfigAsCjs && rollup --config rollup.config.worker.js --bundleConfigAsCjs && yarn downlevel-dts",
30
40
  "build:watch": "rollup --watch --config rollup.config.js",
31
41
  "build-docs": "typedoc",
32
42
  "proto": "protoc --plugin=node_modules/ts-proto/protoc-gen-ts_proto --ts_proto_opt=esModuleInterop=true --ts_proto_out=./src/proto --ts_proto_opt=outputClientImpl=false,useOptionals=messages,oneof=unions -I./protocol ./protocol/livekit_rtc.proto ./protocol/livekit_models.proto",
33
- "sample": "vite serve example --port 8080 --open",
43
+ "sample": "vite example -c vite.config.js",
34
44
  "lint": "eslint src",
35
45
  "test": "jest",
36
46
  "deploy": "gh-pages -d example/dist",
@@ -60,6 +60,7 @@ export interface SignalOptions {
60
60
  publishOnly?: string;
61
61
  adaptiveStream?: boolean;
62
62
  maxRetries: number;
63
+ e2eeEnabled: boolean;
63
64
  }
64
65
 
65
66
  type SignalMessage = SignalRequest['message'];
@@ -198,7 +199,7 @@ export class SignalClient {
198
199
  return res;
199
200
  }
200
201
 
201
- connect(
202
+ private connect(
202
203
  url: string,
203
204
  token: string,
204
205
  opts: ConnectOpts,
@@ -329,21 +330,38 @@ export class SignalClient {
329
330
  });
330
331
  }
331
332
 
333
+ /** @internal */
334
+ resetCallbacks = () => {
335
+ this.onAnswer = undefined;
336
+ this.onLeave = undefined;
337
+ this.onLocalTrackPublished = undefined;
338
+ this.onLocalTrackUnpublished = undefined;
339
+ this.onNegotiateRequested = undefined;
340
+ this.onOffer = undefined;
341
+ this.onRemoteMuteChanged = undefined;
342
+ this.onSubscribedQualityUpdate = undefined;
343
+ this.onTokenRefresh = undefined;
344
+ this.onTrickle = undefined;
345
+ this.onClose = undefined;
346
+ };
347
+
332
348
  async close() {
333
349
  const unlock = await this.closingLock.lock();
334
350
  try {
335
351
  this.isConnected = false;
336
352
  if (this.ws) {
337
- this.ws.onclose = null;
338
353
  this.ws.onmessage = null;
339
354
  this.ws.onopen = null;
355
+ this.ws.onclose = null;
340
356
 
341
357
  // calling `ws.close()` only starts the closing handshake (CLOSING state), prefer to wait until state is actually CLOSED
342
- const closePromise = new Promise((resolve) => {
358
+ const closePromise = new Promise<void>((resolve) => {
343
359
  if (this.ws) {
344
- this.ws.onclose = resolve;
360
+ this.ws.onclose = () => {
361
+ resolve();
362
+ };
345
363
  } else {
346
- resolve(true);
364
+ resolve();
347
365
  }
348
366
  });
349
367
 
@@ -353,9 +371,9 @@ export class SignalClient {
353
371
  await Promise.race([closePromise, sleep(250)]);
354
372
  }
355
373
  this.ws = undefined;
356
- this.clearPingInterval();
357
374
  }
358
375
  } finally {
376
+ this.clearPingInterval();
359
377
  unlock();
360
378
  }
361
379
  }
@@ -402,7 +420,7 @@ export class SignalClient {
402
420
  sendAddTrack(req: AddTrackRequest) {
403
421
  return this.sendRequest({
404
422
  $case: 'addTrack',
405
- addTrack: AddTrackRequest.fromPartial(req),
423
+ addTrack: req,
406
424
  });
407
425
  }
408
426
 
@@ -622,10 +640,11 @@ export class SignalClient {
622
640
 
623
641
  private async handleOnClose(reason: string) {
624
642
  if (!this.isConnected) return;
643
+ const onCloseCallback = this.onClose;
625
644
  await this.close();
626
645
  log.debug(`websocket connection closed: ${reason}`);
627
- if (this.onClose) {
628
- this.onClose(reason);
646
+ if (onCloseCallback) {
647
+ onCloseCallback(reason);
629
648
  }
630
649
  }
631
650
 
@@ -11,6 +11,7 @@ export class TURNCheck extends Checker {
11
11
  const joinRes = await signalClient.join(this.url, this.token, {
12
12
  autoSubscribe: true,
13
13
  maxRetries: 0,
14
+ e2eeEnabled: false,
14
15
  });
15
16
 
16
17
  let hasTLS = false;