livekit-client 2.0.6 → 2.0.8

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 (34) 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 +27 -3
  4. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  5. package/dist/livekit-client.esm.mjs +74 -35
  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/worker/FrameCryptor.d.ts.map +1 -1
  10. package/dist/src/index.d.ts +7 -6
  11. package/dist/src/index.d.ts.map +1 -1
  12. package/dist/src/room/PCTransport.d.ts.map +1 -1
  13. package/dist/src/room/Room.d.ts.map +1 -1
  14. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  15. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  16. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  17. package/dist/src/room/track/RemoteAudioTrack.d.ts.map +1 -1
  18. package/dist/src/room/track/options.d.ts +6 -0
  19. package/dist/src/room/track/options.d.ts.map +1 -1
  20. package/dist/src/room/track/utils.d.ts.map +1 -1
  21. package/dist/ts4.2/src/index.d.ts +7 -6
  22. package/dist/ts4.2/src/room/track/options.d.ts +6 -0
  23. package/package.json +1 -1
  24. package/src/e2ee/worker/FrameCryptor.ts +12 -0
  25. package/src/e2ee/worker/e2ee.worker.ts +24 -3
  26. package/src/index.ts +32 -29
  27. package/src/room/PCTransport.ts +6 -18
  28. package/src/room/Room.ts +1 -0
  29. package/src/room/participant/LocalParticipant.ts +31 -3
  30. package/src/room/participant/publishUtils.ts +38 -11
  31. package/src/room/track/LocalTrack.ts +11 -9
  32. package/src/room/track/RemoteAudioTrack.ts +1 -1
  33. package/src/room/track/options.ts +7 -0
  34. package/src/room/track/utils.ts +1 -0
@@ -13473,7 +13473,7 @@ function getMatch(exp, ua) {
13473
13473
  return match && match.length >= id && match[id] || '';
13474
13474
  }
13475
13475
 
13476
- var version$1 = "2.0.6";
13476
+ var version$1 = "2.0.8";
13477
13477
 
13478
13478
  const version = version$1;
13479
13479
  const protocolVersion = 12;
@@ -14118,7 +14118,8 @@ function screenCaptureToDisplayMediaStreamOptions(options) {
14118
14118
  controller: options.controller,
14119
14119
  selfBrowserSurface: options.selfBrowserSurface,
14120
14120
  surfaceSwitching: options.surfaceSwitching,
14121
- systemAudio: options.systemAudio
14121
+ systemAudio: options.systemAudio,
14122
+ preferCurrentTab: options.preferCurrentTab
14122
14123
  };
14123
14124
  }
14124
14125
  function mimeTypeToVideoCodecString(mimeType) {
@@ -15036,6 +15037,13 @@ class LocalTrack extends Track {
15036
15037
  const unlock = yield this.processorLock.lock();
15037
15038
  try {
15038
15039
  this.log.debug('setting up processor', this.logContext);
15040
+ const processorOptions = {
15041
+ kind: this.kind,
15042
+ track: this._mediaStreamTrack,
15043
+ element: this.processorElement,
15044
+ audioContext: this.audioContext
15045
+ };
15046
+ yield processor.init(processorOptions);
15039
15047
  if (this.processor) {
15040
15048
  yield this.stopProcessor();
15041
15049
  }
@@ -15048,13 +15056,6 @@ class LocalTrack extends Track {
15048
15056
  this.processorElement.play().catch(error => this.log.error('failed to play processor element', Object.assign(Object.assign({}, this.logContext), {
15049
15057
  error
15050
15058
  })));
15051
- const processorOptions = {
15052
- kind: this.kind,
15053
- track: this._mediaStreamTrack,
15054
- element: this.processorElement,
15055
- audioContext: this.audioContext
15056
- };
15057
- yield processor.init(processorOptions);
15058
15059
  this.processor = processor;
15059
15060
  if (this.processor.processedTrack) {
15060
15061
  for (const el of this.attachedElements) {
@@ -15091,7 +15092,10 @@ class LocalTrack extends Track {
15091
15092
  this.processor = undefined;
15092
15093
  (_b = this.processorElement) === null || _b === void 0 ? void 0 : _b.remove();
15093
15094
  this.processorElement = undefined;
15094
- yield this.restart();
15095
+ // apply original track constraints in case the processor changed them
15096
+ yield this._mediaStreamTrack.applyConstraints(this._constraints);
15097
+ // force re-setting of the mediaStreamTrack on the sender
15098
+ yield this.setMediaStreamTrack(this._mediaStreamTrack, true);
15095
15099
  this.emit(TrackEvent.TrackProcessorUpdate);
15096
15100
  });
15097
15101
  }
@@ -17031,25 +17035,18 @@ class PCTransport extends eventsExports.EventEmitter {
17031
17035
  if (codecPayload === 0) {
17032
17036
  return true;
17033
17037
  }
17034
- let fmtpFound = false;
17038
+ const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
17035
17039
  for (const fmtp of media.fmtp) {
17036
17040
  if (fmtp.payload === codecPayload) {
17041
+ // if another track's fmtp already is set, we cannot override the bitrate
17042
+ // this has the unfortunate consequence of being forced to use the
17043
+ // initial track's bitrate for all tracks
17037
17044
  if (!fmtp.config.includes('x-google-start-bitrate')) {
17038
- fmtp.config += ";x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC));
17045
+ fmtp.config += ";x-google-start-bitrate=".concat(startBitrate);
17039
17046
  }
17040
- if (!fmtp.config.includes('x-google-max-bitrate')) {
17041
- fmtp.config += ";x-google-max-bitrate=".concat(trackbr.maxbr);
17042
- }
17043
- fmtpFound = true;
17044
17047
  break;
17045
17048
  }
17046
17049
  }
17047
- if (!fmtpFound) {
17048
- media.fmtp.push({
17049
- payload: codecPayload,
17050
- config: "x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC), ";x-google-max-bitrate=").concat(trackbr.maxbr)
17051
- });
17052
- }
17053
17050
  return true;
17054
17051
  });
17055
17052
  }
@@ -19085,23 +19082,40 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19085
19082
  }
19086
19083
  const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate, videoEncoding.priority);
