livekit-client 2.1.2 → 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. package/dist/livekit-client.esm.mjs +153 -49
  2. package/dist/livekit-client.esm.mjs.map +1 -1
  3. package/dist/livekit-client.umd.js +1 -1
  4. package/dist/livekit-client.umd.js.map +1 -1
  5. package/dist/src/api/SignalClient.d.ts.map +1 -1
  6. package/dist/src/room/PCTransport.d.ts.map +1 -1
  7. package/dist/src/room/RTCEngine.d.ts.map +1 -1
  8. package/dist/src/room/RegionUrlProvider.d.ts +1 -0
  9. package/dist/src/room/RegionUrlProvider.d.ts.map +1 -1
  10. package/dist/src/room/Room.d.ts.map +1 -1
  11. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  12. package/dist/src/room/participant/publishUtils.d.ts +1 -0
  13. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  14. package/dist/src/room/track/LocalTrack.d.ts +5 -1
  15. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  16. package/dist/src/room/track/LocalVideoTrack.d.ts +3 -0
  17. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  18. package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
  19. package/dist/src/room/track/Track.d.ts +4 -1
  20. package/dist/src/room/track/Track.d.ts.map +1 -1
  21. package/dist/src/room/track/options.d.ts +4 -0
  22. package/dist/src/room/track/options.d.ts.map +1 -1
  23. package/dist/src/room/track/utils.d.ts +1 -0
  24. package/dist/src/room/track/utils.d.ts.map +1 -1
  25. package/dist/src/room/types.d.ts +1 -1
  26. package/dist/src/room/types.d.ts.map +1 -1
  27. package/dist/src/room/utils.d.ts +1 -0
  28. package/dist/src/room/utils.d.ts.map +1 -1
  29. package/dist/src/version.d.ts +1 -1
  30. package/dist/ts4.2/src/room/RegionUrlProvider.d.ts +1 -0
  31. package/dist/ts4.2/src/room/participant/publishUtils.d.ts +1 -0
  32. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +5 -1
  33. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +3 -0
  34. package/dist/ts4.2/src/room/track/Track.d.ts +4 -1
  35. package/dist/ts4.2/src/room/track/options.d.ts +4 -0
  36. package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
  37. package/dist/ts4.2/src/room/types.d.ts +1 -1
  38. package/dist/ts4.2/src/room/utils.d.ts +1 -0
  39. package/dist/ts4.2/src/version.d.ts +1 -1
  40. package/package.json +2 -2
  41. package/src/api/SignalClient.ts +3 -1
  42. package/src/room/PCTransport.ts +10 -7
  43. package/src/room/RTCEngine.ts +47 -10
  44. package/src/room/RegionUrlProvider.ts +5 -0
  45. package/src/room/Room.ts +9 -2
  46. package/src/room/participant/LocalParticipant.ts +7 -16
  47. package/src/room/participant/publishUtils.ts +20 -0
  48. package/src/room/track/LocalTrack.ts +21 -2
  49. package/src/room/track/LocalVideoTrack.ts +23 -0
  50. package/src/room/track/RemoteTrack.ts +11 -5
  51. package/src/room/track/Track.ts +1 -1
  52. package/src/room/track/options.ts +5 -0
  53. package/src/room/track/utils.ts +4 -0
  54. package/src/room/types.ts +3 -1
  55. package/src/room/utils.ts +4 -2
  56. package/src/version.ts +1 -1
@@ -5494,6 +5494,12 @@ const SimulateScenario = /*@__PURE__*/proto3.makeMessageType("livekit.SimulateSc
5494
5494
  kind: "scalar",
5495
5495
  T: 8 /* ScalarType.BOOL */,
5496
5496
  oneof: "scenario"
5497
+ }, {
5498
+ no: 9,
5499
+ name: "leave_request_full_reconnect",
5500
+ kind: "scalar",
5501
+ T: 8 /* ScalarType.BOOL */,
5502
+ oneof: "scenario"
5497
5503
  }]);
5498
5504
 
