livekit-client 2.15.5 → 2.15.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/livekit-client.e2ee.worker.js +1 -1
  2. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  3. package/dist/livekit-client.e2ee.worker.mjs +54 -50
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +62 -16
  6. package/dist/livekit-client.esm.mjs.map +1 -1
  7. package/dist/livekit-client.umd.js +1 -1
  8. package/dist/livekit-client.umd.js.map +1 -1
  9. package/dist/src/e2ee/E2eeManager.d.ts.map +1 -1
  10. package/dist/src/e2ee/worker/FrameCryptor.d.ts +0 -1
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  12. package/dist/src/e2ee/worker/sifPayload.d.ts +22 -0
  13. package/dist/src/e2ee/worker/sifPayload.d.ts.map +1 -0
  14. package/dist/src/room/Room.d.ts.map +1 -1
  15. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  16. package/dist/src/room/track/RemoteVideoTrack.d.ts +1 -0
  17. package/dist/src/room/track/RemoteVideoTrack.d.ts.map +1 -1
  18. package/dist/src/room/track/Track.d.ts +4 -1
  19. package/dist/src/room/track/Track.d.ts.map +1 -1
  20. package/dist/src/room/utils.d.ts +8 -0
  21. package/dist/src/room/utils.d.ts.map +1 -1
  22. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +0 -1
  23. package/dist/ts4.2/src/e2ee/worker/sifPayload.d.ts +22 -0
  24. package/dist/ts4.2/src/room/track/RemoteVideoTrack.d.ts +1 -0
  25. package/dist/ts4.2/src/room/track/Track.d.ts +4 -1
  26. package/dist/ts4.2/src/room/utils.d.ts +8 -0
  27. package/package.json +7 -7
  28. package/src/e2ee/E2eeManager.ts +18 -1
  29. package/src/e2ee/worker/FrameCryptor.ts +8 -18
  30. package/src/e2ee/worker/e2ee.worker.ts +6 -1
  31. package/src/e2ee/worker/sifPayload.ts +75 -0
  32. package/src/room/Room.ts +11 -2
  33. package/src/room/track/LocalTrack.ts +5 -2
  34. package/src/room/track/RemoteVideoTrack.ts +12 -2
  35. package/src/room/track/Track.ts +10 -1
  36. package/src/room/utils.ts +12 -3
  37. package/dist/src/e2ee/worker/SifGuard.d.ts +0 -11
  38. package/dist/src/e2ee/worker/SifGuard.d.ts.map +0 -1
  39. package/dist/ts4.2/src/e2ee/worker/SifGuard.d.ts +0 -11
  40. package/src/e2ee/worker/SifGuard.ts +0 -47
@@ -11388,7 +11388,7 @@ function getOSVersion(ua) {
11388
11388
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
11389
11389
  }
11390
11390
 
11391
- var version$1 = "2.15.5";
11391
+ var version$1 = "2.15.6";
11392
11392
 
11393
11393
  const version = version$1;
11394
11394
  const protocolVersion = 16;
@@ -11425,17 +11425,24 @@ var VideoQuality;
11425
11425
  VideoQuality[VideoQuality["HIGH"] = 2] = "HIGH";
11426
11426
  })(VideoQuality || (VideoQuality = {}));
