livekit-client 0.18.4 → 1.0.0

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 (59) hide show
  1. package/README.md +1 -1
  2. package/dist/api/SignalClient.d.ts +2 -2
  3. package/dist/api/SignalClient.d.ts.map +1 -1
  4. package/dist/index.d.ts +2 -3
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/livekit-client.esm.mjs +263 -261
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/options.d.ts +1 -68
  11. package/dist/options.d.ts.map +1 -1
  12. package/dist/room/DeviceManager.d.ts.map +1 -1
  13. package/dist/room/RTCEngine.d.ts +3 -2
  14. package/dist/room/RTCEngine.d.ts.map +1 -1
  15. package/dist/room/Room.d.ts +11 -7
  16. package/dist/room/Room.d.ts.map +1 -1
  17. package/dist/room/events.d.ts +6 -12
  18. package/dist/room/events.d.ts.map +1 -1
  19. package/dist/room/participant/LocalParticipant.d.ts.map +1 -1
  20. package/dist/room/participant/Participant.d.ts +0 -4
  21. package/dist/room/participant/Participant.d.ts.map +1 -1
  22. package/dist/room/participant/RemoteParticipant.d.ts +3 -2
  23. package/dist/room/participant/RemoteParticipant.d.ts.map +1 -1
  24. package/dist/room/participant/publishUtils.d.ts.map +1 -1
  25. package/dist/room/track/RemoteVideoTrack.d.ts +2 -0
  26. package/dist/room/track/RemoteVideoTrack.d.ts.map +1 -1
  27. package/dist/room/track/Track.d.ts +7 -3
  28. package/dist/room/track/Track.d.ts.map +1 -1
  29. package/dist/room/track/defaults.d.ts.map +1 -1
  30. package/dist/room/track/options.d.ts +9 -30
  31. package/dist/room/track/options.d.ts.map +1 -1
  32. package/dist/version.d.ts +1 -1
  33. package/dist/version.d.ts.map +1 -1
  34. package/package.json +3 -3
  35. package/src/api/SignalClient.ts +32 -7
  36. package/src/index.ts +2 -2
  37. package/src/options.ts +0 -82
  38. package/src/room/DeviceManager.ts +4 -1
  39. package/src/room/RTCEngine.ts +16 -7
  40. package/src/room/Room.ts +65 -41
  41. package/src/room/events.ts +7 -14
  42. package/src/room/participant/LocalParticipant.ts +37 -9
  43. package/src/room/participant/Participant.ts +0 -5
  44. package/src/room/participant/RemoteParticipant.ts +16 -5
  45. package/src/room/participant/publishUtils.test.ts +2 -2
  46. package/src/room/participant/publishUtils.ts +34 -5
  47. package/src/room/track/LocalAudioTrack.ts +2 -2
  48. package/src/room/track/LocalTrack.ts +17 -17
  49. package/src/room/track/LocalVideoTrack.ts +3 -3
  50. package/src/room/track/RemoteVideoTrack.ts +15 -2
  51. package/src/room/track/Track.ts +20 -13
  52. package/src/room/track/create.ts +1 -1
  53. package/src/room/track/defaults.ts +1 -2
  54. package/src/room/track/options.ts +12 -31
  55. package/src/room/track/utils.test.ts +6 -6
  56. package/src/version.ts +1 -1
  57. package/dist/connect.d.ts +0 -24
  58. package/dist/connect.d.ts.map +0 -1
  59. package/src/connect.ts +0 -98
@@ -9260,10 +9260,15 @@ var RoomEvent;
9260
9260
  /**
9261
9261
  * Whenever the connection state of the room changes
9262
9262
  *
9263
- * args: ([[RoomState]])
9263
+ * args: ([[ConnectionState]])
9264
9264
  */
9265
9265
 
9266
- RoomEvent["StateChanged"] = "stateChanged";
9266
+ RoomEvent["ConnectionStateChanged"] = "connectionStateChanged";
9267
+ /**
9268
+ * @deprecated StateChanged has been renamed to ConnectionStateChanged
9269
+ */
9270
+
9271
+ RoomEvent["StateChanged"] = "connectionStateChanged";
9267
9272
  /**
9268
9273
  * When input or output devices on the machine have changed.
9269
9274
  */
@@ -9370,12 +9375,6 @@ var RoomEvent;
9370
9375
  */
9371
9376
 
9372
9377
  RoomEvent["ActiveSpeakersChanged"] = "activeSpeakersChanged";
9373
- /**
9374
- * @deprecated Use ParticipantMetadataChanged instead
9375
- * @internal
9376
- */
9377
-
9378
- RoomEvent["MetadataChanged"] = "metadataChanged";
9379
9378
  /**
9380
9379
  * Participant metadata is a simple way for app-specific state to be pushed to
9381
9380
  * all users.
@@ -9541,12 +9540,6 @@ var ParticipantEvent;
9541
9540
  */
9542
9541
 
9543
9542
  ParticipantEvent["LocalTrackUnpublished"] = "localTrackUnpublished";
