livekit-client 1.13.2 → 1.13.4

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.
Files changed (39) hide show
  1. package/README.md +2 -2
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +87 -16
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +137 -31
  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/e2ee/utils.d.ts +3 -0
  11. package/dist/src/e2ee/utils.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  13. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  14. package/dist/src/room/participant/LocalParticipant.d.ts +6 -2
  15. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  16. package/dist/src/room/participant/Participant.d.ts +5 -3
  17. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  18. package/dist/src/room/track/LocalTrack.d.ts +7 -0
  19. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  20. package/dist/src/room/track/RemoteTrack.d.ts +7 -0
  21. package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
  22. package/dist/src/room/utils.d.ts +1 -1
  23. package/dist/ts4.2/src/e2ee/utils.d.ts +3 -0
  24. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +6 -2
  25. package/dist/ts4.2/src/room/participant/Participant.d.ts +5 -3
  26. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +7 -0
  27. package/dist/ts4.2/src/room/track/RemoteTrack.d.ts +7 -0
  28. package/dist/ts4.2/src/room/utils.d.ts +1 -1
  29. package/package.json +15 -15
  30. package/src/e2ee/utils.ts +52 -0
  31. package/src/e2ee/worker/FrameCryptor.ts +49 -27
  32. package/src/room/RTCEngine.ts +3 -2
  33. package/src/room/Room.ts +3 -3
  34. package/src/room/participant/LocalParticipant.ts +9 -7
  35. package/src/room/participant/Participant.ts +7 -5
  36. package/src/room/track/LocalTrack.ts +14 -0
  37. package/src/room/track/RemoteTrack.ts +14 -0
  38. package/src/room/track/options.ts +1 -1
  39. package/src/room/utils.ts +2 -2
@@ -2483,7 +2483,7 @@ function debugJsonValue(json) {
2483
2483
  case "string":
2484
2484
  return json.length > 100 ? "string" : "\"".concat(json.split('"').join('\\"'), "\"");
2485
2485
  default:
2486
- return json.toString();
2486
+ return String(json);
2487
2487
  }
2488
2488
  }
2489
2489
  // May throw an error. If the error message is non-blank, it should be shown.
