livekit-client 2.1.3 → 2.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. package/dist/livekit-client.esm.mjs +95 -29
  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/room/PCTransport.d.ts.map +1 -1
  6. package/dist/src/room/Room.d.ts.map +1 -1
  7. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  8. package/dist/src/room/participant/publishUtils.d.ts +1 -0
  9. package/dist/src/room/participant/publishUtils.d.ts.map +1 -1
  10. package/dist/src/room/track/LocalTrack.d.ts +5 -1
  11. package/dist/src/room/track/LocalTrack.d.ts.map +1 -1
  12. package/dist/src/room/track/LocalVideoTrack.d.ts +4 -0
  13. package/dist/src/room/track/LocalVideoTrack.d.ts.map +1 -1
  14. package/dist/src/room/track/RemoteTrack.d.ts.map +1 -1
  15. package/dist/src/room/track/options.d.ts +4 -0
  16. package/dist/src/room/track/options.d.ts.map +1 -1
  17. package/dist/src/room/track/utils.d.ts +1 -0
  18. package/dist/src/room/track/utils.d.ts.map +1 -1
  19. package/dist/src/room/types.d.ts +1 -1
  20. package/dist/src/room/types.d.ts.map +1 -1
  21. package/dist/src/room/utils.d.ts +1 -0
  22. package/dist/src/room/utils.d.ts.map +1 -1
  23. package/dist/ts4.2/src/room/participant/publishUtils.d.ts +1 -0
  24. package/dist/ts4.2/src/room/track/LocalTrack.d.ts +5 -1
  25. package/dist/ts4.2/src/room/track/LocalVideoTrack.d.ts +4 -0
  26. package/dist/ts4.2/src/room/track/options.d.ts +4 -0
  27. package/dist/ts4.2/src/room/track/utils.d.ts +1 -0
  28. package/dist/ts4.2/src/room/types.d.ts +1 -1
  29. package/dist/ts4.2/src/room/utils.d.ts +1 -0
  30. package/package.json +2 -2
  31. package/src/room/PCTransport.ts +10 -7
  32. package/src/room/Room.ts +7 -1
  33. package/src/room/participant/LocalParticipant.ts +7 -16
  34. package/src/room/participant/publishUtils.ts +20 -0
  35. package/src/room/track/LocalTrack.ts +21 -2
  36. package/src/room/track/LocalVideoTrack.ts +27 -0
  37. package/src/room/track/RemoteTrack.ts +4 -1
  38. package/src/room/track/options.ts +5 -0
  39. package/src/room/track/utils.ts +4 -0
  40. package/src/room/types.ts +3 -1
  41. package/src/room/utils.ts +4 -2
@@ -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,7 +10505,7 @@ 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.3";
10508
+ var version$1 = "2.1.5";
10503
10509
 
10504
10510
  const version = version$1;
10505
10511
  const protocolVersion = 13;