9544
- /**
9545
- * @deprecated Use ParticipantMetadataChanged instead
9546
- * @internal
9547
- */
9548
-
9549
- ParticipantEvent["MetadataChanged"] = "metadataChanged";
9550
9543
  /**
9551
9544
  * Participant metadata is a simple way for app-specific state to be pushed to
9552
9545
  * all users.
@@ -9737,8 +9730,11 @@ class DeviceManager {
9737
9730
  video: kind !== 'audioinput' && kind !== 'audiooutput',
9738
9731
  audio: kind !== 'videoinput'
9739
9732
  };
9740
- await navigator.mediaDevices.getUserMedia(permissionsToAcquire);
9733
+ const stream = await navigator.mediaDevices.getUserMedia(permissionsToAcquire);
9741
9734
  devices = await navigator.mediaDevices.enumerateDevices();
9735
+ stream.getTracks().forEach(track => {
9736
+ track.stop();
9737
+ });
9742
9738
  }
9743
9739
  }
9744
9740
 
@@ -9783,7 +9779,7 @@ class DeviceManager {
9783
9779
  }
9784
9780
  DeviceManager.mediaDeviceKinds = ['audioinput', 'audiooutput', 'videoinput'];
9785
9781
 
9786
- const version = '0.18.4';
9782
+ const version = '1.0.0';
9787
9783
  const protocolVersion = 7;
9788
9784
 
9789
9785
  const separator = '|';
@@ -10351,7 +10347,7 @@ class Track extends events.exports.EventEmitter {
10351
10347
  };
10352
10348
 
10353
10349
  this.kind = kind;
10354
- this.mediaStreamTrack = mediaTrack;
10350
+ this._mediaStreamTrack = mediaTrack;
10355
10351
  this.source = Track.Source.Unknown;
10356
10352
 
10357
10353
  if (isWeb()) {
@@ -10368,6 +10364,10 @@ class Track extends events.exports.EventEmitter {
10368
10364
  return this._currentBitrate;
10369
10365
  }
10370
10366
 
10367
+ get mediaStreamTrack() {
10368
+ return this._mediaStreamTrack;
10369
+ }
10370
+
10371
10371
  attach(element) {
10372
10372
  let elementType = 'audio';
10373
10373
 
@@ -10401,7 +10401,7 @@ class Track extends events.exports.EventEmitter {
10401
10401
  // we'll want to re-attach it in that case
10402
10402
 
10403
10403
 
10404
- attachToElement(this.mediaStreamTrack, element);
10404
+ attachToElement(this._mediaStreamTrack, element);
10405
10405
 
10406
10406
  if (element instanceof HTMLAudioElement) {
10407
10407
  // manually play audio to detect audio playback status
@@ -10419,7 +10419,7 @@ class Track extends events.exports.EventEmitter {
10419
10419
  detach(element) {
10420
10420
  // detach from a single element
10421
10421
  if (element) {
10422
- detachTrack(this.mediaStreamTrack, element);
10422
+ detachTrack(this._mediaStreamTrack, element);
10423
10423
  const idx = this.attachedElements.indexOf(element);
10424
10424
 
10425
10425
  if (idx >= 0) {
@@ -10433,7 +10433,7 @@ class Track extends events.exports.EventEmitter {
10433
10433
 
10434
10434
  const detached = [];
10435
10435
  this.attachedElements.forEach(elm => {
10436
- detachTrack(this.mediaStreamTrack, elm);
10436
+ detachTrack(this._mediaStreamTrack, elm);
10437
10437
  detached.push(elm);
10438
10438
  this.recycleElement(elm);
10439
10439
  this.emit(TrackEvent.ElementDetached, elm);
@@ -10444,7 +10444,7 @@ class Track extends events.exports.EventEmitter {
10444
10444
  }
10445
10445
 
10446
10446
  stop() {
10447
- this.mediaStreamTrack.stop();
10447
+ this._mediaStreamTrack.stop();
10448
10448
 
10449
10449
  if (isWeb()) {
10450
10450
  document.removeEventListener('visibilitychange', this.appVisibilityChangedListener);
@@ -10452,11 +10452,11 @@ class Track extends events.exports.EventEmitter {
10452
10452
  }
10453
10453
 
10454
10454
  enable() {
10455
- this.mediaStreamTrack.enabled = true;
10455
+ this._mediaStreamTrack.enabled = true;
10456
10456
  }
10457
10457
 
10458
10458
  disable() {
10459
- this.mediaStreamTrack.enabled = false;
10459
+ this._mediaStreamTrack.enabled = false;
10460
10460
  }
10461
10461
 
10462
10462
  recycleElement(element) {
@@ -10686,14 +10686,15 @@ class LocalTrack extends Track {
10686
10686
  this.emit(TrackEvent.Ended, this);
10687
10687
  };
10688
10688
 
10689
- this.mediaStreamTrack.addEventListener('ended', this.handleEnded);
10689
+ this._mediaStreamTrack.addEventListener('ended', this.handleEnded);
10690
+
10690
10691
  this.constraints = constraints !== null && constraints !== void 0 ? constraints : mediaTrack.getConstraints();
10691
10692
  this.reacquireTrack = false;
10692
10693
  this.wasMuted = false;
10693
10694
  }
10694
10695
 
10695
10696
  get id() {
10696
- return this.mediaStreamTrack.id;
10697
+ return this._mediaStreamTrack.id;
10697
10698
  }
10698
10699
 
10699
10700
  get dimensions() {
@@ -10704,7 +10705,7 @@ class LocalTrack extends Track {
10704
10705
  const {
10705
10706
  width,
10706
10707
  height
10707
- } = this.mediaStreamTrack.getSettings();
10708
+ } = this._mediaStreamTrack.getSettings();
10708
10709
 
10709
10710
  if (width && height) {
10710
10711
  return {
@@ -10733,7 +10734,8 @@ class LocalTrack extends Track {
10733
10734
  const {
10734
10735
  deviceId,
10735
10736
  groupId
10736
- } = this.mediaStreamTrack.getSettings();
10737
+ } = this._mediaStreamTrack.getSettings();
10738
+
10737
10739
  const kind = this.kind === Track.Kind.Audio ? 'audioinput' : 'videoinput';
10738
10740
  return DeviceManager.getInstance().normalizeDeviceId(kind, deviceId, groupId);
10739
10741
  }
@@ -10755,17 +10757,20 @@ class LocalTrack extends Track {
10755
10757
 
10756
10758
 
10757
10759
  this.attachedElements.forEach(el => {
10758
- detachTrack(this.mediaStreamTrack, el);
10760
+ detachTrack(this._mediaStreamTrack, el);
10759
10761
  });
10760
- this.mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10762
+
10763
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10761
10764
  // the new track, otherwise the new track will stop with
10762
10765
  // 'A MediaStreamTrack ended due to a capture failure`
10763
10766
 
10764
- this.mediaStreamTrack.stop();
10767
+
10768
+ this._mediaStreamTrack.stop();
10769
+
10765
10770
  track.addEventListener('ended', this.handleEnded);
10766
10771
  livekitLogger.debug('replace MediaStreamTrack');
10767
10772
  await this.sender.replaceTrack(track);
10768
- this.mediaStreamTrack = track;
10773
+ this._mediaStreamTrack = track;
10769
10774
  this.attachedElements.forEach(el => {
10770
10775
  attachToElement(track, el);
10771
10776
  });
@@ -10796,20 +10801,23 @@ class LocalTrack extends Track {
10796
10801
 
10797
10802
 
10798
10803
  this.attachedElements.forEach(el => {
10799
- detachTrack(this.mediaStreamTrack, el);
10804
+ detachTrack(this._mediaStreamTrack, el);
10800
10805
  });
10801
- this.mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10806
+
10807
+ this._mediaStreamTrack.removeEventListener('ended', this.handleEnded); // on Safari, the old audio track must be stopped before attempting to acquire
10802
10808
  // the new track, otherwise the new track will stop with
10803
10809
  // 'A MediaStreamTrack ended due to a capture failure`
10804
10810
 
10805
- this.mediaStreamTrack.stop(); // create new track and attach
10811
+
10812
+ this._mediaStreamTrack.stop(); // create new track and attach
10813
+
10806
10814
 
10807
10815
  const mediaStream = await navigator.mediaDevices.getUserMedia(streamConstraints);
10808
10816
  const newTrack = mediaStream.getTracks()[0];
10809
10817
  newTrack.addEventListener('ended', this.handleEnded);
10810
10818
  livekitLogger.debug('re-acquired MediaStreamTrack');
10811
10819
  await this.sender.replaceTrack(newTrack);
10812
- this.mediaStreamTrack = newTrack;
10820
+ this._mediaStreamTrack = newTrack;
10813
10821
  this.attachedElements.forEach(el => {
10814
10822
  attachToElement(newTrack, el);
10815
10823
  });
@@ -10824,12 +10832,12 @@ class LocalTrack extends Track {
10824
10832
  }
10825
10833
 
10826
10834
  this.isMuted = muted;
10827
- this.mediaStreamTrack.enabled = !muted;
10835
+ this._mediaStreamTrack.enabled = !muted;
10828
10836
  this.emit(muted ? TrackEvent.Muted : TrackEvent.Unmuted, this);
10829
10837
  }
10830
10838
 
10831
10839
  get needsReAcquisition() {
10832
- return this.mediaStreamTrack.readyState !== 'live' || this.mediaStreamTrack.muted || !this.mediaStreamTrack.enabled || this.reacquireTrack;
10840
+ return this._mediaStreamTrack.readyState !== 'live' || this._mediaStreamTrack.muted || !this._mediaStreamTrack.enabled || this.reacquireTrack;
10833
10841
  }
10834
10842
 
10835
10843
  async handleAppVisibilityChanged() {
@@ -10879,7 +10887,7 @@ class LocalTrack extends Track {
10879
10887
 
10880
10888
  this._isUpstreamPaused = false;
10881
10889
  this.emit(TrackEvent.UpstreamResumed, this);
10882
- await this.sender.replaceTrack(this.mediaStreamTrack);
10890
+ await this.sender.replaceTrack(this._mediaStreamTrack);
10883
10891
  }
10884
10892
 
10885
10893
  }
@@ -11004,7 +11012,9 @@ class LocalAudioTrack extends LocalTrack {
11004
11012
  try {
11005
11013
  stats = await this.getSenderStats();
11006
11014
  } catch (e) {
11007
- livekitLogger.error('could not get audio sender stats', e);
11015
+ livekitLogger.error('could not get audio sender stats', {
11016
+ error: e
11017
+ });
11008
11018
  return;
11009
11019
  }
11010
11020
 
@@ -11038,7 +11048,7 @@ class LocalAudioTrack extends LocalTrack {
11038
11048
  if (this.source === Track.Source.Microphone && this.stopOnMute) {
11039
11049
  livekitLogger.debug('stopping mic track'); // also stop the track, so that microphone indicator is turned off
11040
11050
 
11041
- this.mediaStreamTrack.stop();
11051
+ this._mediaStreamTrack.stop();
11042
11052
  }
11043
11053
 
11044
11054
  await super.mute();
@@ -11192,7 +11202,9 @@ class LocalVideoTrack extends LocalTrack {
11192
11202
 
11193
11203
  stop() {
11194
11204
  this.sender = undefined;
11195
- this.mediaStreamTrack.getConstraints();
11205
+
11206
+ this._mediaStreamTrack.getConstraints();
11207
+
11196
11208
  super.stop();
11197
11209
  }
11198
11210
 
@@ -11200,7 +11212,7 @@ class LocalVideoTrack extends LocalTrack {
11200
11212
  if (this.source === Track.Source.Camera) {
11201
11213
  livekitLogger.debug('stopping camera track'); // also stop the track, so that camera indicator is turned off
11202
11214
 
11203
- this.mediaStreamTrack.stop();
11215
+ this._mediaStreamTrack.stop();
11204
11216
  }
11205
11217
 
11206
11218
  await super.mute();
@@ -11381,7 +11393,7 @@ class LocalVideoTrack extends LocalTrack {
11381
11393
  if (!isMobile()) return;
11382
11394
 
11383
11395
  if (this.isInBackground && this.source === Track.Source.Camera) {
11384
- this.mediaStreamTrack.enabled = false;
11396
+ this._mediaStreamTrack.enabled = false;
11385
11397
  }
11386
11398
  }
11387
11399
 
@@ -11625,6 +11637,7 @@ class RemoteVideoTrack extends RemoteTrack {
11625
11637
  constructor(mediaTrack, sid, receiver, adaptiveStreamSettings) {
11626
11638
  super(mediaTrack, sid, Track.Kind.Video, receiver);
11627
11639
  this.elementInfos = [];
11640
+ this.hasUsedAttach = false;
11628
11641
 
11629
11642
  this.monitorReceiver = async () => {
11630
11643
  if (!this.receiver) {
@@ -11672,6 +11685,14 @@ class RemoteVideoTrack extends RemoteTrack {
11672
11685
  get isAdaptiveStream() {
11673
11686
  return this.adaptiveStreamSettings !== undefined;
11674
11687
  }
11688
+
11689
+ get mediaStreamTrack() {
11690
+ if (this.isAdaptiveStream && !this.hasUsedAttach) {
11691
+ livekitLogger.warn('When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start');
11692
+ }
11693
+
11694
+ return this._mediaStreamTrack;
11695
+ }
11675
11696
  /** @internal */
