livekit-client 2.1.2 → 2.1.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 (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);