5499
5505
  /**
@@ -10499,10 +10505,10 @@ function getOSVersion(ua) {
10499
10505
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
10500
10506
  }
10501
10507
 
10502
- var version$1 = "2.1.2";
10508
+ var version$1 = "2.1.4";
10503
10509
 
10504
10510
  const version = version$1;
10505
- const protocolVersion = 12;
10511
+ const protocolVersion = 13;
10506
10512
 
10507
10513
  /**
10508
10514
  * Timers that can be overridden with platform specific implementations
@@ -11203,6 +11209,9 @@ function getLogContextFromTrack(track) {
11203
11209
  };
11204
11210
  }
11205
11211
  }
11212
+ function supportsSynchronizationSources() {
11213
+ return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;
11214
+ }
11206
11215
 
11207
11216
  const separator = '|';
11208
11217
  const ddExtensionURI = 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';
@@ -11575,7 +11584,7 @@ function isVideoCodec(maybeCodec) {
11575
11584
  return videoCodecs.includes(maybeCodec);
11576
11585
  }
11577
11586
  function unwrapConstraint(constraint) {
11578
- if (typeof constraint === 'string') {
11587
+ if (typeof constraint === 'string' || typeof constraint === 'number') {
11579
11588
  return constraint;
11580
11589
  }
11581
11590
  if (Array.isArray(constraint)) {
@@ -11712,6 +11721,14 @@ DeviceManager.userMediaPromiseMap = new Map();
11712
11721
 
11713
11722
  const defaultDimensionsTimeout = 1000;
11714
11723
  class LocalTrack extends Track {
11724
+ /** @internal */
11725
+ get sender() {
11726
+ return this._sender;
11727
+ }
11728
+ /** @internal */
11729
+ set sender(sender) {
11730
+ this._sender = sender;
11731
+ }
11715
11732
  get constraints() {
11716
11733
  return this._constraints;
11717
11734
  }