11676
11697
 
11677
11698
 
@@ -11680,9 +11701,9 @@ class RemoteVideoTrack extends RemoteTrack {
11680
11701
  this.attachedElements.forEach(element => {
11681
11702
  // detach or attach
11682
11703
  if (muted) {
11683
- detachTrack(this.mediaStreamTrack, element);
11704
+ detachTrack(this._mediaStreamTrack, element);
11684
11705
  } else {
11685
- attachToElement(this.mediaStreamTrack, element);
11706
+ attachToElement(this._mediaStreamTrack, element);
11686
11707
  }
11687
11708
  });
11688
11709
  }
@@ -11712,6 +11733,7 @@ class RemoteVideoTrack extends RemoteTrack {
11712
11733
  this.debouncedHandleResize();
11713
11734
  }
11714
11735
 
11736
+ this.hasUsedAttach = true;
11715
11737
  return element;
11716
11738
  }
11717
11739
 
@@ -12063,25 +12085,10 @@ const VideoPresets = {
12063
12085
  h216: new VideoPreset(384, 216, 180000, 15),
12064
12086
  h360: new VideoPreset(640, 360, 300000, 20),
12065
12087
  h540: new VideoPreset(960, 540, 600000, 25),
12066
- h720: new VideoPreset(1280, 720, 2000000, 30),
12088
+ h720: new VideoPreset(1280, 720, 1700000, 30),
12067
12089
  h1080: new VideoPreset(1920, 1080, 3000000, 30),
12068
12090
  h1440: new VideoPreset(2560, 1440, 5000000, 30),
12069
- h2160: new VideoPreset(3840, 2160, 8000000, 30),
12070
-
12071
- /** @deprecated */
12072
- qvga: new VideoPreset(320, 180, 120000, 10),
12073
-
12074
- /** @deprecated */
12075
- vga: new VideoPreset(640, 360, 300000, 20),
12076
-
12077
- /** @deprecated */
12078
- qhd: new VideoPreset(960, 540, 600000, 25),
12079
-
12080
- /** @deprecated */
12081
- hd: new VideoPreset(1280, 720, 2000000, 30),
12082
-
12083
- /** @deprecated */
12084
- fhd: new VideoPreset(1920, 1080, 3000000, 30)
12091
+ h2160: new VideoPreset(3840, 2160, 8000000, 30)
12085
12092
  };