@@ -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);
@@ -14098,8 +14122,6 @@ class PCTransport extends eventsExports.EventEmitter {
14098
14122
  if (media.type === 'audio') {
14099
14123
  ensureAudioNackAndStereo(media, [], []);
14100
14124
  } else if (media.type === 'video') {
14101
- ensureVideoDDExtensionForSVC(media);
14102
- // mung sdp for codec bitrate setting that can't apply by sendEncoding
14103
14125
  this.trackBitrates.some(trackbr => {
14104
14126
  if (!media.msid || !trackbr.cid || !media.msid.includes(trackbr.cid)) {
14105
14127
  return false;
@@ -14115,6 +14137,14 @@ class PCTransport extends eventsExports.EventEmitter {
14115
14137
  if (codecPayload === 0) {
14116
14138
  return true;
14117
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
+ }
14118
14148
  const startBitrate = Math.round(trackbr.maxbr * startBitrateForSVC);
14119
14149
  for (const fmtp of media.fmtp) {
14120
14150
  if (fmtp.payload === codecPayload) {
@@ -14331,13 +14361,9 @@ function ensureAudioNackAndStereo(media, stereoMids, nackMids) {
14331
14361
  }
14332
14362
  }
14333
14363
  function ensureVideoDDExtensionForSVC(media) {
14334
- var _a, _b, _c, _d;
14335
- const codec = (_b = (_a = media.rtp[0]) === null || _a === void 0 ? void 0 : _a.codec) === null || _b === void 0 ? void 0 : _b.toLowerCase();
14336
- if (!isSVCCodec(codec)) {
14337
- return;
14338
- }
14364
+ var _a, _b;
14339
14365
  let maxID = 0;
14340
- 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 => {
14341
14367
  if (ext.uri === ddExtensionURI) {
14342
14368
  return true;
14343
14369
  }
@@ -14347,7 +14373,7 @@ function ensureVideoDDExtensionForSVC(media) {
14347
14373
  return false;
14348
14374
  });
14349
14375
  if (!ddFound) {
14350
- (_d = media.ext) === null || _d === void 0 ? void 0 : _d.push({
14376
+ (_b = media.ext) === null || _b === void 0 ? void 0 : _b.push({
14351
14377
  value: maxID + 1,
14352
14378
  uri: ddExtensionURI
14353
14379
  });
@@ -15055,6 +15081,10 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
15055
15081
  scalabilityMode: scalabilityMode
15056
15082
  });
15057
15083
  }
15084
+ if (original.encoding.priority) {
15085
+ encodings[0].priority = original.encoding.priority;
15086
+ encodings[0].networkPriority = original.encoding.priority;
15087
+ }
15058
15088
  livekitLogger.debug("using svc encoding", {
15059
15089
  encodings
15060
15090
  });
@@ -15268,9 +15298,28 @@ class ScalabilityMode {
15268
15298
  return "L".concat(this.spatial, "T").concat(this.temporal).concat((_a = this.suffix) !== null && _a !== void 0 ? _a : '');
15269
15299
  }
15270
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
+ }
15271
15311
 
15272
15312
  const refreshSubscribedCodecAfterNewCodec = 5000;
15273
15313
  class LocalVideoTrack extends LocalTrack {
15314
+ get sender() {
15315
+ return this._sender;
15316
+ }
15317
+ set sender(sender) {
15318
+ this._sender = sender;
15319
+ if (this.degradationPreference) {
15320
+ this.setDegradationPreference(this.degradationPreference);
15321
+ }
15322
+ }
15274
15323
  /**
15275
15324
  *
15276
15325
  * @param mediaTrack
@@ -15283,6 +15332,7 @@ class LocalVideoTrack extends LocalTrack {
15283
15332
  super(mediaTrack, Track.Kind.Video, constraints, userProvidedTrack, loggerOptions);
15284
15333
  /* @internal */
15285
15334
  this.simulcastCodecs = new Map();
15335
+ this.degradationPreference = 'balanced';
15286
15336
  this.monitorSender = () => __awaiter(this, void 0, void 0, function* () {
15287
15337
  if (!this.sender) {
15288
15338
  this._currentBitrate = 0;
@@ -15605,6 +15655,23 @@ class LocalVideoTrack extends LocalTrack {
15605
15655
  }();
15606
15656
  });
15607
15657
  }
15658
+ setDegradationPreference(preference) {
15659
+ return __awaiter(this, void 0, void 0, function* () {
15660
+ this.degradationPreference = preference;
15661
+ if (this.sender) {
15662
+ try {
15663
+ this.log.debug("setting degradationPreference to ".concat(preference), this.logContext);
15664
+ const params = this.sender.getParameters();
15665
+ params.degradationPreference = preference;
15666
+ this.sender.setParameters(params);
15667
+ } catch (e) {
15668
+ this.log.warn("failed to set degradationPreference", Object.assign({
15669
+ error: e
15670
+ }, this.logContext));
15671
+ }
15672
+ }
15673
+ });
15674
+ }
15608
15675
  addSimulcastTrack(codec, encodings) {
15609
15676
  if (this.simulcastCodecs.has(codec)) {
15610
15677
  this.log.error("".concat(codec, " already added, skipping adding simulcast codec"), this.logContext);
@@ -17076,7 +17143,9 @@ class RemoteTrack extends Track {
17076
17143
  if (!this.monitorInterval) {
17077
17144
  this.monitorInterval = setInterval(() => this.monitorReceiver(), monitorFrequency);
17078
17145
  }
17079
- this.registerTimeSyncUpdate();
17146
+ if (supportsSynchronizationSources()) {
17147
+ this.registerTimeSyncUpdate();
17148
+ }
17080
17149
  }
17081
17150
  registerTimeSyncUpdate() {
17082
17151
  const loop = () => {
@@ -18634,7 +18703,7 @@ class LocalParticipant extends Participant {
18634
18703
  }
18635
18704
  publish(track, opts, isStereo) {
18636
18705
  return __awaiter(this, void 0, void 0, function* () {
18637
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
18706
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
18638
18707
  const existingTrackOfSource = Array.from(this.trackPublications.values()).find(publishedTrack => track instanceof LocalTrack && publishedTrack.source === track.source);
18639
18708
  if (existingTrackOfSource && track.source !== Track.Source.Unknown) {
18640
18709
  this.log.info("publishing a second track with the same source: ".concat(track.source), Object.assign(Object.assign({}, this.logContext), getLogContextFromTrack(track)));
@@ -18794,6 +18863,10 @@ class LocalParticipant extends Participant {
18794
18863
  trackInfo: ti
18795
18864
  }));
18796
18865
  track.sender = yield this.engine.createSender(track, opts, encodings);
18866
+ if (track instanceof LocalVideoTrack) {
18867
+ (_l = opts.degradationPreference) !== null && _l !== void 0 ? _l : opts.degradationPreference = getDefaultDegradationPreference(track);
18868
+ track.setDegradationPreference(opts.degradationPreference);
18869
+ }
18797
18870
  if (encodings) {
18798
18871
  if (isFireFox() && track.kind === Track.Kind.Audio) {
18799
18872
  /* Refer to RFC https://datatracker.ietf.org/doc/html/rfc7587#section-6.1,
@@ -18814,11 +18887,10 @@ class LocalParticipant extends Participant {
18814
18887
  this.engine.pcManager.publisher.setTrackCodecBitrate({
18815
18888
  transceiver: trackTransceiver,
18816
18889
  codec: 'opus',
18817
- maxbr: ((_l = encodings[0]) === null || _l === void 0 ? void 0 : _l.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
18890
+ maxbr: ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate) ? encodings[0].maxBitrate / 1000 : 0
18818
18891
  });
18819
18892
  }
18820
- } else if (track.codec && track.codec == 'av1' && ((_m = encodings[0]) === null || _m === void 0 ? void 0 : _m.maxBitrate)) {
18821
- // AV1 requires setting x-start-bitrate in SDP
18893
+ } else if (track.codec && isSVCCodec(track.codec) && ((_o = encodings[0]) === null || _o === void 0 ? void 0 : _o.maxBitrate)) {
18822
18894
  this.engine.pcManager.publisher.setTrackCodecBitrate({
18823
18895
  cid: req.cid,
18824
18896
  codec: track.codec,
@@ -18826,19 +18898,6 @@ class LocalParticipant extends Participant {
18826
18898
  });
18827
18899
  }
18828
18900
  }
18829
- if (track.kind === Track.Kind.Video && track.source === Track.Source.ScreenShare) {
18830
- // a few of reasons we are forcing this setting without allowing overrides:
18831
- // 1. without this, Chrome seems to aggressively resize the SVC video stating `quality-limitation: bandwidth` even when BW isn't an issue
18832
- // 2. since we are overriding contentHint to motion (to workaround L1T3 publishing), it overrides the default degradationPreference to `balanced`
18833
- try {
18834
- this.log.debug("setting degradationPreference to maintain-resolution");
18835
- const params = track.sender.getParameters();
18836
- params.degradationPreference = 'maintain-resolution';
18837
- yield track.sender.setParameters(params);
18838
- } catch (e) {
18839
- this.log.warn("failed to set degradationPreference: ".concat(e));
18840
- }
18841
- }
18842
18901
  yield this.engine.negotiate();
18843
18902
  if (track instanceof LocalVideoTrack) {
18844
18903
  track.startMonitor(this.engine.client);
@@ -20626,6 +20685,13 @@ class Room extends eventsExports.EventEmitter {
20626
20685
  }
20627
20686
  });
20628
20687
  break;
20688
+ case 'leave-full-reconnect':
20689
+ req = new SimulateScenario({
20690
+ scenario: {
20691
+ case: 'leaveRequestFullReconnect',
20692
+ value: true
20693
+ }
20694
+ });
20629
20695
  }
20630
20696
  if (req) {
20631
20697
  yield this.engine.client.sendSimulateScenario(req);