livekit-client 2.0.7 → 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.
@@ -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.7";
13476
+ var version$1 = "2.0.8";
13477
13477
 
13478
13478
  const version = version$1;
13479
13479
  const protocolVersion = 12;
@@ -15037,6 +15037,13 @@ class LocalTrack extends Track {
15037
15037
  const unlock = yield this.processorLock.lock();
15038
15038
  try {
15039
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);
15040
15047
  if (this.processor) {
15041
15048
  yield this.stopProcessor();
15042
15049
  }
@@ -15049,13 +15056,6 @@ class LocalTrack extends Track {
15049
15056
  this.processorElement.play().catch(error => this.log.error('failed to play processor element', Object.assign(Object.assign({}, this.logContext), {
15050
15057
  error
15051
15058
  })));
15052
- const processorOptions = {
15053
- kind: this.kind,
15054
- track: this._mediaStreamTrack,
15055
- element: this.processorElement,
15056
- audioContext: this.audioContext
15057
- };
15058
- yield processor.init(processorOptions);
15059
15059
  this.processor = processor;
15060
15060
  if (this.processor.processedTrack) {
15061
15061
  for (const el of this.attachedElements) {
@@ -15092,7 +15092,10 @@ class LocalTrack extends Track {
15092
15092
  this.processor = undefined;
15093
15093
  (_b = this.processorElement) === null || _b === void 0 ? void 0 : _b.remove();
15094
15094
  this.processorElement = undefined;
15095
- 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);
15096
15099
  this.emit(TrackEvent.TrackProcessorUpdate);
15097
15100
  });
15098
15101
  }
@@ -17032,25 +17035,18 @@ class PCTransport extends eventsExports.EventEmitter {
17032
17035
  if (codecPayload === 0) {
17033
17036
  return true;
17034
17037
  }
17035
- let fmtpFound = false;
17038
+ const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
17036
17039
  for (const fmtp of media.fmtp) {
17037
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
17038
17044
  if (!fmtp.config.includes('x-google-start-bitrate')) {
17039
- fmtp.config += ";x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC));
17045
+ fmtp.config += ";x-google-start-bitrate=".concat(startBitrate);
17040
17046
  }
17041
- if (!fmtp.config.includes('x-google-max-bitrate')) {
17042
- fmtp.config += ";x-google-max-bitrate=".concat(trackbr.maxbr);
17043
- }
17044
- fmtpFound = true;
17045
17047
  break;
17046
17048
  }
17047
17049
  }
17048
- if (!fmtpFound) {
17049
- media.fmtp.push({
17050
- payload: codecPayload,
17051
- config: "x-google-start-bitrate=".concat(Math.round(trackbr.maxbr * startBitrateForSVC), ";x-google-max-bitrate=").concat(trackbr.maxbr)
17052
- });
17053
- }
17054
17050
  return true;
17055
17051
  });
17056
17052
  }
@@ -19086,23 +19082,40 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19086
19082
  }
19087
19083
  const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate, videoEncoding.priority);
19088
19084
  if (scalabilityMode && isSVCCodec(videoCodec)) {
19089
- livekitLogger.debug("using svc with scalabilityMode ".concat(scalabilityMode));
19090
19085
  const sm = new ScalabilityMode(scalabilityMode);
19091
19086
  const encodings = [];
19092
19087
  if (sm.spatial > 3) {
19093
19088
  throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
19094
19089
  }
19095
- 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 {
19096
19109
  encodings.push({
19097
- rid: videoRids[2 - i],
19098
- maxBitrate: videoEncoding.maxBitrate / Math.pow(3, i),
19110
+ maxBitrate: videoEncoding.maxBitrate,
19111
+ maxFramerate: original.encoding.maxFramerate,
19099
19112
  /* @ts-ignore */
19100
- maxFramerate: original.encoding.maxFramerate
19113
+ scalabilityMode: scalabilityMode
19101
19114
  });
19102
19115
  }
19103
- /* @ts-ignore */
19104
- encodings[0].scalabilityMode = scalabilityMode;
19105
- livekitLogger.debug('encodings', encodings);
19116
+ livekitLogger.debug("using svc encoding", {
19117
+ encodings
19118
+ });
19106
19119
  return encodings;
19107
19120
  }
19108
19121
  if (!useSimulcast) {
@@ -19126,7 +19139,7 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
19126
19139
  // to disable when CPU constrained.
19127
19140
  // So encodings should be ordered in increasing spatial
19128
19141
  // resolution order.
19129
- // 2. ion-sfu translates rids into layers. So, all encodings
19142
+ // 2. livekit-server translates rids into layers. So, all encodings
19130
19143
  // should have the base layer `q` and then more added
19131
19144
  // based on other conditions.
19132
19145
  const size = Math.max(width, height);
@@ -21521,8 +21534,10 @@ class LocalParticipant extends Participant {
21521
21534
  // for svc codecs, disable simulcast and use vp8 for backup codec
21522
21535
  if (track instanceof LocalVideoTrack) {
21523
21536
  if (isSVCCodec(videoCodec)) {
21524
- // vp9 svc with screenshare has problem to encode, always use L1T3 here
21525
- 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
21540
+ opts.scalabilityMode = 'L1T3';
21526
21541
  // Chrome does not allow more than 5 fps with L1T3, and it has encoding bugs with L3T3
21527
21542
  // It has a different path for screenshare handling and it seems to be untested/buggy
21528
21543
  // As a workaround, we are setting contentHint to force it to go through the same
@@ -21530,9 +21545,7 @@ class LocalParticipant extends Participant {
21530
21545
  // that we need
21531
21546
  if ('contentHint' in track.mediaStreamTrack) {
21532
21547
  track.mediaStreamTrack.contentHint = 'motion';
21533
- this.log.info('forcing contentHint to motion for screenshare with VP9', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
21534
- } else {
21535
- opts.scalabilityMode = 'L1T3';
21548
+ this.log.info('forcing contentHint to motion for screenshare with SVC codecs', Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
21536
21549
  }
21537
21550
  }
21538
21551
  // set scalabilityMode to 'L3T3_KEY' by default
@@ -21632,7 +21645,8 @@ class LocalParticipant extends Participant {
21632
21645
  maxbr: ((_l = encodings[0]) === null || _l === void 0 ? void 0 : _l.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
21633
21646
  });
21634
21647
  }
21635
- } 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
21636
21650
  this.engine.pcManager.publisher.setTrackCodecBitrate({
21637
21651
  cid: req.cid,
21638
21652
  codec: track.codec,
@@ -21640,6 +21654,19 @@ class LocalParticipant extends Participant {
21640
21654
  });
21641
21655
  }
21642
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
+ }
21643
21670
  yield this.engine.negotiate();
21644
21671
  if (track instanceof LocalVideoTrack) {
21645
21672
  track.startMonitor(this.engine.client);
@@ -24612,5 +24639,5 @@ function isFacingModeValue(item) {
24612
24639
  return item === undefined || allowedValues.includes(item);
24613
24640
  }
24614
24641
 
24615
- 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 };
24616
24643
  //# sourceMappingURL=livekit-client.esm.mjs.map