12086
12093
  /**
12087
12094
  * Four by three presets
@@ -12096,44 +12103,14 @@ const VideoPresets43 = {
12096
12103
  h540: new VideoPreset(720, 540, 450000, 25),
12097
12104
  h720: new VideoPreset(960, 720, 1500000, 30),
12098
12105
  h1080: new VideoPreset(1440, 1080, 2500000, 30),
12099
- h1440: new VideoPreset(1920, 1440, 3500000, 30),
12100
-
12101
- /** @deprecated */
12102
- qvga: new VideoPreset(240, 180, 90000, 10),
12103
-
12104
- /** @deprecated */
12105
- vga: new VideoPreset(480, 360, 225000, 20),
12106
-
12107
- /** @deprecated */
12108
- qhd: new VideoPreset(720, 540, 450000, 25),
12109
-
12110
- /** @deprecated */
12111
- hd: new VideoPreset(960, 720, 1500000, 30),
12112
-
12113
- /** @deprecated */
12114
- fhd: new VideoPreset(1440, 1080, 2800000, 30)
12106
+ h1440: new VideoPreset(1920, 1440, 3500000, 30)
12115
12107
  };
12116
12108
  const ScreenSharePresets = {
12117
12109
  h360fps3: new VideoPreset(640, 360, 200000, 3),
12118
12110
  h720fps5: new VideoPreset(1280, 720, 400000, 5),
12119
12111
  h720fps15: new VideoPreset(1280, 720, 1000000, 15),
12120
12112
  h1080fps15: new VideoPreset(1920, 1080, 1500000, 15),
12121
- h1080fps30: new VideoPreset(1920, 1080, 3000000, 30),
12122
-
12123
- /** @deprecated */
12124
- vga: new VideoPreset(640, 360, 200000, 3),
12125
-
12126
- /** @deprecated */
12127
- hd_8: new VideoPreset(1280, 720, 400000, 5),
12128
-
12129
- /** @deprecated */
12130
- hd_15: new VideoPreset(1280, 720, 1000000, 15),
12131
-
12132
- /** @deprecated */
12133
- fhd_15: new VideoPreset(1920, 1080, 1500000, 15),
12134
-
12135
- /** @deprecated */
12136
- fhd_30: new VideoPreset(1920, 1080, 3000000, 30)
12113
+ h1080fps30: new VideoPreset(1920, 1080, 3000000, 30)
12137
12114
  };
12138
12115
 
12139
12116
  var ConnectionQuality;
@@ -12291,7 +12268,6 @@ class Participant extends events.exports.EventEmitter {
12291
12268
  this.metadata = md;
12292
12269
 
12293
12270
  if (changed) {
12294
- this.emit(ParticipantEvent.MetadataChanged, prevMetadata);
12295
12271
  this.emit(ParticipantEvent.ParticipantMetadataChanged, prevMetadata);
12296
12272
  }
12297
12273
  }
@@ -12432,9 +12408,10 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
12432
12408
  }
12433
12409
 
12434
12410
  const useSimulcast = options === null || options === void 0 ? void 0 : options.simulcast;
12411
+ const scalabilityMode = options === null || options === void 0 ? void 0 : options.scalabilityMode;
12435
12412
 
