livekit-client 1.11.1 → 1.11.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -14187,7 +14187,7 @@ function getMatch(exp, ua) {
14187
14187
  return match && match.length >= id && match[id] || '';
14188
14188
  }
14189
14189
 
14190
- var version$1 = "1.11.1";
14190
+ var version$1 = "1.11.2";
14191
14191
 
14192
14192
  const version = version$1;
14193
14193
  const protocolVersion = 9;
@@ -14636,6 +14636,27 @@ class Mutex {
14636
14636
  return willUnlock;
14637
14637
  }
14638
14638
  }
14639
+ function unwrapConstraint(constraint) {
14640
+ if (typeof constraint === 'string') {
14641
+ return constraint;
14642
+ }
14643
+ if (Array.isArray(constraint)) {
14644
+ return constraint[0];
14645
+ }
14646
+ if (constraint.exact) {
14647
+ if (Array.isArray(constraint.exact)) {
14648
+ return constraint.exact[0];
14649
+ }
14650
+ return constraint.exact;
14651
+ }
14652
+ if (constraint.ideal) {
14653
+ if (Array.isArray(constraint.ideal)) {
14654
+ return constraint.ideal[0];
14655
+ }
14656
+ return constraint.ideal;
14657
+ }
14658
+ throw Error('could not unwrap constraint');
14659
+ }
14639
14660
 
14640
14661
  var QueueTaskStatus;
14641
14662
  (function (QueueTaskStatus) {
@@ -16734,6 +16755,11 @@ var RoomEvent;
16734
16755
  * args: (isLow: boolean, kind: [[DataPacket_Kind]])
16735
16756
  */
16736
16757
  RoomEvent["DCBufferStatusChanged"] = "dcBufferStatusChanged";
16758
+ /**
16759
+ * Triggered by a call to room.switchActiveDevice
16760
+ * args: (kind: MediaDeviceKind, deviceId: string)
16761
+ */
16762
+ RoomEvent["ActiveDeviceChanged"] = "activeDeviceChanged";
16737
16763
  })(RoomEvent || (RoomEvent = {}));
16738
16764
  var ParticipantEvent;