19087
19084
  if (scalabilityMode && isSVCCodec(videoCodec)) {
19088
- livekitLogger.debug("using svc with scalabilityMode ".concat(scalabilityMode));
19089
19085
  const sm = new ScalabilityMode(scalabilityMode);
19090
19086
  const encodings = [];
19091
19087
  if (sm.spatial > 3) {
19092
19088
  throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
19093
19089
  }
19094
- for (let i = 0; i < sm.spatial; i += 1) {
19090
+ // Before M113 in Chrome, defining multiple encodings with an SVC codec indicated
19091
+ // that SVC mode should be used. Safari still works this way.
19092
+ // This is a bit confusing but is due to how libwebrtc interpreted the encodings field
19093
+ // before M113.
19094
+ // Announced here: https://groups.google.com/g/discuss-webrtc/c/-QQ3pxrl-fw?pli=1
19095
+ const browser = getBrowser();
19096
+ if (isSafari() || (browser === null || browser === void 0 ? void 0 : browser.name) === 'Chrome' && compareVersions(browser === null || browser === void 0 ? void 0 : browser.version, '113') < 0) {
19097
+ for (let i = 0; i < sm.spatial; i += 1) {
19098
+ // in legacy SVC, scaleResolutionDownBy cannot be set
19099
+ encodings.push({
19100
+ rid: videoRids[2 - i],
19101
+ maxBitrate: videoEncoding.maxBitrate / Math.pow(3, i),
19102
+ maxFramerate: original.encoding.maxFramerate
19103
+ });
19104
+ }
19105
+ // legacy SVC, scalabilityMode is set only on the first encoding
19106
+ /* @ts-ignore */
19107
+ encodings[0].scalabilityMode = scalabilityMode;
19108
+ } else {
19095
19109
  encodings.push({
19096
- rid: videoRids[2 - i],
19097
- maxBitrate: videoEncoding.maxBitrate / Math.pow(3, i),
19110
+ maxBitrate: videoEncoding.maxBitrate,
19111
+ maxFramerate: original.encoding.maxFramerate,
19098
19112
  /* @ts-ignore */
19099
- maxFramerate: original.encoding.maxFramerate
19113
+ scalabilityMode: scalabilityMode
19100
19114
  });
19101
19115
  }
19102
- /* @ts-ignore */
19103
- encodings[0].scalabilityMode = scalabilityMode;
19104
- livekitLogger.debug('encodings', encodings);
19116
+ livekitLogger.debug("using svc encoding", {
19117
+ encodings
19118
+ });
19105
19119
  return encodings;
19106
19120
  }
19107
19121
  if (!useSimulcast) {
@@ -19125,7 +19139,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19125
19139
  // to disable when CPU constrained.
19126
19140
  // So encodings should be ordered in increasing spatial
19127
19141
  // resolution order.
19128
- // 2. ion-sfu translates rids into layers. So, all encodings
19142
+ // 2. livekit-server translates rids into layers. So, all encodings
19129
19143
  // should have the base layer `q` and then more added
19130
19144
  // based on other conditions.
19131
19145
  const size = Math.max(width, height);
@@ -21520,9 +21534,19 @@ class LocalParticipant extends Participant {
21520
21534
  // for svc codecs, disable simulcast and use vp8 for backup codec
21521
21535
  if (track instanceof LocalVideoTrack) {
21522
21536
  if (isSVCCodec(videoCodec)) {
21523
- // vp9 svc with screenshare has problem to encode, always use L1T3 here
21524
- if (track.source === Track.Source.ScreenShare && videoCodec === 'vp9') {
21537
+ if (track.source === Track.Source.ScreenShare) {
21538
+ // vp9 svc with screenshare cannot encode multiple spatial layers
21539
+ // doing so reduces publish resolution to minimal resolution
21525
21540
  opts.scalabilityMode = 'L1T3';
21541
+ // Chrome does not allow more than 5 fps with L1T3, and it has encoding bugs with L3T3
21542
+ // It has a different path for screenshare handling and it seems to be untested/buggy
21543
+ // As a workaround, we are setting contentHint to force it to go through the same
21544
+ // path as regular camera video. While this is not optimal, it delivers the performance
21545
+ // that we need
21546
+ if ('contentHint' in track.mediaStreamTrack) {
21547
+ track.mediaStreamTrack.contentHint = 'motion';
21548
+ this.log.info('forcing contentHint to motion for screenshare with SVC codecs', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
21549
+ }
21526
21550
  }
21527
21551
  // set scalabilityMode to 'L3T3_KEY' by default
21528
21552
  opts.scalabilityMode = (_e = opts.scalabilityMode) !== null && _e !== void 0 ? _e : 'L3T3_KEY';
@@ -21621,7 +21645,8 @@ class LocalParticipant extends Participant {
21621
21645
  maxbr: ((_l = encodings[0]) === null || _l === void 0 ? void 0 : _l.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
21622
21646
  });
21623
21647
  }
21624
- } else if (track.codec && isSVCCodec(track.codec) && ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate)) {
21648
+ } else if (track.codec && track.codec == 'av1' && ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate)) {
21649
+ // AV1 requires setting x-start-bitrate in SDP
21625
21650
  this.engine.pcManager.publisher.setTrackCodecBitrate({
21626
21651
  cid: req.cid,
21627
21652
  codec: track.codec,
@@ -21629,6 +21654,19 @@ class LocalParticipant extends Participant {
21629
21654
  });
21630
21655
  }
21631
21656
  }
21657
+ if (track.kind === Track.Kind.Video && track.source === Track.Source.ScreenShare) {
21658
+ // a few of reasons we are forcing this setting without allowing overrides:
21659
+ // 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
21660
+ // 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
21661
+ try {
21662
+ this.log.debug("setting degradationPreference to maintain-resolution");
21663
+ const params = track.sender.getParameters();
21664
+ params.degradationPreference = 'maintain-resolution';
21665
+ yield track.sender.setParameters(params);
21666
+ } catch (e) {
21667
+ this.log.warn("failed to set degradationPreference: ".concat(e));
21668
+ }
21669
+ }
21632
21670
  yield this.engine.negotiate();
21633
21671
  if (track instanceof LocalVideoTrack) {
21634
21672
  track.startMonitor(this.engine.client);
@@ -22524,6 +22562,7 @@ class Room extends eventsExports.EventEmitter {
22524
22562
  }
22525
22563
  if (nextUrl) {
22526
22564
  this.log.info("Initial connection failed with ConnectionError: ".concat(e.message, ". Retrying with another region: ").concat(nextUrl), this.logContext);
22565
+ this.recreateEngine();
22527
22566
  yield connectFn(resolve, reject, nextUrl);
22528
22567
  } else {
22529
22568
  this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
@@ -24600,5 +24639,5 @@ function isFacingModeValue(item) {
24600
24639
  return item === undefined || allowedValues.includes(item);
24601
24640
  }
24602
24641
 
24603
- 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, LoggerNames, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, 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, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
24642
+ 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, LoggerNames, MediaDeviceFailure, NegotiationError, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
24604
24643
  //# sourceMappingURL=livekit-client.esm.mjs.map