12436
- if (!videoEncoding && !useSimulcast || !width || !height) {
12437
- // when we aren't simulcasting, will need to return a single encoding without
12413
+ if (!videoEncoding && !useSimulcast && !scalabilityMode || !width || !height) {
12414
+ // when we aren't simulcasting or svc, will need to return a single encoding without
12438
12415
  // capping bandwidth. we always require a encoding for dynacast
12439
12416
  return [{}];
12440
12417
  }
@@ -12445,11 +12422,41 @@ function computeVideoEncodings(isScreenShare, width, height, options) {
12445
12422
  livekitLogger.debug('using video encoding', videoEncoding);
12446
12423
  }
12447
12424
 
12425
+ const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
12426
+ livekitLogger.debug("scalabilityMode ".concat(scalabilityMode));
12427
+
12428
+ if (scalabilityMode) {
12429
+ const encodings = []; // svc use first encoding as the original, so we sort encoding from high to low
12430
+
12431
+ switch (scalabilityMode) {
12432
+ case 'L3T3':
12433
+ for (let i = 0; i < 3; i += 1) {
12434
+ encodings.push({
12435
+ rid: videoRids[2 - i],
12436
+ scaleResolutionDownBy: 2 ** i,
12437
+ maxBitrate: videoEncoding ? videoEncoding.maxBitrate / 2 ** i : 0,
12438
+
12439
+ /* @ts-ignore */
12440
+ maxFramerate: original.encoding.maxFramerate,
12441
+
12442
+ /* @ts-ignore */
12443
+ scalabilityMode: 'L3T3'
12444
+ });
12445
+ }
12446
+
12447
+ livekitLogger.debug('encodings', encodings);
12448
+ return encodings;
12449
+
12450
+ default:
12451
+ // TODO : support other scalability modes
12452
+ throw new Error("unsupported scalabilityMode: ".concat(scalabilityMode));
12453
+ }
12454
+ }
12455
+
12448
12456
  if (!useSimulcast) {
12449
12457
  return [videoEncoding];
12450
12458
  }
12451
12459
 
12452
- const original = new VideoPreset(width, height, videoEncoding.maxBitrate, videoEncoding.maxFramerate);
12453
12460
  let presets = [];
12454
12461
 
12455
12462
  if (isScreenShare) {
@@ -12852,29 +12859,32 @@ class RemoteParticipant extends Participant {
12852
12859
  }
12853
12860
  }
12854
12861
  /**
12855
- * sets the volume on the participant's microphone track if it exists.
12862
+ * sets the volume on the participant's microphone track
12863
+ * if no track exists the volume will be applied when the microphone track is added
12856
12864
  */
12857
12865
 
12858
12866
 
12859
12867
  setVolume(volume) {
12868
+ this.volume = volume;
12860
12869
  const audioPublication = this.getTrack(Track.Source.Microphone);
12861
12870
 
12862
- if (audioPublication) {
12871
+ if (audioPublication && audioPublication.track) {
12863
12872
  audioPublication.track.setVolume(volume);
12864
12873
  }
12865
12874
  }
12866
12875
  /**
12867
12876
  * gets the volume on the participant's microphone track
12868
- * returns undefined if no microphone track exists
12869
12877
  */
12870
12878
 
12871
12879
 
12872
12880
  getVolume() {
12873
12881
  const audioPublication = this.getTrack(Track.Source.Microphone);
12874
12882
 
12875
- if (audioPublication) {
12883
+ if (audioPublication && audioPublication.track) {
12876
12884
  return audioPublication.track.getVolume();
12877
12885
  }
12886
+
12887
+ return this.volume;
12878
12888
  }
12879
12889
  /** @internal */
12880
12890
 
@@ -12930,7 +12940,12 @@ class RemoteParticipant extends Participant {
12930
12940
  track.isMuted = publication.isMuted;
12931
12941
  track.setMediaStream(mediaStream);
12932
12942
  track.start();
12933
- publication.setTrack(track);
12943
+ publication.setTrack(track); // set participant volume on new microphone tracks
12944
+
12945
+ if (this.volume !== undefined && track instanceof RemoteAudioTrack && track.source === Track.Source.Microphone) {
12946
+ track.setVolume(this.volume);
12947
+ }
12948
+
12934
12949
  this.emit(ParticipantEvent.TrackSubscribed, track, publication);
12935
12950
  return publication;
12936
12951
  }
@@ -13441,7 +13456,7 @@ class LocalParticipant extends Participant {
13441
13456
 
13442
13457
 
13443
13458
  async publishTrack(track, options) {
13444
- var _a, _b, _c, _d, _e, _f;
13459
+ var _a, _b, _c, _d, _e, _f, _g;
13445
13460
 
13446
13461
  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
13462
 
@@ -13514,7 +13529,19 @@ class LocalParticipant extends Participant {
13514
13529
  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
13530
 
13516
13531
  req.width = width !== null && width !== void 0 ? width : 0;
13517
- req.height = height !== null && height !== void 0 ? height : 0;
13532
+ req.height = height !== null && height !== void 0 ? height : 0; // for svc codecs, disable simulcast and enable scalability L3T3
13533
+ // by default
13534
+
13535
+ if (track instanceof LocalVideoTrack) {
13536
+ if ((opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'vp9' || (opts === null || opts === void 0 ? void 0 : opts.videoCodec) === 'av1') {
13537
+ opts.simulcast = false;
13538
+ opts.scalabilityMode = (_g = opts.scalabilityMode) !== null && _g !== void 0 ? _g : 'L3T3';
13539
+ } else {
13540
+ // other codecs, unset scalability
13541
+ opts.scalabilityMode = undefined;
13542
+ }
13543
+ }
13544
+
13518
13545
  encodings = computeVideoEncodings(track.source === Track.Source.ScreenShare, width, height, opts);
13519
13546
  req.layers = videoLayersFromEncodings(req.width, req.height, encodings);
13520
13547
  } else if (track.kind === Track.Kind.Audio && opts.audioBitrate) {
@@ -13523,6 +13550,10 @@ class LocalParticipant extends Participant {
13523
13550
  }];
13524
13551
  }
13525
13552
 
13553
+ if (!this.engine || this.engine.isClosed) {
13554
+ throw new UnexpectedConnectionState('cannot publish track when not connected');
13555
+ }
13556
+
13526
13557
  const ti = await this.engine.addTrack(req);
13527
13558
  const publication = new LocalTrackPublication(track.kind, ti, track);
13528
13559
  track.sid = ti.sid;
@@ -13544,6 +13575,11 @@ class LocalParticipant extends Participant {
13544
13575
  }
13545
13576
 
13546
13577
  const transceiver = this.engine.publisher.pc.addTransceiver(track.mediaStreamTrack, transceiverInit);
13578
+
13579
+ if (opts.videoCodec) {
13580
+ this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
13581
+ }
13582
+
13547
13583
  this.engine.negotiate(); // store RTPSender
13548
13584
 
13549
13585
  track.sender = transceiver.sender;
@@ -13554,10 +13590,6 @@ class LocalParticipant extends Participant {
13554
13590
  track.startMonitor();
13555
13591
  }
13556
13592
 
13557
- if (opts.videoCodec) {
13558
- this.setPreferredCodec(transceiver, track.kind, opts.videoCodec);
13559
- }
13560
-
13561
13593
  this.addTrackPublication(publication); // send event for publication
13562
13594
 
13563
13595
  this.emit(ParticipantEvent.LocalTrackPublished, publication);
@@ -13739,21 +13771,38 @@ class LocalParticipant extends Participant {
13739
13771
 
13740
13772
  const cap = RTCRtpSender.getCapabilities(kind);
13741
13773
  if (!cap) return;
13742
- const selected = cap.codecs.find(c => {
13774
+ let selected;
13775
+ const codecs = [];
13776
+ cap.codecs.forEach(c => {
13743
13777
  const codec = c.mimeType.toLowerCase();
13744
- const matchesVideoCodec = codec === "video/".concat(videoCodec); // for h264 codecs that have sdpFmtpLine available, use only if the
13778
+ const matchesVideoCodec = codec === "video/".concat(videoCodec);
13779
+
13780
+ if (selected !== undefined) {
13781
+ codecs.push(c);
13782
+ return;
13783
+ } // for h264 codecs that have sdpFmtpLine available, use only if the
13745
13784
  // profile-level-id is 42e01f for cross-browser compatibility
13746
13785
 
13786
+
13747
13787
  if (videoCodec === 'h264' && c.sdpFmtpLine) {
13748
- return matchesVideoCodec && c.sdpFmtpLine.includes('profile-level-id=42e01f');
13788
+ if (matchesVideoCodec && c.sdpFmtpLine.includes('profile-level-id=42e01f')) {
13789
+ selected = c;
13790
+ return;
13791
+ }
13749
13792
  }
13750
13793
 
13751
- return matchesVideoCodec || codec === 'audio/opus';
13794
+ if (matchesVideoCodec || codec === 'audio/opus') {
13795
+ selected = c;
13796
+ return;
13797
+ }
13798
+
13799
+ codecs.push(c);
13752
13800
  });
13753
13801
 
13754
13802
  if (selected && 'setCodecPreferences' in transceiver) {
13755
13803
  // @ts-ignore
13756
- transceiver.setCodecPreferences([selected]);
13804
+ codecs.unshift(selected);
13805
+ transceiver.setCodecPreferences(codecs);
13757
13806
  }
13758
13807
  }
13759
13808
  /** @internal */
@@ -17354,7 +17403,7 @@ class SignalClient {
17354
17403
  this.requestQueue = new Queue();
17355
17404
  }
17356
17405
 
17357
- async join(url, token, opts) {
17406
+ async join(url, token, opts, abortSignal) {
17358
17407
  // during a full reconnect, we'd want to start the sequence even if currently
17359
17408
  // connected
17360
17409
  this.isConnected = false;
@@ -17362,7 +17411,7 @@ class SignalClient {
17362
17411
  autoSubscribe: opts === null || opts === void 0 ? void 0 : opts.autoSubscribe,
17363
17412
  publishOnly: opts === null || opts === void 0 ? void 0 : opts.publishOnly,
17364
17413
  adaptiveStream: opts === null || opts === void 0 ? void 0 : opts.adaptiveStream
17365
- });
17414
+ }, abortSignal);
17366
17415
  return res;
17367
17416
  }
17368
17417
 
@@ -17373,7 +17422,7 @@ class SignalClient {
17373
17422
  });
17374
17423
  }
17375
17424
 
17376
- connect(url, token, opts) {
17425
+ connect(url, token, opts, abortSignal) {
17377
17426
  if (url.startsWith('http')) {
17378
17427
  url = url.replace('http', 'ws');
17379
17428
  } // strip trailing slash
@@ -17384,6 +17433,17 @@ class SignalClient {
17384
17433
  const clientInfo = getClientInfo();
17385
17434
  const params = createConnectionParams(token, clientInfo, opts);
17386
17435
  return new Promise((resolve, reject) => {
17436
+ const abortHandler = () => {
17437
+ ws.close();
17438
+ this.close();
17439
+ reject(new ConnectionError('room connection has been cancelled'));
17440
+ };
17441
+
17442
+ if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
17443
+ abortHandler();
17444
+ }
17445
+
17446
+ abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.addEventListener('abort', abortHandler);
17387
17447
  livekitLogger.debug("connecting to ".concat(url + params));
17388
17448
  this.ws = undefined;
17389
17449
  const ws = new WebSocket(url + params);
@@ -17439,6 +17499,7 @@ class SignalClient {
17439
17499
  // handle join message only
17440
17500
  if (msg.join) {
17441
17501
  this.isConnected = true;
17502
+ abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.removeEventListener('abort', abortHandler);
17442
17503
  resolve(msg.join);
17443
17504
  } else {
17444
17505
  reject(new ConnectionError('did not receive join response'));
@@ -17861,7 +17922,7 @@ class RTCEngine extends events.exports.EventEmitter {
17861
17922
  this.rtcConfig = {};
17862
17923
  this.subscriberPrimary = false;
17863
17924
  this.pcState = PCState.New;
17864
- this.isClosed = true;
17925
+ this._isClosed = true;
17865
17926
  this.pendingTrackResolvers = {}; // true if publisher connection has already been established.
17866
17927
  // this is helpful to know if we need to restart ICE on the publisher connection
17867
17928
 
@@ -17932,7 +17993,7 @@ class RTCEngine extends events.exports.EventEmitter {
17932
17993
 
17933
17994
 
17934
17995
  this.handleDisconnect = connection => {
17935
- if (this.isClosed) {
17996
+ if (this._isClosed) {
17936
17997
  return;
17937
17998
  }
17938
17999
 
@@ -17947,7 +18008,7 @@ class RTCEngine extends events.exports.EventEmitter {
17947
18008
  setTimeout(async () => {
17948
18009
  var _a;
17949
18010
 
17950
- if (this.isClosed) {
18011
+ if (this._isClosed) {
17951
18012
  return;
17952
18013
  }
17953
18014
 
@@ -18000,12 +18061,16 @@ class RTCEngine extends events.exports.EventEmitter {
18000
18061
  this.client = new SignalClient();
18001
18062
  }
18002
18063
 
18003
- async join(url, token, opts) {
18064
+ get isClosed() {
18065
+ return this._isClosed;
18066
+ }
18067
+
18068
+ async join(url, token, opts, abortSignal) {
18004
18069
  this.url = url;
18005
18070
  this.token = token;
18006
18071
  this.signalOpts = opts;
18007
- const joinResponse = await this.client.join(url, token, opts);
18008
- this.isClosed = false;
18072
+ const joinResponse = await this.client.join(url, token, opts, abortSignal);
18073
+ this._isClosed = false;
18009
18074
  this.subscriberPrimary = joinResponse.subscriberPrimary;
18010
18075
 
18011
18076
  if (!this.publisher) {
@@ -18022,7 +18087,7 @@ class RTCEngine extends events.exports.EventEmitter {
18022
18087
  }
18023
18088
 
18024
18089
  close() {
18025
- this.isClosed = true;
18090
+ this._isClosed = true;
18026
18091
  this.removeAllListeners();
18027
18092
 
18028
18093
  if (this.publisher && this.publisher.pc.signalingState !== 'closed') {
@@ -18525,21 +18590,25 @@ const publishDefaults = {
18525
18590
  };
18526
18591
  const audioDefaults = {
18527
18592
  autoGainControl: true,
18528
- channelCount: 1,
18529
18593
  echoCancellation: true,
18530
18594
  noiseSuppression: true
18531
18595
  };
18532
18596
  const videoDefaults = {
18533
- resolution: VideoPresets.h540.resolution
18597
+ resolution: VideoPresets.h720.resolution
18534
18598
  };
18535
18599
 
18536
- var RoomState;
18600
+ var ConnectionState;
18537
18601
 
18538
- (function (RoomState) {
18539
- RoomState["Disconnected"] = "disconnected";
18540
- RoomState["Connected"] = "connected";
18541
- RoomState["Reconnecting"] = "reconnecting";
18542
- })(RoomState || (RoomState = {}));
18602
+ (function (ConnectionState) {
18603
+ ConnectionState["Disconnected"] = "disconnected";
18604
+ ConnectionState["Connecting"] = "connecting";
18605
+ ConnectionState["Connected"] = "connected";
18606
+ ConnectionState["Reconnecting"] = "reconnecting";
18607
+ })(ConnectionState || (ConnectionState = {}));
18608
+ /** @deprecated RoomState has been renamed to [[ConnectionState]] */
18609
+
18610
+
18611
+ const RoomState = ConnectionState;
18543
18612
  /**
18544
18613
  * In LiveKit, a room is the logical grouping for a list of participants.
18545
18614
  * Participants in a room can publish tracks, and subscribe to others' tracks.
@@ -18549,7 +18618,6 @@ var RoomState;
18549
18618
  * @noInheritDoc
18550
18619
  */
18551
18620
 
18552
-
18553
18621
  class Room extends events.exports.EventEmitter {
18554
18622
  /**
18555
18623
  * Creates a new Room, the primary construct for a LiveKit session.
@@ -18562,7 +18630,7 @@ class Room extends events.exports.EventEmitter {
18562
18630
 
18563
18631
  super();
18564
18632
  _this = this;
18565
- this.state = RoomState.Disconnected;
18633
+ this.state = ConnectionState.Disconnected;
18566
18634
  /**
18567
18635
  * list of participants that are actively speaking. when this changes
18568
18636
  * a [[RoomEvent.ActiveSpeakersChanged]] event is fired
@@ -18585,9 +18653,15 @@ class Room extends events.exports.EventEmitter {
18585
18653
  var _a, _b; // guard against calling connect
18586
18654
 
18587
18655
 
18588
- if (this.state !== RoomState.Disconnected) {
18656
+ if (this.state !== ConnectionState.Disconnected) {
18589
18657
  livekitLogger.warn("already connected to room ".concat(this.name));
18590
18658
  return;
18659
+ }
18660
+
18661
+ this.setAndEmitConnectionState(ConnectionState.Connecting);
18662
+
18663
+ if (!this.abortController || this.abortController.signal.aborted) {
18664
+ this.abortController = new AbortController();
18591
18665
  } // recreate engine if previously disconnected
18592
18666
 
18593
18667
 
@@ -18605,7 +18679,7 @@ class Room extends events.exports.EventEmitter {
18605
18679
  autoSubscribe: opts === null || opts === void 0 ? void 0 : opts.autoSubscribe,
18606
18680
  publishOnly: opts === null || opts === void 0 ? void 0 : opts.publishOnly,
18607
18681
  adaptiveStream: typeof ((_a = this.options) === null || _a === void 0 ? void 0 : _a.adaptiveStream) === 'object' ? true : (_b = this.options) === null || _b === void 0 ? void 0 : _b.adaptiveStream
18608
- });
18682
+ }, this.abortController.signal);
18609
18683
  livekitLogger.debug("connected to Livekit Server version: ".concat(joinResponse.serverVersion, ", region: ").concat(joinResponse.serverRegion));
18610
18684
 
18611
18685
  if (!joinResponse.serverVersion) {
@@ -18618,15 +18692,12 @@ class Room extends events.exports.EventEmitter {
18618
18692
  this.options.dynacast = false;
18619
18693
  }
18620
18694
 
18621
- this.state = RoomState.Connected;
18622
18695
  const pi = joinResponse.participant;
18623
18696
  this.localParticipant.sid = pi.sid;
18624
18697
  this.localParticipant.identity = pi.identity;
18625
18698
  this.localParticipant.updateInfo(pi); // forward metadata changed for the local participant
18626
18699
 
18627
- this.localParticipant.on(ParticipantEvent.MetadataChanged, metadata => {
18628
- this.emit(RoomEvent.MetadataChanged, metadata, this.localParticipant);
18629
- }).on(ParticipantEvent.ParticipantMetadataChanged, metadata => {
18700
+ this.localParticipant.on(ParticipantEvent.ParticipantMetadataChanged, metadata => {
18630
18701
  this.emit(RoomEvent.ParticipantMetadataChanged, metadata, this.localParticipant);
18631
18702
  }).on(ParticipantEvent.TrackMuted, pub => {
18632
18703
  this.emit(RoomEvent.TrackMuted, pub, this.localParticipant);
@@ -18650,29 +18721,48 @@ class Room extends events.exports.EventEmitter {
18650
18721
  this.name = joinResponse.room.name;
18651
18722
  this.sid = joinResponse.room.sid;
18652
18723
  this.metadata = joinResponse.room.metadata;
18653
- this.emit(RoomEvent.StateChanged, this.state);
18654
18724
  } catch (err) {
18655
18725
  this.engine.close();
18726
+ this.setAndEmitConnectionState(ConnectionState.Disconnected);
18656
18727
  throw err;
18657
18728
  } // don't return until ICE connected
18658
18729
 
18659
18730
 
18660
18731
  return new Promise((resolve, reject) => {
18732
+ var _a, _b;
18733
+
18661
18734
  const connectTimeout = setTimeout(() => {
18662
18735
  // timeout
18663
18736
  this.engine.close();
18737
+ this.setAndEmitConnectionState(ConnectionState.Disconnected);
18664
18738
  reject(new ConnectionError('could not connect after timeout'));
18665
18739
  }, maxICEConnectTimeout);
18740
+
18741
+ const abortHandler = () => {
18742
+ livekitLogger.warn('closing engine');
18743
+ clearTimeout(connectTimeout);
18744
+ this.engine.close();
18745
+ this.setAndEmitConnectionState(ConnectionState.Disconnected);
18746
+ reject(new ConnectionError('room connection has been cancelled'));
18747
+ };
18748
+
18749
+ if ((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.aborted) {
18750
+ abortHandler();
18751
+ }
18752
+
18753
+ (_b = this.abortController) === null || _b === void 0 ? void 0 : _b.signal.addEventListener('abort', abortHandler);
18666
18754
  this.engine.once(EngineEvent.Connected, () => {
18667
- var _a;
18755
+ var _a, _b;
18668
18756
 
18669
- clearTimeout(connectTimeout); // also hook unload event
18757
+ clearTimeout(connectTimeout);
18758
+ (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal.removeEventListener('abort', abortHandler); // also hook unload event
18670
18759
 
18671
18760
  if (isWeb()) {
18672
18761
  window.addEventListener('beforeunload', this.onBeforeUnload);
18673
- (_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.addEventListener('devicechange', this.handleDeviceChange);
18762
+ (_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
18674
18763
  }
18675
18764
 
18765
+ this.setAndEmitConnectionState(ConnectionState.Connected);
18676
18766
  resolve(this);
18677
18767
  });
18678
18768
  });
@@ -18685,7 +18775,16 @@ class Room extends events.exports.EventEmitter {
18685
18775
  this.disconnect = function () {
18686
18776
  let stopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
18687
18777
 
18688
- // send leave
18778
+ var _a;
18779
+
18780
+ if (_this.state === ConnectionState.Connecting) {
18781
+ // try aborting pending connection attempt
18782
+ livekitLogger.warn('abort connection attempt');
18783
+ (_a = _this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
18784
+ return;
18785
+ } // send leave
18786
+
18787
+
18689
18788
  if (_this.engine) {
18690
18789
  _this.engine.client.sendLeave();
18691
18790
 
@@ -18704,9 +18803,8 @@ class Room extends events.exports.EventEmitter {
18704
18803
  };
18705
18804
 
18706
18805
  this.handleRestarting = () => {
18707
- this.state = RoomState.Reconnecting;
18708
- this.emit(RoomEvent.Reconnecting);
18709
- this.emit(RoomEvent.StateChanged, this.state); // also unwind existing participants & existing subscriptions
18806
+ this.setAndEmitConnectionState(ConnectionState.Reconnecting);
18807
+ this.emit(RoomEvent.Reconnecting); // also unwind existing participants & existing subscriptions
18710
18808
 
18711
18809
  for (const p of this.participants.values()) {
18712
18810
  this.handleParticipantDisconnected(p.sid, p);
@@ -18715,9 +18813,8 @@ class Room extends events.exports.EventEmitter {
18715
18813
 
18716
18814
  this.handleRestarted = async joinResponse => {
18717
18815
  livekitLogger.debug("reconnected to server region ".concat(joinResponse.serverRegion));
18718
- this.state = RoomState.Connected;
18719
- this.emit(RoomEvent.Reconnected);
18720
- this.emit(RoomEvent.StateChanged, this.state); // rehydrate participants
18816
+ this.setAndEmitConnectionState(ConnectionState.Connected);
18817
+ this.emit(RoomEvent.Reconnected); // rehydrate participants
18721
18818
 
18722
18819
  if (joinResponse.participant) {
18723
18820
  // with a restart, the sid will have changed, we'll map our understanding to it
@@ -18959,16 +19056,14 @@ class Room extends events.exports.EventEmitter {
18959
19056
  }).on(EngineEvent.Disconnected, () => {
18960
19057
  this.handleDisconnect();
18961
19058
  }).on(EngineEvent.ActiveSpeakersUpdate, this.handleActiveSpeakersUpdate).on(EngineEvent.DataPacketReceived, this.handleDataPacket).on(EngineEvent.Resuming, () => {
18962
- this.state = RoomState.Reconnecting;
19059
+ this.setAndEmitConnectionState(ConnectionState.Reconnecting);
18963
19060
  this.emit(RoomEvent.Reconnecting);
18964
- this.emit(RoomEvent.StateChanged, this.state);
18965
19061
  }).on(EngineEvent.Resumed, () => {
18966
- this.state = RoomState.Connected;
19062
+ this.setAndEmitConnectionState(ConnectionState.Connected);
18967
19063
  this.emit(RoomEvent.Reconnected);
18968
- this.emit(RoomEvent.StateChanged, this.state);
18969
19064
  this.updateSubscriptions();
18970
19065
  }).on(EngineEvent.SignalResumed, () => {
18971
- if (this.state === RoomState.Reconnecting) {
19066
+ if (this.state === ConnectionState.Reconnecting) {
18972
19067
  this.sendSyncState();
18973
19068
  }
18974
19069
  }).on(EngineEvent.Restarting, this.handleRestarting).on(EngineEvent.Restarted, this.handleRestarted);
@@ -19154,10 +19249,6 @@ class Room extends events.exports.EventEmitter {
19154
19249
 
19155
19250
  var _a;
19156
19251
 
19157
- if (this.state === RoomState.Disconnected) {
19158
- return;
19159
- }
19160
-
19161
19252
  this.participants.forEach(p => {
19162
19253
  p.tracks.forEach(pub => {
19163
19254
  p.unpublishTrack(pub.trackSid);
@@ -19188,9 +19279,8 @@ class Room extends events.exports.EventEmitter {
19188
19279
  (_a = navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.removeEventListener('devicechange', this.handleDeviceChange);
19189
19280
  }
19190
19281
 
19191
- this.state = RoomState.Disconnected;
19282
+ this.setAndEmitConnectionState(ConnectionState.Disconnected);
19192
19283
  this.emit(RoomEvent.Disconnected);
19193
- this.emit(RoomEvent.StateChanged, this.state);
19194
19284
  }
19195
19285
 
19196
19286
  handleParticipantDisconnected(sid, participant) {
@@ -19265,8 +19355,6 @@ class Room extends events.exports.EventEmitter {
19265
19355
  this.emit(RoomEvent.TrackMuted, pub, participant);
19266
19356
  }).on(ParticipantEvent.TrackUnmuted, pub => {
19267
19357
  this.emit(RoomEvent.TrackUnmuted, pub, participant);
19268
- }).on(ParticipantEvent.MetadataChanged, metadata => {
19269
- this.emit(RoomEvent.MetadataChanged, metadata, participant);
19270
19358
  }).on(ParticipantEvent.ParticipantMetadataChanged, metadata => {
19271
19359
  this.emit(RoomEvent.ParticipantMetadataChanged, metadata, participant);
19272
19360
  }).on(ParticipantEvent.ConnectionQualityChanged, quality => {
@@ -19328,6 +19416,15 @@ class Room extends events.exports.EventEmitter {
19328
19416
  }
19329
19417
  }
19330
19418
  }
19419
+ }
19420
+
19421
+ setAndEmitConnectionState(state) {
19422
+ if (state === this.state) {
19423
+ return;
19424
+ }
19425
+
19426
+ this.state = state;
19427
+ this.emit(RoomEvent.ConnectionStateChanged, this.state);
19331
19428
  } // /** @internal */
19332
19429
 
19333
19430
 
@@ -19345,101 +19442,6 @@ class Room extends events.exports.EventEmitter {
19345
19442
 
19346
19443
  }
19347
19444
 
19348
- /**
19349
- * @deprecated Use room.connect() instead
19350
- *
19351
- * Connects to a LiveKit room, shorthand for `new Room()` and [[Room.connect]]
19352
- *
19353
- * ```typescript
19354
- * connect('wss://myhost.livekit.io', token, {
19355
- * // publish audio and video tracks on joining
19356
- * audio: true,
19357
- * video: true,
19358
- * captureDefaults: {
19359
- * facingMode: 'user',
19360
- * },
19361
- * })
19362
- * ```
19363
- * @param url URL to LiveKit server
19364
- * @param token AccessToken, a JWT token that includes authentication and room details
19365
- * @param options
19366
- */
19367
-
19368
- async function connect(url, token, options) {
19369
- var _a, _b, _c, _d;
19370
-
19371
- options !== null && options !== void 0 ? options : options = {};
19372
-
19373
- if (options.adaptiveStream === undefined) {
19374
- options.adaptiveStream = options.autoManageVideo === true ? {} : undefined;
19375
- }
19376
-
19377
- setLogLevel((_a = options.logLevel) !== null && _a !== void 0 ? _a : LogLevel.warn);
19378
- const config = (_b = options.rtcConfig) !== null && _b !== void 0 ? _b : {};
19379
-
19380
- if (options.iceServers) {
19381
- config.iceServers = options.iceServers;
19382
- }
19383
-
19384
- const room = new Room(options); // connect to room
19385
-
19386
- await room.connect(url, token, options);
19387
- const publishAudio = (_c = options.audio) !== null && _c !== void 0 ? _c : false;
19388
- const publishVideo = (_d = options.video) !== null && _d !== void 0 ? _d : false;
19389
-
19390
- if (publishAudio || publishVideo) {
19391
- setTimeout(async () => {
19392
- // if publishing both
19393
- let err;
19394
-
19395
- if (publishAudio && publishVideo) {
19396
- try {
19397
- await room.localParticipant.enableCameraAndMicrophone();
19398
- } catch (e) {
19399
- const errKind = MediaDeviceFailure.getFailure(e);
19400
- livekitLogger.warn('received error while creating media', {
19401
- error: errKind
19402
- });
19403
-
19404
- if (e instanceof Error) {
19405
- livekitLogger.warn(e.message);
19406
- } // when it's a device issue, try to publish the other kind
19407
-
19408
-
19409
- if (errKind === MediaDeviceFailure.NotFound || errKind === MediaDeviceFailure.DeviceInUse) {
19410
- try {
19411
- await room.localParticipant.setMicrophoneEnabled(true);
19412
- } catch (audioErr) {
19413
- err = audioErr;
19414
- }
19415
- } else {
19416
- err = e;
19417
- }
19418
- }
19419
- } else if (publishAudio) {
19420
- try {
19421
- await room.localParticipant.setMicrophoneEnabled(true);
19422
- } catch (e) {
19423
- err = e;
19424
- }
19425
- } else if (publishVideo) {
19426
- try {
19427
- await room.localParticipant.setCameraEnabled(true);
19428
- } catch (e) {
19429
- err = e;
19430
- }
19431
- }
19432
-
19433
- if (err) {
19434
- room.emit(RoomEvent.MediaDevicesError, err);
19435
- livekitLogger.error('could not create media', err);
19436
- }
19437
- });
19438
- }
19439
-
19440
- return room;
19441
- }
19442
-
19443
19445
  /**
19444
19446
  * Creates a local video and audio track at the same time. When acquiring both
19445
19447
  * audio and video tracks together, it'll display a single permission prompt to
@@ -19513,7 +19515,7 @@ async function createLocalScreenTracks(options) {
19513
19515
  }
19514
19516
 
19515
19517
  if (options.resolution === undefined) {
19516
- options.resolution = VideoPresets.fhd.resolution;
19518
+ options.resolution = VideoPresets.h1080.resolution;
19517
19519
  }
19518
19520
 
19519
19521
  let videoConstraints = true;
@@ -19550,5 +19552,5 @@ async function createLocalScreenTracks(options) {
19550
19552
  return localTracks;
19551
19553
  }
19552
19554
 
19553
- export { AudioPresets, ConnectionError, ConnectionQuality, DataPacket_Kind, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, connect, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, protocolVersion, setLogExtension, setLogLevel, version };
19555
+ export { AudioPresets, ConnectionError, ConnectionQuality, ConnectionState, DataPacket_Kind, EngineEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, MediaDeviceFailure, Participant, ParticipantEvent, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, RoomState, ScreenSharePresets, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, detachTrack, protocolVersion, setLogExtension, setLogLevel, version };
19554
19556
  //# sourceMappingURL=livekit-client.esm.mjs.map