@@ -11726,6 +11743,7 @@ class LocalTrack extends Track {
11726
11743
  let userProvidedTrack = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
11727
11744
  let loggerOptions = arguments.length > 4 ? arguments[4] : undefined;
11728
11745
  super(mediaTrack, kind, loggerOptions);
11746
+ this.manuallyStopped = false;
11729
11747
  this._isUpstreamPaused = false;
11730
11748
  this.handleTrackMuteEvent = () => this.debouncedTrackMuteHandler().catch(() => this.log.debug('track mute bounce got cancelled by an unmute event', this.logContext));
11731
11749
  this.debouncedTrackMuteHandler = r(() => __awaiter(this, void 0, void 0, function* () {
@@ -11936,6 +11954,7 @@ class LocalTrack extends Track {
11936
11954
  }
11937
11955
  restart(constraints) {
11938
11956
  return __awaiter(this, void 0, void 0, function* () {
11957
+ this.manuallyStopped = false;
11939
11958
  const unlock = yield this.restartLock.lock();
11940
11959
  try {
11941
11960
  if (!constraints) {
@@ -11971,6 +11990,10 @@ class LocalTrack extends Track {
11971
11990
  yield this.setMediaStreamTrack(newTrack);
11972
11991
  this._constraints = constraints;
11973
11992
  this.emit(TrackEvent.Restarted, this);
11993
+ if (this.manuallyStopped) {
11994
+ this.log.warn('track was stopped during a restart, stopping restarted track', this.logContext);
11995
+ this.stop();
11996
+ }
11974
11997
  return this;
11975
11998
  } finally {
11976
11999
  unlock();
@@ -12008,6 +12031,7 @@ class LocalTrack extends Track {
12008
12031
  }
12009
12032
  stop() {
12010
12033
  var _a;
12034
+ this.manuallyStopped = true;
12011
12035
  super.stop();
12012
12036
  this._mediaStreamTrack.removeEventListener('ended', this.handleEnded);
12013
12037
  this._mediaStreamTrack.removeEventListener('mute', this.handleTrackMuteEvent);
@@ -12933,8 +12957,9 @@ class SignalClient {
12933
12957
  return this.sendRequest({
12934
12958
  case: 'leave',
12935
12959
  value: new LeaveRequest({
12936
- canReconnect: false,
12937
- reason: DisconnectReason.CLIENT_INITIATED
12960
+ reason: DisconnectReason.CLIENT_INITIATED,
12961
+ // server doesn't process this field, keeping it here to indicate the intent of a full disconnect
12962
+ action: LeaveRequest_Action.DISCONNECT
12938
12963
  })
12939
12964
  });
12940
12965
  }
@@ -14097,8 +14122,6 @@ class PCTransport extends eventsExports.EventEmitter {
14097
14122
  if (media.type === 'audio') {
14098
14123
  ensureAudioNackAndStereo(media, [], []);
14099
14124
  } else if (media.type === 'video') {
14100
- ensureVideoDDExtensionForSVC(media);
14101
- // mung sdp for codec bitrate setting that can't apply by sendEncoding
14102
14125
  this.trackBitrates.some(trackbr => {
14103
14126
  if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
14104
14127
  return false;
@@ -14114,6 +14137,14 @@ class PCTransport extends eventsExports.EventEmitter {
14114
14137
  if (codecPayload === 0) {
14115
14138
  return true;
14116
14139
  }
14140
+ if (isSVCCodec(trackbr.codec)) {
14141
+ ensureVideoDDExtensionForSVC(media);
14142
+ }
14143
+ // TODO: av1 slow starting issue already fixed in chrome 124, clean this after some versions
14144
+ // mung sdp for av1 bitrate setting that can't apply by sendEncoding
14145
+ if (trackbr.codec !== 'av1') {
14146
+ return true;
14147
+ }
14117
14148
  const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
14118
14149
  for (const fmtp of media.fmtp) {
14119
14150
  if (fmtp.payload === codecPayload) {
@@ -14330,13 +14361,9 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
14330
14361
  }
14331
14362
  }
14332
14363
  function ensureVideoDDExtensionForSVC(media) {
14333
- var _a, _b, _c, _d;
14334
- const codec = (_b = (_a = media.rtp[0]) === null || _a === void 0 ? void 0 : _a.codec) === null || _b === void 0 ? void 0 : _b.toLowerCase();
14335
- if (!isSVCCodec(codec)) {
14336
- return;
14337
- }
14364
+ var _a, _b;
14338
14365
  let maxID = 0;
14339
- const ddFound = (_c = media.ext) === null || _c === void 0 ? void 0 : _c.some(ext => {
14366
+ const ddFound = (_a = media.ext) === null || _a === void 0 ? void 0 : _a.some(ext => {
14340
14367
  if (ext.uri === ddExtensionURI) {
14341
14368
  return true;
14342
14369
  }
@@ -14346,7 +14373,7 @@ function ensureVideoDDExtensionForSVC(media) {
14346
14373
  return false;
14347
14374
  });
14348
14375
  if (!ddFound) {
14349
- (_d = media.ext) === null || _d === void 0 ? void 0 : _d.push({
14376
+ (_b = media.ext) === null || _b === void 0 ? void 0 : _b.push({
14350
14377
  value: maxID + 1,
14351
14378
  uri: ddExtensionURI
14352
14379
  });
@@ -15054,6 +15081,10 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
15054
15081
  scalabilityMode: scalabilityMode
15055
15082
  });
15056
15083
  }
15084
+ if (original.encoding.priority) {
15085
+ encodings[0].priority = original.encoding.priority;
15086
+ encodings[0].networkPriority = original.encoding.priority;
15087
+ }
15057
15088
  livekitLogger.debug("using svc encoding", {
15058
15089
  encodings
15059
15090
  });
@@ -15267,9 +15298,25 @@ class ScalabilityMode {
15267
15298
  return "L".concat(this.spatial, "T").concat(this.temporal).concat((_a = this.suffix) !== null && _a !== void 0 ? _a : '');
15268
15299
  }
15269
15300
  }
15301
+ function getDefaultDegradationPreference(track) {
15302
+ // a few of reasons we have different default paths:
15303
+ // 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
15304
+ // 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
15305
+ if (track.source === Track.Source.ScreenShare || track.constraints.height && unwrapConstraint(track.constraints.height) >= 1080) {
15306
+ return 'maintain-resolution';
15307
+ } else {
15308
+ return 'balanced';
15309
+ }
15310
+ }
15270
15311
 
15271
15312
  const refreshSubscribedCodecAfterNewCodec = 5000;
15272
15313
  class LocalVideoTrack extends LocalTrack {
15314
+ set sender(sender) {
15315
+ this._sender = sender;
15316
+ if (this.degradationPreference) {
15317
+ this.setDegradationPreference(this.degradationPreference);
15318
+ }
15319
+ }
15273
15320
  /**
15274
15321
  *
15275
15322
  * @param mediaTrack
@@ -15282,6 +15329,7 @@ class LocalVideoTrack extends LocalTrack {
15282
15329
  super(mediaTrack, Track.Kind.Video, constraints, userProvidedTrack, loggerOptions);
15283
15330
  /* @internal */
15284
15331
  this.simulcastCodecs = new Map();
15332
+ this.degradationPreference = 'balanced';
15285
15333
  this.monitorSender = () => __awaiter(this, void 0, void 0, function* () {
15286
15334
  if (!this.sender) {
15287
15335
  this._currentBitrate = 0;
@@ -15604,6 +15652,23 @@ class LocalVideoTrack extends LocalTrack {
15604
15652
  }();
15605
15653
  });
15606
15654
  }
15655
+ setDegradationPreference(preference) {
15656
+ return __awaiter(this, void 0, void 0, function* () {
15657
+ this.degradationPreference = preference;
15658
+ if (this.sender) {
15659
+ try {
15660
+ this.log.debug("setting degradationPreference to ".concat(preference), this.logContext);
15661
+ const params = this.sender.getParameters();
15662
+ params.degradationPreference = preference;
15663
+ this.sender.setParameters(params);
15664
+ } catch (e) {
15665
+ this.log.warn("failed to set degradationPreference", Object.assign({
15666
+ error: e
15667
+ }, this.logContext));
15668
+ }
15669
+ }
15670
+ });
15671
+ }
15607
15672
  addSimulcastTrack(codec, encodings) {
15608
15673
  if (this.simulcastCodecs.has(codec)) {
15609
15674
  this.log.error("".concat(codec, " already added, skipping adding simulcast codec"), this.logContext);
@@ -16223,7 +16288,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16223
16288
  }
16224
16289
  configure(joinResponse) {
16225
16290
  return __awaiter(this, void 0, void 0, function* () {
16226
- var _a;
16291
+ var _a, _b;
16227
16292
  // already configured
16228
16293
  if (this.pcManager && this.pcManager.currentState !== PCTransportState.NEW) {
16229
16294
  return;
@@ -16268,7 +16333,9 @@ class RTCEngine extends eventsExports.EventEmitter {
16268
16333
  this.pcManager.onTrack = ev => {
16269
16334
  this.emit(EngineEvent.MediaTrackAdded, ev.track, ev.streams[0], ev.receiver);
16270
16335
  };
16271
- this.createDataChannels();
16336
+ if (!supportOptionalDatachannel((_b = joinResponse.serverInfo) === null || _b === void 0 ? void 0 : _b.protocol)) {
16337
+ this.createDataChannels();
16338
+ }
16272
16339
  });
16273
16340
  }
16274
16341
  setupSignalClientCallbacks() {
@@ -16335,17 +16402,27 @@ class RTCEngine extends eventsExports.EventEmitter {
16335
16402
  this.handleDisconnect('signal', ReconnectReason.RR_SIGNAL_DISCONNECTED);
16336
16403
  };
16337
16404
  this.client.onLeave = leave => {
16338
- if (leave === null || leave === void 0 ? void 0 : leave.canReconnect) {
16339
- this.fullReconnectOnNext = true;
16340
- // reconnect immediately instead of waiting for next attempt
16341
- this.handleDisconnect(leaveReconnect);
16342
- } else {
16343
- this.emit(EngineEvent.Disconnected, leave === null || leave === void 0 ? void 0 : leave.reason);
16344
- this.close();
16345
- }
16346
16405
  this.log.debug('client leave request', Object.assign(Object.assign({}, this.logContext), {
16347
16406
  reason: leave === null || leave === void 0 ? void 0 : leave.reason
16348
16407
  }));
16408
+ if (leave.regions && this.regionUrlProvider) {
16409
+ this.log.debug('updating regions', this.logContext);
16410
+ this.regionUrlProvider.setServerReportedRegions(leave.regions);
16411
+ }
16412
+ switch (leave.action) {
16413
+ case LeaveRequest_Action.DISCONNECT:
16414
+ this.emit(EngineEvent.Disconnected, leave === null || leave === void 0 ? void 0 : leave.reason);
16415
+ this.close();
16416
+ break;
16417
+ case LeaveRequest_Action.RECONNECT:
16418
+ this.fullReconnectOnNext = true;
16419
+ // reconnect immediately instead of waiting for next attempt
16420
+ this.handleDisconnect(leaveReconnect);
16421
+ break;
16422
+ case LeaveRequest_Action.RESUME:
16423
+ // reconnect immediately instead of waiting for next attempt
16424
+ this.handleDisconnect(leaveReconnect);
16425
+ }
16349
16426
  };
16350
16427
  }
16351
16428
  makeRTCConfiguration(serverResponse) {
@@ -16729,7 +16806,15 @@ class RTCEngine extends eventsExports.EventEmitter {
16729
16806
  if (!transport) {
16730
16807
  throw new ConnectionError("".concat(transportName, " connection not set"));
16731
16808
  }
16732
- if (!subscriber && !_this2.pcManager.publisher.isICEConnected && _this2.pcManager.publisher.getICEConnectionState() !== 'checking') {
16809
+ let needNegotiation = false;
16810
+ if (!subscriber && !_this2.dataChannelForKind(kind, subscriber)) {
16811
+ _this2.createDataChannels();
16812
+ needNegotiation = true;
16813
+ }
16814
+ if (!needNegotiation && !subscriber && !_this2.pcManager.publisher.isICEConnected && _this2.pcManager.publisher.getICEConnectionState() !== 'checking') {
16815
+ needNegotiation = true;
16816
+ }
16817
+ if (needNegotiation) {
16733
16818
  // start negotiation
16734
16819
  _this2.negotiate();
16735
16820
  }
@@ -16782,6 +16867,10 @@ class RTCEngine extends eventsExports.EventEmitter {
16782
16867
  return;
16783
16868
  }
16784
16869
  this.pcManager.requirePublisher();
16870
+ // don't negotiate without any transceivers or data channel, it will generate sdp without ice frag then negotiate failed
16871
+ if (this.pcManager.publisher.getTransceivers().length == 0 && !this.lossyDC && !this.reliableDC) {
16872
+ this.createDataChannels();
16873
+ }
16785
16874
  const abortController = new AbortController();
16786
16875
  const handleClosed = () => {
16787
16876
  abortController.abort();
@@ -16922,6 +17011,9 @@ class RTCEngine extends eventsExports.EventEmitter {
16922
17011
  }
16923
17012
  }
16924
17013
  class SignalReconnectError extends Error {}
17014
+ function supportOptionalDatachannel(protocol) {
17015
+ return protocol !== undefined && protocol > 13;
17016
+ }
16925
17017
 
16926
17018
  class RegionUrlProvider {
16927
17019
  constructor(url, token) {
@@ -16980,6 +17072,10 @@ class RegionUrlProvider {
16980
17072
  }
16981
17073
  });
16982
17074
  }
17075
+ setServerReportedRegions(regions) {
17076
+ this.regionSettings = regions;
17077
+ this.lastUpdateAt = Date.now();
17078
+ }
16983
17079
  }
16984
17080
  function getCloudConfigUrl(serverUrl) {
16985
17081
  return "".concat(serverUrl.protocol.replace('ws', 'http'), "//").concat(serverUrl.host, "/settings");
@@ -17044,16 +17140,27 @@ class RemoteTrack extends Track {
17044
17140
  if (!this.monitorInterval) {
17045
17141
  this.monitorInterval = setInterval(() => this.monitorReceiver(), monitorFrequency);
17046
17142
  }
17047
- this.registerTimeSyncUpdate();
17143
+ if (supportsSynchronizationSources()) {
17144
+ this.registerTimeSyncUpdate();
17145
+ }
17048
17146
  }
17049
17147
  registerTimeSyncUpdate() {
17050
17148
  const loop = () => {
17051
- var _a, _b;
17149
+ var _a;
17052
17150
  this.timeSyncHandle = requestAnimationFrame(() => loop());
17053
- const newTime = (_b = (_a = this.receiver) === null || _a === void 0 ? void 0 : _a.getSynchronizationSources()[0]) === null || _b === void 0 ? void 0 : _b.rtpTimestamp;
17054
- if (newTime && this.rtpTimestamp !== newTime) {
17055
- this.emit(TrackEvent.TimeSyncUpdate, newTime);
17056
- this.rtpTimestamp = newTime;
17151
+ const sources = (_a = this.receiver) === null || _a === void 0 ? void 0 : _a.getSynchronizationSources()[0];
17152
+ if (sources) {
17153
+ const {
17154
+ timestamp,
17155
+ rtpTimestamp
17156
+ } = sources;
17157
+ if (rtpTimestamp && this.rtpTimestamp !== rtpTimestamp) {
17158
+ this.emit(TrackEvent.TimeSyncUpdate, {
17159
+ timestamp,
17160
+ rtpTimestamp
17161
+ });
17162
+ this.rtpTimestamp = rtpTimestamp;
17163
+ }
17057
17164
  }
17058
17165
  };
17059
17166
  loop();
@@ -18593,7 +18700,7 @@ class LocalParticipant extends Participant {
18593
18700
  }
18594
18701
  publish(track, opts, isStereo) {
18595
18702
  return __awaiter(this, void 0, void 0, function* () {
18596
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
18703
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
18597
18704
  const existingTrackOfSource = Array.from(this.trackPublications.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
18598
18705
  if (existingTrackOfSource && track.source !== Track.Source.Unknown) {
18599
18706
  this.log.info("publishing a second track with the same source: ".concat(track.source), Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
@@ -18753,6 +18860,10 @@ class LocalParticipant extends Participant {
18753
18860
  trackInfo: ti
18754
18861
  }));
18755
18862
  track.sender = yield this.engine.createSender(track, opts, encodings);
18863
+ if (track instanceof LocalVideoTrack) {
18864
+ (_l = opts.degradationPreference) !== null && _l !== void 0 ? _l : opts.degradationPreference = getDefaultDegradationPreference(track);
18865
+ track.setDegradationPreference(opts.degradationPreference);
18866
+ }
18756
18867
  if (encodings) {
18757
18868
  if (isFireFox() && track.kind === Track.Kind.Audio) {
18758
18869
  /* Refer to RFC https://datatracker.ietf.org/doc/html/rfc7587#section-6.1,
@@ -18773,11 +18884,10 @@ class LocalParticipant extends Participant {
18773
18884
  this.engine.pcManager.publisher.setTrackCodecBitrate({
18774
18885
  transceiver: trackTransceiver,
18775
18886
  codec: 'opus',
18776
- maxbr: ((_l = encodings[0]) === null || _l === void 0 ? void 0 : _l.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
18887
+ maxbr: ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
18777
18888
  });
18778
18889
  }
18779
- } else if (track.codec && track.codec == 'av1' && ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate)) {
18780
- // AV1 requires setting x-start-bitrate in SDP
18890
+ } else if (track.codec && isSVCCodec(track.codec) && ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate)) {
18781
18891
  this.engine.pcManager.publisher.setTrackCodecBitrate({
18782
18892
  cid: req.cid,
18783
18893
  codec: track.codec,
@@ -18785,19 +18895,6 @@ class LocalParticipant extends Participant {
18785
18895
  });
18786
18896
  }
18787
18897
  }
18788
- if (track.kind === Track.Kind.Video && track.source === Track.Source.ScreenShare) {
18789
- // a few of reasons we are forcing this setting without allowing overrides:
18790
- // 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
18791
- // 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
18792
- try {
18793
- this.log.debug("setting degradationPreference to maintain-resolution");
18794
- const params = track.sender.getParameters();
18795
- params.degradationPreference = 'maintain-resolution';
18796
- yield track.sender.setParameters(params);
18797
- } catch (e) {
18798
- this.log.warn("failed to set degradationPreference: ".concat(e));
18799
- }
18800
- }
18801
18898
  yield this.engine.negotiate();
18802
18899
  if (track instanceof LocalVideoTrack) {
18803
18900
  track.startMonitor(this.engine.client);
@@ -20569,7 +20666,7 @@ class Room extends eventsExports.EventEmitter {
20569
20666
  if (onLeave) {
20570
20667
  onLeave(new LeaveRequest({
20571
20668
  reason: DisconnectReason.CLIENT_INITIATED,
20572
- canReconnect: true
20669
+ action: LeaveRequest_Action.RECONNECT
20573
20670
  }));
20574
20671
  }
20575
20672
  });
@@ -20585,6 +20682,13 @@ class Room extends eventsExports.EventEmitter {
20585
20682
  }
20586
20683
  });
20587
20684
  break;
20685
+ case 'leave-full-reconnect':
20686
+ req = new SimulateScenario({
20687
+ scenario: {
20688
+ case: 'leaveRequestFullReconnect',
20689
+ value: true
20690
+ }
20691
+ });
20588
20692
  }
20589
20693
  if (req) {
20590
20694
  yield this.engine.client.sendSimulateScenario(req);