@@ -2590,6 +2590,7 @@ function readEnum(type, json, ignoreUnknownFields) {
2590
2590
  break;
2591
2591
  case "string":
2592
2592
  const value = type.findName(json);
2593
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
2593
2594
  if (value || ignoreUnknownFields) {
2594
2595
  return value === null || value === void 0 ? void 0 : value.no;
2595
2596
  }
@@ -2786,6 +2787,8 @@ function makeUtilCommon() {
2786
2787
  let val = s[localName].value;
2787
2788
  if (sourceField && sourceField.kind == "message" && !(val instanceof sourceField.T)) {
2788
2789
  val = new sourceField.T(val);
2790
+ } else if (sourceField && sourceField.kind === "scalar" && sourceField.T === ScalarType.BYTES) {
2791
+ val = toU8Arr(val);
2789
2792
  }
2790
2793
  t[localName] = {
2791
2794
  case: sk,
@@ -2794,13 +2797,23 @@ function makeUtilCommon() {
2794
2797
  break;
2795
2798
  case "scalar":
2796
2799
  case "enum":
2797
- t[localName] = s[localName];
2800
+ let copy = s[localName];
2801
+ if (member.T === ScalarType.BYTES) {
2802
+ copy = member.repeated ? copy.map(toU8Arr) : toU8Arr(copy);
2803
+ }
2804
+ t[localName] = copy;
2798
2805
  break;
2799
2806
  case "map":
2800
2807
  switch (member.V.kind) {
2801
2808
  case "scalar":
2802
2809
  case "enum":
2803
- Object.assign(t[localName], s[localName]);
2810
+ if (member.V.T === ScalarType.BYTES) {
2811
+ for (const [k, v] of Object.entries(s[localName])) {
2812
+ t[localName][k] = toU8Arr(v);
2813
+ }
2814
+ } else {
2815
+ Object.assign(t[localName], s[localName]);
2816
+ }
2804
2817
  break;
2805
2818
  case "message":
2806
2819
  const messageType = member.V.T;
@@ -2823,7 +2836,13 @@ function makeUtilCommon() {
2823
2836
  } else if (s[localName] !== undefined) {
2824
2837
  const val = s[localName];
2825
2838
  if (mt.fieldWrapper) {
2826
- t[localName] = val;
2839
+ if (
2840
+ // We can't use BytesValue.typeName as that will create a circular import
2841
+ mt.typeName === "google.protobuf.BytesValue") {
2842
+ t[localName] = toU8Arr(val);
2843
+ } else {
2844
+ t[localName] = val;
2845
+ }
2827
2846
  } else {
2828
2847
  t[localName] = val instanceof mt ? val : new mt(val);
2829
2848
  }
@@ -2906,22 +2925,22 @@ function makeUtilCommon() {
2906
2925
  const source = message[member.localName];
2907
2926
  let copy;
2908
2927
  if (member.repeated) {
2909
- copy = source.map(e => cloneSingularField(member, e));
2928
+ copy = source.map(cloneSingularField);
2910
2929
  } else if (member.kind == "map") {
2911
2930
  copy = any[member.localName];
2912
2931
  for (const [key, v] of Object.entries(source)) {
2913
- copy[key] = cloneSingularField(member.V, v);
2932
+ copy[key] = cloneSingularField(v);
2914
2933
  }
2915
2934
  } else if (member.kind == "oneof") {
2916
2935
  const f = member.findField(source.case);
2917
2936
  copy = f ? {
2918
2937
  case: source.case,
2919
- value: cloneSingularField(f, source.value)
2938
+ value: cloneSingularField(source.value)
2920
2939
  } : {
2921
2940
  case: undefined
2922
2941
  };
2923
2942
  } else {
2924
- copy = cloneSingularField(member, source);
2943
+ copy = cloneSingularField(source);
2925
2944
  }
2926
2945
  any[member.localName] = copy;
2927
2946
  }
@@ -2930,7 +2949,7 @@ function makeUtilCommon() {
2930
2949
  };
2931
2950
  }
2932
2951
  // clone a single field value - i.e. the element type of repeated fields, the value type of maps
2933
- function cloneSingularField(field, value) {
2952
+ function cloneSingularField(value) {
2934
2953
  if (value === undefined) {
2935
2954
  return value;
2936
2955
  }
@@ -2944,6 +2963,10 @@ function cloneSingularField(field, value) {
2944
2963
  }
2945
2964
  return value;
2946
2965
  }
2966
+ // converts any ArrayLike<number> to Uint8Array if necessary.
2967
+ function toU8Arr(input) {
2968
+ return input instanceof Uint8Array ? input : new Uint8Array(input);
2969
+ }
2947
2970
 
2948
2971
  // Copyright 2021-2023 Buf Technologies, Inc.
2949
2972
  //
@@ -11840,7 +11863,7 @@ function getMatch(exp, ua) {
11840
11863
  return match && match.length >= id && match[id] || '';
11841
11864
  }
11842
11865
 
11843
- var version$1 = "1.13.2";
11866
+ var version$1 = "1.13.4";
11844
11867
 
11845
11868
  const version = version$1;
11846
11869
  const protocolVersion = 9;
@@ -11914,7 +11937,7 @@ const VideoPresets43 = {
11914
11937
  h120: new VideoPreset(160, 120, 70000, 20),
11915
11938
  h180: new VideoPreset(240, 180, 125000, 20),
11916
11939
  h240: new VideoPreset(320, 240, 140000, 20),
11917
- h360: new VideoPreset(480, 360, 225000, 20),
11940
+ h360: new VideoPreset(480, 360, 330000, 20),
11918
11941
  h480: new VideoPreset(640, 480, 500000, 20),
11919
11942
  h540: new VideoPreset(720, 540, 600000, 25),
11920
11943
  h720: new VideoPreset(960, 720, 1300000, 30),
@@ -13212,12 +13235,12 @@ function createAudioAnalyser(track, options) {
13212
13235
  const volume = Math.sqrt(sum / dataArray.length);
13213
13236
  return volume;
13214
13237
  };
13215
- const cleanup = () => {
13216
- audioContext.close();
13238
+ const cleanup = () => __awaiter(this, void 0, void 0, function* () {
13239
+ yield audioContext.close();
13217
13240
  if (opts.cloneTrack) {
13218
13241
  streamTrack.stop();
13219
13242
  }
13220
- };
13243
+ });
13221
13244
  return {
13222
13245
  calculateVolume,
13223
13246
  analyser,
@@ -14039,6 +14062,54 @@ function ratchet(material, salt) {
14039
14062
  return crypto.subtle.deriveBits(algorithmOptions, material, 256);
14040
14063
  });
14041
14064
  }
14065
+ function needsRbspUnescaping(frameData) {
14066
+ for (var i = 0; i < frameData.length - 3; i++) {
14067
+ if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;
14068
+ }
14069
+ return false;
14070
+ }
14071
+ function parseRbsp(stream) {
14072
+ const dataOut = [];
14073
+ var length = stream.length;
14074
+ for (var i = 0; i < stream.length;) {
14075
+ // Be careful about over/underflow here. byte_length_ - 3 can underflow, and
14076
+ // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_
14077
+ // above, and that expression will produce the number of bytes left in
14078
+ // the stream including the byte at i.
14079
+ if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {
14080
+ // Two rbsp bytes.
14081
+ dataOut.push(stream[i++]);
14082
+ dataOut.push(stream[i++]);
14083
+ // Skip the emulation byte.
14084
+ i++;
14085
+ } else {
14086
+ // Single rbsp byte.
14087
+ dataOut.push(stream[i++]);
14088
+ }
14089
+ }
14090
+ return new Uint8Array(dataOut);
14091
+ }
14092
+ const kZerosInStartSequence = 2;
14093
+ const kEmulationByte = 3;
14094
+ function writeRbsp(data_in) {
14095
+ const dataOut = [];
14096
+ var numConsecutiveZeros = 0;
14097
+ for (var i = 0; i < data_in.length; ++i) {
14098
+ var byte = data_in[i];
14099
+ if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {
14100
+ // Need to escape.
14101
+ dataOut.push(kEmulationByte);
14102
+ numConsecutiveZeros = 0;
14103
+ }
14104
+ dataOut.push(byte);
14105
+ if (byte == 0) {
14106
+ ++numConsecutiveZeros;
14107
+ } else {
14108
+ numConsecutiveZeros = 0;
14109
+ }
14110
+ }
14111
+ return new Uint8Array(dataOut);
14112
+ }
14042
14113
 
14043
14114
  /**
14044
14115
  * @experimental
@@ -14552,6 +14623,22 @@ class LocalTrack extends Track {
14552
14623
  }
14553
14624
  });
14554
14625
  }
14626
+ /**
14627
+ * Gets the RTCStatsReport for the LocalTrack's underlying RTCRtpSender
14628
+ * See https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport
14629
+ *
14630
+ * @returns Promise<RTCStatsReport> | undefined
14631
+ */
14632
+ getRTCStatsReport() {
14633
+ var _a;
14634
+ return __awaiter(this, void 0, void 0, function* () {
14635
+ if (!((_a = this.sender) === null || _a === void 0 ? void 0 : _a.getStats)) {
14636
+ return;
14637
+ }
14638
+ const statsReport = yield this.sender.getStats();
14639
+ return statsReport;
14640
+ });
14641
+ }
14555
14642
  /**
14556
14643
  * Sets a processor on this track.
14557
14644
  * See https://github.com/livekit/track-processors-js for example usage
@@ -16336,6 +16423,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16336
16423
  this.subscriber.close();
16337
16424
  this.subscriber = undefined;
16338
16425
  }
16426
+ this.hasPublished = false;
16339
16427
  this.primaryPC = undefined;
16340
16428
  const dcCleanup = dc => {
16341
16429
  if (!dc) return;
@@ -16957,7 +17045,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16957
17045
  });
16958
17046
  }
16959
17047
  waitForPCReconnected() {
16960
- var _a;
17048
+ var _a, _b;
16961
17049
  return __awaiter(this, void 0, void 0, function* () {
16962
17050
  const startTime = Date.now();
16963
17051
  let now = startTime;
@@ -16971,7 +17059,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16971
17059
  // on Safari, we don't get a connectionstatechanged event during ICE restart
16972
17060
  // this means we'd have to check its status manually and update address
16973
17061
  // manually
16974
- now - startTime > minReconnectWait && ((_a = this.primaryPC) === null || _a === void 0 ? void 0 : _a.connectionState) === 'connected') {
17062
+ now - startTime > minReconnectWait && ((_a = this.primaryPC) === null || _a === void 0 ? void 0 : _a.connectionState) === 'connected' && (!this.hasPublished || ((_b = this.publisher) === null || _b === void 0 ? void 0 : _b.pc.connectionState) === 'connected')) {
16975
17063
  this.pcState = PCState.Connected;
16976
17064
  }
16977
17065
  if (this.pcState === PCState.Connected) {
@@ -18364,6 +18452,22 @@ class RemoteTrack extends Track {
18364
18452
  // use `enabled` of track to enable re-use of transceiver
18365
18453
  super.disable();
18366
18454
  }
18455
+ /**
18456
+ * Gets the RTCStatsReport for the RemoteTrack's underlying RTCRtpReceiver
18457
+ * See https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport
18458
+ *
18459
+ * @returns Promise<RTCStatsReport> | undefined
18460
+ */
18461
+ getRTCStatsReport() {
18462
+ var _a;
18463
+ return __awaiter(this, void 0, void 0, function* () {
18464
+ if (!((_a = this.receiver) === null || _a === void 0 ? void 0 : _a.getStats)) {
18465
+ return;
18466
+ }
18467
+ const statsReport = yield this.receiver.getStats();
18468
+ return statsReport;
18469
+ });
18470
+ }
18367
18471
  /* @internal */
18368
18472
  startMonitor() {
18369
18473
  if (!this.monitorInterval) {
@@ -19153,8 +19257,8 @@ class Participant extends eventsExports.EventEmitter {
19153
19257
  }
19154
19258
  this.identity = info.identity;
19155
19259
  this.sid = info.sid;
19156
- this.setName(info.name);
19157
- this.setMetadata(info.metadata);
19260
+ this._setName(info.name);
19261
+ this._setMetadata(info.metadata);
19158
19262
  if (info.permission) {
19159
19263
  this.setPermissions(info.permission);
19160
19264
  }
@@ -19165,8 +19269,10 @@ class Participant extends eventsExports.EventEmitter {
19165
19269
  });
19166
19270
  return true;
19167
19271
  }
19168
- /** @internal */
19169
- setMetadata(md) {
19272
+ /**
19273
+ * Updates metadata from server
19274
+ **/
19275
+ _setMetadata(md) {
19170
19276
  const changed = this.metadata !== md;
19171
19277
  const prevMetadata = this.metadata;
19172
19278
  this.metadata = md;
@@ -19174,7 +19280,7 @@ class Participant extends eventsExports.EventEmitter {
19174
19280
  this.emit(ParticipantEvent.ParticipantMetadataChanged, prevMetadata);
19175
19281
  }
19176
19282
  }
19177
- setName(name) {
19283
+ _setName(name) {
19178
19284
  const changed = this.name !== name;
19179
19285
  this.name = name;
19180
19286
  if (changed) {
@@ -19969,26 +20075,28 @@ class LocalParticipant extends Participant {
19969
20075
  };
19970
20076
  this.engine.client.onSubscribedQualityUpdate = this.handleSubscribedQualityUpdate;
19971
20077
  this.engine.client.onLocalTrackUnpublished = this.handleLocalTrackUnpublished;
19972
- this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.Restarted, this.handleReconnected).on(EngineEvent.Resumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.Disconnected, this.handleDisconnected);
20078
+ this.engine.on(EngineEvent.Connected, this.handleReconnected).on(EngineEvent.SignalRestarted, this.handleReconnected).on(EngineEvent.SignalResumed, this.handleReconnected).on(EngineEvent.Restarting, this.handleReconnecting).on(EngineEvent.Resuming, this.handleReconnecting).on(EngineEvent.Disconnected, this.handleDisconnected);
19973
20079
  }
19974
20080
  /**
19975
20081
  * Sets and updates the metadata of the local participant.
19976
- * Note: this requires `canUpdateOwnMetadata` permission encoded in the token.
20082
+ * The change does not take immediate effect.
20083
+ * If successful, a `ParticipantEvent.MetadataChanged` event will be emitted on the local participant.
20084
+ * Note: this requires `canUpdateOwnMetadata` permission.
19977
20085
  * @param metadata
19978
20086
  */
19979
20087
  setMetadata(metadata) {
19980
20088
  var _a;
19981
- super.setMetadata(metadata);
19982
20089
  this.engine.client.sendUpdateLocalMetadata(metadata, (_a = this.name) !== null && _a !== void 0 ? _a : '');
19983
20090
  }
19984
20091
  /**
19985
20092
  * Sets and updates the name of the local participant.
19986
- * Note: this requires `canUpdateOwnMetadata` permission encoded in the token.
20093
+ * The change does not take immediate effect.
20094
+ * If successful, a `ParticipantEvent.ParticipantNameChanged` event will be emitted on the local participant.
20095
+ * Note: this requires `canUpdateOwnMetadata` permission.
19987
20096
  * @param metadata
19988
20097
  */
19989
20098
  setName(name) {
19990
20099
  var _a;
19991
- super.setName(name);
19992
20100
  this.engine.client.sendUpdateLocalMetadata((_a = this.metadata) !== null && _a !== void 0 ? _a : '', name);
19993
20101
  }
19994
20102
  /**
@@ -20367,7 +20475,7 @@ class LocalParticipant extends Participant {
20367
20475
  disableDtx: !((_a = opts.dtx) !== null && _a !== void 0 ? _a : true),
20368
20476
  encryption: this.encryptionType,
20369
20477
  stereo: isStereo,
20370
- disableRed: !((_b = opts.red) !== null && _b !== void 0 ? _b : true)
20478
+ disableRed: this.isE2EEEnabled || !((_b = opts.red) !== null && _b !== void 0 ? _b : true)
20371
20479
  });
20372
20480
  // compute encodings and layers for video
20373
20481
  let encodings;
@@ -20923,9 +21031,7 @@ class Room extends eventsExports.EventEmitter {
20923
21031
  }
20924
21032
  }
20925
21033
  if (nextUrl) {
20926
- livekitLogger.info('initial connection failed, retrying with another region', {
20927
- nextUrl
20928
- });
21034
+ livekitLogger.info("Initial connection failed with ConnectionError: ".concat(e.message, ". Retrying with another region: ").concat(nextUrl));
20929
21035
  yield connectFn(resolve, reject, nextUrl);
20930
21036
  } else {
20931
21037
  reject(e);
@@ -22876,5 +22982,5 @@ function isFacingModeValue(item) {
22876
22982
  return item === undefined || allowedValues.includes(item);
22877
22983
  }
22878
22984
 
22879
- export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isCodecEqual, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, mimeTypeToVideoCodecString, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs };
22985
+ export { AudioPresets, BaseKeyProvider, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, importKey, isBackupCodec, isBrowserSupported, isCodecEqual, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, mimeTypeToVideoCodecString, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22880
22986
  //# sourceMappingURL=livekit-client.esm.mjs.map