16739
16765
  (function (ParticipantEvent) {
@@ -18564,7 +18590,7 @@ class LocalTrack extends Track {
18564
18590
  throw new TrackInvalidError('unable to replace an unpublished track');
18565
18591
  }
18566
18592
  livekitLogger.debug('replace MediaStreamTrack');
18567
- this.setMediaStreamTrack(track);
18593
+ yield this.setMediaStreamTrack(track);
18568
18594
  // this must be synced *after* setting mediaStreamTrack above, since it relies
18569
18595
  // on the previous state in order to cleanup
18570
18596
  this.providedByUser = userProvidedTrack;
@@ -18604,7 +18630,7 @@ class LocalTrack extends Track {
18604
18630
  const newTrack = mediaStream.getTracks()[0];
18605
18631
  newTrack.addEventListener('ended', this.handleEnded);
18606
18632
  livekitLogger.debug('re-acquired MediaStreamTrack');
18607
- this.setMediaStreamTrack(newTrack);
18633
+ yield this.setMediaStreamTrack(newTrack);
18608
18634
  this.constraints = constraints;
18609
18635
  if (this.processor) {
18610
18636
  const processor = this.processor;
@@ -18766,12 +18792,13 @@ class LocalAudioTrack extends LocalTrack {
18766
18792
  setDeviceId(deviceId) {
18767
18793
  return __awaiter(this, void 0, void 0, function* () {
18768
18794
  if (this.constraints.deviceId === deviceId) {
18769
- return;
18795
+ return true;
18770
18796
  }
18771
18797
  this.constraints.deviceId = deviceId;
18772
18798
  if (!this.isMuted) {
18773
18799
  yield this.restartTrack();
18774
18800
  }
18801
+ return unwrapConstraint(deviceId) === this.mediaStreamTrack.getSettings().deviceId;
18775
18802
  });
18776
18803
  }
18777
18804
  mute() {
@@ -19359,8 +19386,8 @@ class LocalVideoTrack extends LocalTrack {
19359
19386
  }
19360
19387
  setDeviceId(deviceId) {
19361
19388
  return __awaiter(this, void 0, void 0, function* () {
19362
- if (this.constraints.deviceId === deviceId) {
19363
- return;
19389
+ if (this.constraints.deviceId === deviceId && this._mediaStreamTrack.getSettings().deviceId === unwrapConstraint(deviceId)) {
19390
+ return true;
19364
19391
  }
19365
19392
  this.constraints.deviceId = deviceId;
19366
19393
  // when video is muted, underlying media stream track is stopped and
@@ -19368,6 +19395,7 @@ class LocalVideoTrack extends LocalTrack {
19368
19395
  if (!this.isMuted) {
19369
19396
  yield this.restartTrack();
19370
19397
  }
19398
+ return unwrapConstraint(deviceId) === this._mediaStreamTrack.getSettings().deviceId;
19371
19399
  });
19372
19400
  }
19373
19401
  restartTrack(options) {
@@ -19862,7 +19890,6 @@ class RemoteVideoTrack extends RemoteTrack {
19862
19890
  constructor(mediaTrack, sid, receiver, adaptiveStreamSettings) {
19863
19891
  super(mediaTrack, sid, Track.Kind.Video, receiver);
19864
19892
  this.elementInfos = [];
19865
- this.isObserved = false;
19866
19893
  this.monitorReceiver = () => __awaiter(this, void 0, void 0, function* () {
19867
19894
  if (!this.receiver) {
19868
19895
  this._currentBitrate = 0;
@@ -19882,10 +19909,10 @@ class RemoteVideoTrack extends RemoteTrack {
19882
19909
  get isAdaptiveStream() {
19883
19910
  return this.adaptiveStreamSettings !== undefined;
19884
19911
  }
19912
+ /**
19913
+ * Note: When using adaptiveStream, you need to use remoteVideoTrack.attach() to add the track to a HTMLVideoElement, otherwise your video tracks might never start
19914
+ */
19885
19915
  get mediaStreamTrack() {
19886
- if (this.isAdaptiveStream && !this.isObserved) {
19887
- 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');
19888
- }
19889
19916
  return this._mediaStreamTrack;
19890
19917
  }
19891
19918
  /** @internal */
@@ -19934,7 +19961,6 @@ class RemoteVideoTrack extends RemoteTrack {
19934
19961
  // the tab comes into focus for the first time.
19935
19962
  this.debouncedHandleResize();
19936
19963
  this.updateVisibility();
19937
- this.isObserved = true;
19938
19964
  } else {
19939
19965
  livekitLogger.warn('visibility resize observer not triggered');
19940
19966
  }
@@ -22062,6 +22088,7 @@ class Room extends EventEmitter {
22062
22088
  */
22063
22089
  constructor(options) {
22064
22090
  var _this;
22091
+ var _a;
22065
22092
  super();
22066
22093
  _this = this;
22067
22094
  this.state = ConnectionState.Disconnected;
@@ -22087,7 +22114,7 @@ class Room extends EventEmitter {
22087
22114
  this.setAndEmitConnectionState(ConnectionState.Connecting);
22088
22115
  const urlProvider = new RegionUrlProvider(url, token);
22089
22116
  const connectFn = (resolve, reject, regionUrl) => __awaiter(this, void 0, void 0, function* () {
22090
- var _a;
22117
+ var _b;
22091
22118
  if (this.abortController) {
22092
22119
  this.abortController.abort();
22093
22120
  }
@@ -22102,7 +22129,7 @@ class Room extends EventEmitter {
22102
22129
  if (isCloud(new URL(url)) && e instanceof ConnectionError && e.reason !== 3 /* ConnectionErrorReason.Cancelled */) {
22103
22130
  let nextUrl = null;
22104
22131
  try {
22105
- nextUrl = yield urlProvider.getNextBestRegionUrl((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal);
22132
+ nextUrl = yield urlProvider.getNextBestRegionUrl((_b = this.abortController) === null || _b === void 0 ? void 0 : _b.signal);
22106
22133
  } catch (error) {
22107
22134
  if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
22108
22135
  reject(error);
@@ -22164,7 +22191,7 @@ class Room extends EventEmitter {
22164
22191
  }
22165
22192
  };
22166
22193
  this.attemptConnection = (url, token, opts, abortController) => __awaiter(this, void 0, void 0, function* () {
22167
- var _b;
22194
+ var _c;
22168
22195
  if (this.state === ConnectionState.Reconnecting) {
22169
22196
  livekitLogger.info('Reconnection attempt replaced by new connection attempt');
22170
22197
  // make sure we close and recreate the existing engine in order to get rid of any potentially ongoing reconnection attempts
@@ -22223,7 +22250,7 @@ class Room extends EventEmitter {
22223
22250
  }
22224
22251
  if (isWeb()) {
22225
22252
  document.addEventListener('freeze', this.onPageLeave);
22226
- (_b = navigator.mediaDevices) === null || _b === void 0 ? void 0 : _b.addEventListener('devicechange', this.handleDeviceChange);
22253
+ (_c = navigator.mediaDevices) === null || _c === void 0 ? void 0 : _c.addEventListener('devicechange', this.handleDeviceChange);
22227
22254
  }
22228
22255
  this.setAndEmitConnectionState(ConnectionState.Connected);
22229
22256
  this.emit(RoomEvent.Connected);
@@ -22235,7 +22262,7 @@ class Room extends EventEmitter {
22235
22262
  this.disconnect = function () {
22236
22263
  let stopTracks = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
22237
22264
  return __awaiter(_this, void 0, void 0, function* () {
22238
- var _c, _d, _e, _f;
22265
+ var _d, _e, _f, _g;
22239
22266
  const unlock = yield this.disconnectLock.lock();
22240
22267
  try {
22241
22268
  if (this.state === ConnectionState.Disconnected) {
@@ -22248,13 +22275,13 @@ class Room extends EventEmitter {
22248
22275
  if (this.state === ConnectionState.Connecting || this.state === ConnectionState.Reconnecting) {
22249
22276
  // try aborting pending connection attempt
22250
22277
  livekitLogger.warn('abort connection attempt');
22251
- (_c = this.abortController) === null || _c === void 0 ? void 0 : _c.abort();
22278
+ (_d = this.abortController) === null || _d === void 0 ? void 0 : _d.abort();
22252
22279
  // in case the abort controller didn't manage to cancel the connection attempt, reject the connect promise explicitly
22253
- (_e = (_d = this.connectFuture) === null || _d === void 0 ? void 0 : _d.reject) === null || _e === void 0 ? void 0 : _e.call(_d, new ConnectionError('Client initiated disconnect'));
22280
+ (_f = (_e = this.connectFuture) === null || _e === void 0 ? void 0 : _e.reject) === null || _f === void 0 ? void 0 : _f.call(_e, new ConnectionError('Client initiated disconnect'));
22254
22281
  this.connectFuture = undefined;
22255
22282
  }
22256
22283
  // send leave
22257
- if ((_f = this.engine) === null || _f === void 0 ? void 0 : _f.client.isConnected) {
22284
+ if ((_g = this.engine) === null || _g === void 0 ? void 0 : _g.client.isConnected) {
22258
22285
  yield this.engine.client.sendLeave();
22259
22286
  }
22260
22287
  // close engine (also closes client)
@@ -22324,7 +22351,7 @@ class Room extends EventEmitter {
22324
22351
  livekitLogger.debug("fully reconnected to server", {
22325
22352
  region: joinResponse.serverRegion
22326
22353
  });
22327
- } catch (_g) {
22354
+ } catch (_h) {
22328
22355
  // reconnection failed, handleDisconnect is being invoked already, just return here
22329
22356
  return;
22330
22357
  }
@@ -22549,6 +22576,16 @@ class Room extends EventEmitter {
22549
22576
  this.options.publishDefaults = Object.assign(Object.assign({}, publishDefaults), options === null || options === void 0 ? void 0 : options.publishDefaults);
22550
22577
  this.maybeCreateEngine();
22551
22578
  this.disconnectLock = new Mutex();
22579
+ this.activeDeviceMap = new Map();
22580
+ if (this.options.videoCaptureDefaults.deviceId) {
22581
+ this.activeDeviceMap.set('videoinput', unwrapConstraint(this.options.videoCaptureDefaults.deviceId));
22582
+ }
22583
+ if (this.options.audioCaptureDefaults.deviceId) {
22584
+ this.activeDeviceMap.set('audioinput', unwrapConstraint(this.options.audioCaptureDefaults.deviceId));
22585
+ }
22586
+ if ((_a = this.options.audioOutput) === null || _a === void 0 ? void 0 : _a.deviceId) {
22587
+ this.switchActiveDevice('audiooutput', unwrapConstraint(this.options.audioOutput.deviceId));
22588
+ }
22552
22589
  this.localParticipant = new LocalParticipant('', '', this.engine, this.options);
22553
22590
  }
22554
22591
  /**
@@ -22814,15 +22851,16 @@ class Room extends EventEmitter {
22814
22851
  }
22815
22852
  /**
22816
22853
  * Returns the active audio output device used in this room.
22817
- *
22818
- * Note: to get the active `audioinput` or `videoinput` use [[LocalTrack.getDeviceId()]]
22819
- *
22820
22854
  * @return the previously successfully set audio output device ID or an empty string if the default device is used.
22855
+ * @deprecated use `getActiveDevice('audiooutput')` instead
22821
22856
  */
22822
22857
  getActiveAudioOutputDevice() {
22823
22858
  var _a, _b;
22824
22859
  return (_b = (_a = this.options.audioOutput) === null || _a === void 0 ? void 0 : _a.deviceId) !== null && _b !== void 0 ? _b : '';
22825
22860
  }
22861
+ getActiveDevice(kind) {
22862
+ return this.activeDeviceMap.get(kind);
22863
+ }
22826
22864
  /**
22827
22865
  * Switches all active devices used in this room to the given device.
22828
22866
  *
@@ -22835,21 +22873,24 @@ class Room extends EventEmitter {
22835
22873
  */
22836
22874
  switchActiveDevice(kind, deviceId) {
22837
22875
  let exact = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
22838
- var _a;
22839
- var _b;
22876
+ var _a, _b;
22877
+ var _c;
22840
22878
  return __awaiter(this, void 0, void 0, function* () {
22879
+ let deviceHasChanged = false;
22880
+ let success = true;
22841
22881
  const deviceConstraint = exact ? {
22842
22882
  exact: deviceId
22843
22883
  } : deviceId;
22844
22884
  if (kind === 'audioinput') {
22845
22885
  const prevDeviceId = this.options.audioCaptureDefaults.deviceId;
22846
22886
  this.options.audioCaptureDefaults.deviceId = deviceConstraint;
22887
+ deviceHasChanged = prevDeviceId !== deviceConstraint;
22847
22888
  const tracks = Array.from(this.localParticipant.audioTracks.values()).filter(track => track.source === Track.Source.Microphone);
22848
22889
  try {
22849
- yield Promise.all(tracks.map(t => {
22890
+ success = (yield Promise.all(tracks.map(t => {
22850
22891
  var _a;
22851
22892
  return (_a = t.audioTrack) === null || _a === void 0 ? void 0 : _a.setDeviceId(deviceConstraint);
22852
- }));
22893
+ }))).every(val => val === true);
22853
22894
  } catch (e) {
22854
22895
  this.options.audioCaptureDefaults.deviceId = prevDeviceId;
22855
22896
  throw e;
@@ -22857,33 +22898,44 @@ class Room extends EventEmitter {
22857
22898
  } else if (kind === 'videoinput') {
22858
22899
  const prevDeviceId = this.options.videoCaptureDefaults.deviceId;
22859
22900
  this.options.videoCaptureDefaults.deviceId = deviceConstraint;
22901
+ deviceHasChanged = prevDeviceId !== deviceConstraint;
22860
22902
  const tracks = Array.from(this.localParticipant.videoTracks.values()).filter(track => track.source === Track.Source.Camera);
22861
22903
  try {
22862
- yield Promise.all(tracks.map(t => {
22904
+ success = (yield Promise.all(tracks.map(t => {
22863
22905
  var _a;
22864
22906
  return (_a = t.videoTrack) === null || _a === void 0 ? void 0 : _a.setDeviceId(deviceConstraint);
22865
- }));
22907
+ }))).every(val => val === true);
22866
22908
  } catch (e) {
22867
22909
  this.options.videoCaptureDefaults.deviceId = prevDeviceId;
22868
22910
  throw e;
22869
22911
  }
22870
22912
  } else if (kind === 'audiooutput') {
22871
- // TODO add support for webaudio mix once the API becomes available https://github.com/WebAudio/web-audio-api/pull/2498
22872
- if (!supportsSetSinkId()) {
22913
+ if (!supportsSetSinkId() && !this.options.expWebAudioMix || this.audioContext && !('setSinkId' in this.audioContext)) {
22873
22914
  throw new Error('cannot switch audio output, setSinkId not supported');
22874
22915
  }
22875
- (_a = (_b = this.options).audioOutput) !== null && _a !== void 0 ? _a : _b.audioOutput = {};
22916
+ (_a = (_c = this.options).audioOutput) !== null && _a !== void 0 ? _a : _c.audioOutput = {};
22876
22917
  const prevDeviceId = this.options.audioOutput.deviceId;
22877
22918
  this.options.audioOutput.deviceId = deviceId;
22919
+ deviceHasChanged = prevDeviceId !== deviceConstraint;
22878
22920
  try {
22879
- yield Promise.all(Array.from(this.participants.values()).map(p => p.setAudioOutput({
22880
- deviceId
22881
- })));
22921
+ if (this.options.expWebAudioMix) {
22922
+ // @ts-expect-error setSinkId is not yet in the typescript type of AudioContext
22923
+ (_b = this.audioContext) === null || _b === void 0 ? void 0 : _b.setSinkId(deviceId);
22924
+ } else {
22925
+ yield Promise.all(Array.from(this.participants.values()).map(p => p.setAudioOutput({
22926
+ deviceId
22927
+ })));
22928
+ }
22882
22929
  } catch (e) {
22883
22930
  this.options.audioOutput.deviceId = prevDeviceId;
22884
22931
  throw e;
22885
22932
  }
22886
22933
  }
22934
+ if (deviceHasChanged && success) {
22935
+ this.activeDeviceMap.set(kind, deviceId);
22936
+ this.emit(RoomEvent.ActiveDeviceChanged, kind, deviceId);
22937
+ }
22938
+ return success;
22887
22939
  });
22888
22940
  }
22889
22941
  setupLocalParticipantEvents() {