11427
11427
  class Track extends eventsExports.EventEmitter {
11428
+ /**
11429
+ * indicates current state of stream, it'll indicate `paused` if the track
11430
+ * has been paused by congestion controller
11431
+ */
11432
+ get streamState() {
11433
+ return this._streamState;
11434
+ }
11435
+ /** @internal */
11436
+ setStreamState(value) {
11437
+ this._streamState = value;
11438
+ }
11428
11439
  constructor(mediaTrack, kind) {
11429
11440
  let loggerOptions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
11430
11441
  var _a;
11431
11442
  super();
11432
11443
  this.attachedElements = [];
11433
11444
  this.isMuted = false;
11434
- /**
11435
- * indicates current state of stream, it'll indicate `paused` if the track
11436
- * has been paused by congestion controller
11437
- */
11438
- this.streamState = Track.StreamState.Active;
11445
+ this._streamState = Track.StreamState.Active;
11439
11446
  this.isInBackground = false;
11440
11447
  this._currentBitrate = 0;
11441
11448
  this.log = livekitLogger;
@@ -11928,8 +11935,9 @@ function supportsAV1() {
11928
11935
  if (!('getCapabilities' in RTCRtpSender)) {
11929
11936
  return false;
11930
11937
  }
11931
- if (isSafari()) {
11938
+ if (isSafari() || isFireFox()) {
11932
11939
  // Safari 17 on iPhone14 reports AV1 capability, but does not actually support it
11940
+ // Firefox does support AV1, but SVC publishing is not supported
11933
11941
  return false;
11934
11942
  }
11935
11943
  const capabilities = RTCRtpSender.getCapabilities('video');
@@ -12031,9 +12039,9 @@ function isE2EESimulcastSupported() {
12031
12039
  if (browser) {
12032
12040
  if (browser.name !== 'Safari' && browser.os !== 'iOS') {
12033
12041
  return true;
12034
- } else if (browser.os === 'iOS' && browser.osVersion && compareVersions(supportedSafariVersion, browser.osVersion) >= 0) {
12042
+ } else if (browser.os === 'iOS' && browser.osVersion && compareVersions(browser.osVersion, supportedSafariVersion) >= 0) {
12035
12043
  return true;
12036
- } else if (browser.name === 'Safari' && compareVersions(supportedSafariVersion, browser.version) >= 0) {
12044
+ } else if (browser.name === 'Safari' && compareVersions(browser.version, supportedSafariVersion) >= 0) {
12037
12045
  return true;
12038
12046
  } else {
12039
12047
  return false;
@@ -12081,6 +12089,14 @@ function getDevicePixelRatio() {
12081
12089
  }
12082
12090
  return 1;
12083
12091
  }
12092
+ /**
12093
+ * @param v1 - The first version string to compare.
12094
+ * @param v2 - The second version string to compare.
12095
+ * @returns A number indicating the order of the versions:
12096
+ * - 1 if v1 is greater than v2
12097
+ * - -1 if v1 is less than v2
12098
+ * - 0 if v1 and v2 are equal
12099
+ */
12084
12100
  function compareVersions(v1, v2) {
12085
12101
  const parts1 = v1.split('.');
12086
12102
  const parts2 = v2.split('.');
@@ -12875,6 +12891,21 @@ class E2EEManager extends eventsExports.EventEmitter {
12875
12891
  room.localParticipant.on(ParticipantEvent.LocalSenderCreated, (sender, track) => __awaiter(this, void 0, void 0, function* () {
12876
12892
  this.setupE2EESender(track, sender);
12877
12893
  }));
12894
+ room.localParticipant.on(ParticipantEvent.LocalTrackPublished, publication => {
12895
+ // Safari doesn't support retrieving payload information on RTCEncodedVideoFrame, so we need to update the codec manually once we have the trackInfo from the server
12896
+ if (!isVideoTrack(publication.track) || !isSafariBased()) {
12897
+ return;
12898
+ }
12899
+ const msg = {
12900
+ kind: 'updateCodec',
12901
+ data: {
12902
+ trackId: publication.track.mediaStreamID,
12903
+ codec: mimeTypeToVideoCodecString(publication.trackInfo.codecs[0].mimeType),
12904
+ participantIdentity: this.room.localParticipant.identity
12905
+ }
12906
+ };
12907
+ this.worker.postMessage(msg);
12908
+ });
12878
12909
  keyProvider.on(KeyProviderEvent.SetKey, keyInfo => this.postKey(keyInfo)).on(KeyProviderEvent.RatchetRequest, (participantId, keyIndex) => this.postRatchetRequest(participantId, keyIndex));
12879
12910
  }
12880
12911
  postRatchetRequest(participantIdentity, keyIndex) {
@@ -16203,9 +16234,9 @@ class LocalTrack extends Track {
16203
16234
  facingMode
16204
16235
  } : true;
16205
16236
  } else {
16206
- streamConstraints.audio = deviceId ? {
16237
+ streamConstraints.audio = deviceId ? Object.assign({
16207
16238
  deviceId
16208
- } : true;
16239
+ }, otherConstraints) : true;
16209
16240
  }
16210
16241
  // these steps are duplicated from setMediaStreamTrack because we must stop
16211
16242
  // the previous tracks before new tracks can be acquired
@@ -16220,7 +16251,10 @@ class LocalTrack extends Track {
16220
16251
  // create new track and attach
16221
16252
  const mediaStream = yield navigator.mediaDevices.getUserMedia(streamConstraints);
16222
16253
  const newTrack = mediaStream.getTracks()[0];
16223
- yield newTrack.applyConstraints(otherConstraints);
16254
+ if (this.kind === Track.Kind.Video) {
16255
+ // we already captured the audio track with the constraints, so we only need to apply the video constraints
16256
+ yield newTrack.applyConstraints(otherConstraints);
16257
+ }
16224
16258
  newTrack.addEventListener('ended', this.handleEnded);
16225
16259
  this.log.debug('re-acquired MediaStreamTrack', this.logContext);
16226
16260
  yield this.setMediaStreamTrack(newTrack);
@@ -20155,6 +20189,15 @@ class RemoteVideoTrack extends RemoteTrack {
20155
20189
  get isAdaptiveStream() {
20156
20190
  return this.adaptiveStreamSettings !== undefined;
20157
20191
  }
20192
+ setStreamState(value) {
20193
+ super.setStreamState(value);
20194
+ console.log('setStreamState', value);
20195
+ if (value === Track.StreamState.Active) {
20196
+ // update visibility for adaptive stream tracks when stream state received from server is active
20197
+ // this is needed to ensure the track is stopped when there's no element attached to it at all
20198
+ this.updateVisibility();
20199
+ }
20200
+ }
20158
20201
  /**
20159
20202
  * Note: When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
20160
20203
  */
@@ -20304,14 +20347,14 @@ class RemoteVideoTrack extends RemoteTrack {
20304
20347
  this.updateVisibility();
20305
20348
  });
20306
20349
  }
20307
- updateVisibility() {
20350
+ updateVisibility(forceEmit) {
20308
20351
  var _a, _b;
20309
20352
  const lastVisibilityChange = this.elementInfos.reduce((prev, info) => Math.max(prev, info.visibilityChangedAt || 0), 0);
20310
20353
  const backgroundPause = ((_b = (_a = this.adaptiveStreamSettings) === null || _a === void 0 ? void 0 : _a.pauseVideoInBackground) !== null && _b !== void 0 ? _b : true // default to true
20311
20354
  ) ? this.isInBackground : false;
20312
20355
  const isPiPMode = this.elementInfos.some(info => info.pictureInPicture);
20313
20356
  const isVisible = this.elementInfos.some(info => info.visible) && !backgroundPause || isPiPMode;
20314
- if (this.lastVisible === isVisible) {
20357
+ if (this.lastVisible === isVisible && !forceEmit) {
20315
20358
  return;
20316
20359
  }
20317
20360
  if (!isVisible && Date.now() - lastVisibilityChange < REACTION_DELAY) {
@@ -23938,8 +23981,8 @@ class Room extends eventsExports.EventEmitter {
23938
23981
  return;
23939
23982
  }
23940
23983
  const newStreamState = Track.streamStateFromProto(streamState.state);
23984
+ pub.track.setStreamState(newStreamState);
23941
23985
  if (newStreamState !== pub.track.streamState) {
23942
- pub.track.streamState = newStreamState;
23943
23986
  participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
23944
23987
  this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
23945
23988
  }
@@ -24765,7 +24808,10 @@ class Room extends eventsExports.EventEmitter {
24765
24808
  adaptiveStreamSettings = {};
24766
24809
  }
24767
24810
  }
24768
- participant.addSubscribedMediaTrack(mediaTrack, trackId, stream, receiver, adaptiveStreamSettings);
24811
+ const publication = participant.addSubscribedMediaTrack(mediaTrack, trackId, stream, receiver, adaptiveStreamSettings);
24812
+ if ((publication === null || publication === void 0 ? void 0 : publication.isEncrypted) && !this.e2eeManager) {
24813
+ this.emit(RoomEvent.EncryptionError, new Error("Encrypted ".concat(publication.source, " track received from participant ").concat(participant.sid, ", but room does not have encryption enabled!")));
24814
+ }
24769
24815
  }
24770
24816
  handleDisconnect() {
24771
24817
  let shouldStopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;