livekit-client 0.18.4 → 0.18.5

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.
@@ -9783,7 +9783,7 @@ class DeviceManager {
9783
9783
  }
9784
9784
  DeviceManager.mediaDeviceKinds = ['audioinput', 'audiooutput', 'videoinput'];
9785
9785
 
9786
- const version = '0.18.4';
9786
+ const version = '0.18.5';
9787
9787
  const protocolVersion = 7;
9788
9788
 
9789
9789
  const separator = '|';
@@ -10351,7 +10351,7 @@ class Track extends events.exports.EventEmitter {
10351
10351
  };
10352
10352
 
10353
10353
  this.kind = kind;
10354
- this.mediaStreamTrack = mediaTrack;
10354
+ this._mediaStreamTrack = mediaTrack;
10355
10355
  this.source = Track.Source.Unknown;
10356
10356
 
10357
10357
  if (isWeb()) {
@@ -10368,6 +10368,10 @@ class Track extends events.exports.EventEmitter {
10368
10368
  return this._currentBitrate;
10369
10369
  }
10370
10370
 
10371
+ get mediaStreamTrack() {
10372
+ return this._mediaStreamTrack;
10373
+ }
10374
+
10371
10375
  attach(element) {
10372
10376
  let elementType = 'audio';
10373
10377
 
@@ -10401,7 +10405,7 @@ class Track extends events.exports.EventEmitter {
10401
10405
  // we'll want to re-attach it in that case
10402
10406
 
10403
10407
 
10404
- attachToElement(this.mediaStreamTrack, element);
10408
+ attachToElement(this._mediaStreamTrack, element);
10405
10409
 
10406
10410
  if (element instanceof HTMLAudioElement) {
10407
10411
  // manually play audio to detect audio playback status
@@ -10419,7 +10423,7 @@ class Track extends events.exports.EventEmitter {
10419
10423
  detach(element) {
10420
10424
  // detach from a single element
10421
10425
  if (element) {
10422
- detachTrack(this.mediaStreamTrack, element);
10426
+ detachTrack(this._mediaStreamTrack, element);
10423
10427
  const idx = this.attachedElements.indexOf(element);
10424
10428
 
10425
10429
  if (idx >= 0) {
@@ -10433,7 +10437,7 @@ class Track extends events.exports.EventEmitter {
10433
10437
 
10434
10438
  const detached = [];
10435
10439
  this.attachedElements.forEach(elm => {
10436
- detachTrack(this.mediaStreamTrack, elm);
10440
+ detachTrack(this._mediaStreamTrack, elm);
10437
10441
  detached.push(elm);
10438
10442
  this.recycleElement(elm);
10439
10443
  this.emit(TrackEvent.ElementDetached, elm);
@@ -10444,7 +10448,7 @@ class Track extends events.exports.EventEmitter {
10444
10448
  }
10445
10449
 
10446
10450
  stop() {
10447
- this.mediaStreamTrack.stop();
10451
+ this._mediaStreamTrack.stop();
10448
10452
 
10449
10453
  if (isWeb()) {
10450
10454
  document.removeEventListener('visibilitychange', this.appVisibilityChangedListener);
@@ -10452,11 +10456,11 @@ class Track extends events.exports.EventEmitter {
10452
10456
  }
10453
10457
 
10454
10458
  enable() {
10455
- this.mediaStreamTrack.enabled = true;
10459
+ this._mediaStreamTrack.enabled = true;
10456
10460
  }
10457
10461
 
10458
10462
  disable() {
10459
- this.mediaStreamTrack.enabled = false;
10463
+ this._mediaStreamTrack.enabled = false;
10460
10464
  }
10461
10465
 
10462
10466
  recycleElement(element) {
@@ -10686,14 +10690,15 @@ class LocalTrack extends Track {
10686
10690
  this.emit(TrackEvent.Ended, this);
10687
10691
  };
10688
10692
 
10689
- this.mediaStreamTrack.addEventListener('ended', this.handleEnded);
10693
+ this._mediaStreamTrack.addEventListener('ended', this.handleEnded);
10694
+
10690
10695
  this.constraints = constraints !== null && constraints !== void 0 ? constraints : mediaTrack.getConstraints();
10691
10696
  this.reacquireTrack = false;
10692
10697
  this.wasMuted = false;
10693
10698
  }
10694
10699
 
10695
10700
  get id() {
10696
- return this.mediaStreamTrack.id;
10701
+ return this._mediaStreamTrack.id;
10697
10702
  }
10698
10703
 
10699
10704
  get dimensions() {
@@ -10704,7 +10709,7 @@ class LocalTrack extends Track {
10704
10709
  const {
10705
10710
  width,
10706
10711
  height
10707
- } = this.mediaStreamTrack.getSettings();
10712
+ } = this._mediaStreamTrack.getSettings();
10708
10713
 
10709
10714
  if (width && height) {
10710
10715
  return {
@@ -10733,7 +10738,8 @@ class LocalTrack extends Track {
10733
10738
  const {
10734
10739
  deviceId,
10735
10740
  groupId
10736
- } = this.mediaStreamTrack.getSettings();
10741
+ } = this._mediaStreamTrack.getSettings();
10742
+
10737
10743
  const kind = this.kind === Track.Kind.Audio ? 'audioinput' : 'videoinput';
10738
10744
  return DeviceManager.getInstance().normalizeDeviceId(kind, deviceId, groupId);
10739
10745
  }
@@ -10755,17 +10761,20 @@ class LocalTrack extends Track {
10755
10761
 
10756
10762
 
10757
10763
  this.attachedElements.forEach(el => {
10758
- detachTrack(this.mediaStreamTrack, el);
10764
+ detachTrack(this._mediaStreamTrack, el);
10759
10765
  });
10760
- this.mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10766
+
10767
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10761
10768
  // the new track, otherwise the new track will stop with
10762
10769
  // 'A MediaStreamTrack ended due to a capture failure`
10763
10770
 
10764
- this.mediaStreamTrack.stop();
10771
+
10772
+ this._mediaStreamTrack.stop();
10773
+
10765
10774
  track.addEventListener('ended', this.handleEnded);
10766
10775
  livekitLogger.debug('replace MediaStreamTrack');
10767
10776
  await this.sender.replaceTrack(track);
10768
- this.mediaStreamTrack = track;
10777
+ this._mediaStreamTrack = track;
10769
10778
  this.attachedElements.forEach(el => {
10770
10779
  attachToElement(track, el);
10771
10780
  });
@@ -10796,20 +10805,23 @@ class LocalTrack extends Track {
10796
10805
 
10797
10806
 
10798
10807
  this.attachedElements.forEach(el => {
10799
- detachTrack(this.mediaStreamTrack, el);
10808
+ detachTrack(this._mediaStreamTrack, el);
10800
10809
  });
10801
- this.mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10810
+
10811
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10802
10812
  // the new track, otherwise the new track will stop with
10803
10813
  // 'A MediaStreamTrack ended due to a capture failure`
10804
10814
 
10805
- this.mediaStreamTrack.stop(); // create new track and attach
10815
+
10816
+ this._mediaStreamTrack.stop(); // create new track and attach
10817
+
10806
10818
 
10807
10819
  const mediaStream = await navigator.mediaDevices.getUserMedia(streamConstraints);
10808
10820
  const newTrack = mediaStream.getTracks()[0];
10809
10821
  newTrack.addEventListener('ended', this.handleEnded);
10810
10822
  livekitLogger.debug('re-acquired MediaStreamTrack');
10811
10823
  await this.sender.replaceTrack(newTrack);
10812
- this.mediaStreamTrack = newTrack;
10824
+ this._mediaStreamTrack = newTrack;
10813
10825
  this.attachedElements.forEach(el => {
10814
10826
  attachToElement(newTrack, el);
10815
10827
  });
@@ -10824,12 +10836,12 @@ class LocalTrack extends Track {
10824
10836
  }
10825
10837
 
10826
10838
  this.isMuted = muted;
10827
- this.mediaStreamTrack.enabled = !muted;
10839
+ this._mediaStreamTrack.enabled = !muted;
10828
10840
  this.emit(muted ? TrackEvent.Muted : TrackEvent.Unmuted, this);
10829
10841
  }
10830
10842
 
10831
10843
  get needsReAcquisition() {
10832
- return this.mediaStreamTrack.readyState !== 'live' || this.mediaStreamTrack.muted || !this.mediaStreamTrack.enabled || this.reacquireTrack;
10844
+ return this._mediaStreamTrack.readyState !== 'live' || this._mediaStreamTrack.muted || !this._mediaStreamTrack.enabled || this.reacquireTrack;
10833
10845
  }
10834
10846
 
10835
10847
  async handleAppVisibilityChanged() {
@@ -10879,7 +10891,7 @@ class LocalTrack extends Track {
10879
10891
 
10880
10892
  this._isUpstreamPaused = false;
10881
10893
  this.emit(TrackEvent.UpstreamResumed, this);
10882
- await this.sender.replaceTrack(this.mediaStreamTrack);
10894
+ await this.sender.replaceTrack(this._mediaStreamTrack);
10883
10895
  }
10884
10896
 
10885
10897
  }
@@ -11004,7 +11016,9 @@ class LocalAudioTrack extends LocalTrack {
11004
11016
  try {
11005
11017
  stats = await this.getSenderStats();
11006
11018
  } catch (e) {
11007
- livekitLogger.error('could not get audio sender stats', e);
11019
+ livekitLogger.error('could not get audio sender stats', {
11020
+ error: e
11021
+ });
11008
11022
  return;
11009
11023
  }
11010
11024
 
@@ -11038,7 +11052,7 @@ class LocalAudioTrack extends LocalTrack {
11038
11052
  if (this.source === Track.Source.Microphone && this.stopOnMute) {
11039
11053
  livekitLogger.debug('stopping mic track'); // also stop the track, so that microphone indicator is turned off
11040
11054
 
11041
- this.mediaStreamTrack.stop();
11055
+ this._mediaStreamTrack.stop();
11042
11056
  }
11043
11057
 
11044
11058
  await super.mute();
@@ -11192,7 +11206,9 @@ class LocalVideoTrack extends LocalTrack {
11192
11206
 
11193
11207
  stop() {
11194
11208
  this.sender = undefined;
11195
- this.mediaStreamTrack.getConstraints();
11209
+
11210
+ this._mediaStreamTrack.getConstraints();
11211
+
11196
11212
  super.stop();
11197
11213
  }
11198
11214
 
@@ -11200,7 +11216,7 @@ class LocalVideoTrack extends LocalTrack {
11200
11216
  if (this.source === Track.Source.Camera) {
11201
11217
  livekitLogger.debug('stopping camera track'); // also stop the track, so that camera indicator is turned off
11202
11218
 
11203
- this.mediaStreamTrack.stop();
11219
+ this._mediaStreamTrack.stop();
11204
11220
  }
11205
11221
 
11206
11222
  await super.mute();
@@ -11381,7 +11397,7 @@ class LocalVideoTrack extends LocalTrack {
11381
11397
  if (!isMobile()) return;
11382
11398
 
11383
11399
  if (this.isInBackground && this.source === Track.Source.Camera) {
11384
- this.mediaStreamTrack.enabled = false;
11400
+ this._mediaStreamTrack.enabled = false;
11385
11401
  }
11386
11402
  }
11387
11403
 
@@ -11672,6 +11688,14 @@ class RemoteVideoTrack extends RemoteTrack {
11672
11688
  get isAdaptiveStream() {
11673
11689
  return this.adaptiveStreamSettings !== undefined;
11674
11690
  }
11691
+
11692
+ get mediaStreamTrack() {
11693
+ if (this.isAdaptiveStream && this.attachedElements.length === 0) {
11694
+ throw Error('When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, direct usage of mediaStreamTrack is unsupported in this case');
11695
+ }
11696
+
11697
+ return this._mediaStreamTrack;
11698
+ }
11675
11699
  /** @internal */
11676
11700
 
11677
11701
 
@@ -11680,9 +11704,9 @@ class RemoteVideoTrack extends RemoteTrack {
11680
11704
  this.attachedElements.forEach(element => {
11681
11705
  // detach or attach
11682
11706
  if (muted) {
11683
- detachTrack(this.mediaStreamTrack, element);
11707
+ detachTrack(this._mediaStreamTrack, element);
11684
11708
  } else {
11685
- attachToElement(this.mediaStreamTrack, element);
11709
+ attachToElement(this._mediaStreamTrack, element);
11686
11710
  }
11687
11711
  });
11688
11712
  }
@@ -12432,9 +12456,10 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
12432
12456
  }
12433
12457
 
12434
12458
  const useSimulcast = options === null || options === void 0 ? void 0 : options.simulcast;
12459
+ const scalabilityMode = options === null || options === void 0 ? void 0 : options.scalabilityMode;
12435
12460
 
12436
- if (!videoEncoding && !useSimulcast || !width || !height) {
12437
- // when we aren't simulcasting, will need to return a single encoding without
12461
+ if (!videoEncoding && !useSimulcast && !scalabilityMode || !width || !height) {
12462
+ // when we aren't simulcasting or svc, will need to return a single encoding without
12438
12463
  // capping bandwidth. we always require a encoding for dynacast
12439
12464
  return [{}];
12440
12465
  }
@@ -12445,11 +12470,41 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
12445
12470
  livekitLogger.debug('using video encoding', videoEncoding);
12446
12471
  }
12447
12472
 
12473
+ const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
12474
+ livekitLogger.debug("scalabilityMode ".concat(scalabilityMode));
12475
+
12476
+ if (scalabilityMode) {
12477
+ const encodings = []; // svc use first encoding as the original, so we sort encoding from high to low
12478
+
12479
+ switch (scalabilityMode) {
12480
+ case 'L3T3':
12481
+ for (let i = 0; i < 3; i += 1) {
12482
+ encodings.push({
12483
+ rid: videoRids[2 - i],
12484
+ scaleResolutionDownBy: 2 ** i,
12485
+ maxBitrate: videoEncoding ? videoEncoding.maxBitrate / 2 ** i : 0,
12486
+
12487
+ /* @ts-ignore */
12488
+ maxFramerate: original.encoding.maxFramerate,
12489
+
12490
+ /* @ts-ignore */
12491
+ scalabilityMode: 'L3T3'
12492
+ });
12493
+ }
12494
+
12495
+ livekitLogger.debug('encodings', encodings);
12496
+ return encodings;
12497
+
12498
+ default:
12499
+ // TODO : support other scalability modes
12500
+ throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
12501
+ }
12502
+ }
12503
+
12448
12504
  if (!useSimulcast) {
12449
12505
  return [videoEncoding];
12450
12506
  }
12451
12507
 
12452
- const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
12453
12508
  let presets = [];
12454
12509
 
12455
12510
  if (isScreenShare) {
@@ -13441,7 +13496,7 @@ class LocalParticipant extends Participant {
13441
13496
 
13442
13497
 
13443
13498
  async publishTrack(track, options) {
13444
- var _a, _b, _c, _d, _e, _f;
13499
+ var _a, _b, _c, _d, _e, _f, _g;
13445
13500
 
13446
13501
  const opts = _objectSpread2(_objectSpread2({}, (_a = this.roomOptions) === null || _a === void 0 ? void 0 : _a.publishDefaults), options); // convert raw media track into audio or video track
13447
13502
 
@@ -13514,7 +13569,19 @@ class LocalParticipant extends Participant {
13514
13569
  const height = (_e = settings.height) !== null && _e !== void 0 ? _e : (_f = track.dimensions) === null || _f === void 0 ? void 0 : _f.height; // width and height should be defined for video
13515
13570
 
13516
13571
  req.width = width !== null && width !== void 0 ? width : 0;
13517
- req.height = height !== null && height !== void 0 ? height : 0;
13572
+ req.height = height !== null && height !== void 0 ? height : 0; // for svc codecs, disable simulcast and enable scalability L3T3
13573
+ // by default
13574
+
13575
+ if (track instanceof LocalVideoTrack) {
13576
+ if ((opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'vp9' || (opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'av1') {
13577
+ opts.simulcast = false;
13578
+ opts.scalabilityMode = (_g = opts.scalabilityMode) !== null && _g !== void 0 ? _g : 'L3T3';
13579
+ } else {
13580
+ // other codecs, unset scalability
13581
+ opts.scalabilityMode = undefined;
13582
+ }
13583
+ }
13584
+
13518
13585
  encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, width, height, opts);
13519
13586
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
13520
13587
  } else if (track.kind === Track.Kind.Audio && opts.audioBitrate) {
@@ -13544,6 +13611,11 @@ class LocalParticipant extends Participant {
13544
13611
  }
13545
13612
 
13546
13613
  const transceiver = this.engine.publisher.pc.addTransceiver(track.mediaStreamTrack, transceiverInit);
13614
+
13615
+ if (opts.videoCodec) {
13616
+ this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
13617
+ }
13618
+
13547
13619
  this.engine.negotiate(); // store RTPSender
13548
13620
 
13549
13621
  track.sender = transceiver.sender;
@@ -13554,10 +13626,6 @@ class LocalParticipant extends Participant {
13554
13626
  track.startMonitor();
13555
13627
  }
13556
13628
 
13557
- if (opts.videoCodec) {
13558
- this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
13559
- }
13560
-
13561
13629
  this.addTrackPublication(publication); // send event for publication
13562
13630
 
13563
13631
  this.emit(ParticipantEvent.LocalTrackPublished, publication);
@@ -13739,21 +13807,38 @@ class LocalParticipant extends Participant {
13739
13807
 
13740
13808
  const cap = RTCRtpSender.getCapabilities(kind);
13741
13809
  if (!cap) return;
13742
- const selected = cap.codecs.find(c => {
13810
+ let selected;
13811
+ const codecs = [];
13812
+ cap.codecs.forEach(c => {
13743
13813
  const codec = c.mimeType.toLowerCase();
13744
- const matchesVideoCodec = codec === "video/".concat(videoCodec); // for h264 codecs that have sdpFmtpLine available, use only if the
13814
+ const matchesVideoCodec = codec === "video/".concat(videoCodec);
13815
+
13816
+ if (selected !== undefined) {
13817
+ codecs.push(c);
13818
+ return;
13819
+ } // for h264 codecs that have sdpFmtpLine available, use only if the
13745
13820
  // profile-level-id is 42e01f for cross-browser compatibility
13746
13821
 
13822
+
13747
13823
  if (videoCodec === 'h264' && c.sdpFmtpLine) {
13748
- return matchesVideoCodec && c.sdpFmtpLine.includes('profile-level-id=42e01f');
13824
+ if (matchesVideoCodec && c.sdpFmtpLine.includes('profile-level-id=42e01f')) {
13825
+ selected = c;
13826
+ return;
13827
+ }
13828
+ }
13829
+
13830
+ if (matchesVideoCodec || codec === 'audio/opus') {
13831
+ selected = c;
13832
+ return;
13749
13833
  }
13750
13834
 
13751
- return matchesVideoCodec || codec === 'audio/opus';
13835
+ codecs.push(c);
13752
13836
  });
13753
13837
 
13754
13838
  if (selected && 'setCodecPreferences' in transceiver) {
13755
13839
  // @ts-ignore
13756
- transceiver.setCodecPreferences([selected]);
13840
+ codecs.unshift(selected);
13841
+ transceiver.setCodecPreferences(codecs);
13757
13842
  }
13758
13843
  }
13759
13844
  /** @internal */
@@ -18525,12 +18610,11 @@ const publishDefaults = {
18525
18610
  };
18526
18611
  const audioDefaults = {
18527
18612
  autoGainControl: true,
18528
- channelCount: 1,
18529
18613
  echoCancellation: true,
18530
18614
  noiseSuppression: true
18531
18615
  };
18532
18616
  const videoDefaults = {
18533
- resolution: VideoPresets.h540.resolution
18617
+ resolution: VideoPresets.h720.resolution
18534
18618
  };
18535
18619
 
18536
18620
  var RoomState;