@stream-io/video-client 0.4.1 → 0.4.3

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.
package/dist/index.cjs.js CHANGED
@@ -6587,11 +6587,8 @@ class Publisher {
6587
6587
  ? transceiver.sender.track.stop()
6588
6588
  : (transceiver.sender.track.enabled = false);
6589
6589
  // We don't need to notify SFU if unpublishing in response to remote soft mute
6590
- if (!this.state.localParticipant?.publishedTracks.includes(trackType)) {
6591
- return;
6592
- }
6593
- else {
6594
- return this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
6590
+ if (this.state.localParticipant?.publishedTracks.includes(trackType)) {
6591
+ await this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
6595
6592
  }
6596
6593
  }
6597
6594
  };
@@ -9979,22 +9976,43 @@ const CallTypes = new CallTypesRegistry([
9979
9976
  }),
9980
9977
  ]);
9981
9978
 
9982
- const getDevices = (constraints) => {
9979
+ /**
9980
+ * Returns an Observable that emits the list of available devices
9981
+ * that meet the given constraints.
9982
+ *
9983
+ * @param constraints the constraints to use when requesting the devices.
9984
+ * @param kind the kind of devices to enumerate.
9985
+ */
9986
+ const getDevices = (constraints, kind) => {
9983
9987
  return new rxjs.Observable((subscriber) => {
9984
- navigator.mediaDevices
9985
- .getUserMedia(constraints)
9986
- .then((media) => {
9987
- // in Firefox, devices can be enumerated after userMedia is requested
9988
- // and permissions granted. Otherwise, device labels are empty
9989
- navigator.mediaDevices.enumerateDevices().then((devices) => {
9990
- subscriber.next(devices);
9991
- // If we stop the tracks before enumerateDevices -> the labels won't show up in Firefox
9992
- disposeOfMediaStream(media);
9993
- subscriber.complete();
9994
- });
9988
+ const enumerate = async () => {
9989
+ let devices = await navigator.mediaDevices.enumerateDevices();
9990
+ // some browsers report empty device labels (Firefox).
9991
+ // in that case, we need to request permissions (via getUserMedia)
9992
+ // to be able to get the device labels
9993
+ const needsGetUserMedia = devices.some((device) => device.kind === kind && device.label === '');
9994
+ if (needsGetUserMedia) {
9995
+ let mediaStream;
9996
+ try {
9997
+ mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
9998
+ devices = await navigator.mediaDevices.enumerateDevices();
9999
+ }
10000
+ finally {
10001
+ if (mediaStream)
10002
+ disposeOfMediaStream(mediaStream);
10003
+ }
10004
+ }
10005
+ return devices;
10006
+ };
10007
+ enumerate()
10008
+ .then((devices) => {
10009
+ // notify subscribers and complete
10010
+ subscriber.next(devices);
10011
+ subscriber.complete();
9995
10012
  })
9996
10013
  .catch((error) => {
9997
- getLogger(['devices'])('error', 'Failed to get devices', error);
10014
+ const logger = getLogger(['devices']);
10015
+ logger('error', 'Failed to enumerate devices', error);
9998
10016
  subscriber.error(error);
9999
10017
  });
10000
10018
  });
@@ -10008,7 +10026,7 @@ const checkIfAudioOutputChangeSupported = () => {
10008
10026
  if (typeof document === 'undefined')
10009
10027
  return false;
10010
10028
  const element = document.createElement('audio');
10011
- return element.sinkId !== undefined;
10029
+ return 'setSinkId' in element;
10012
10030
  };
10013
10031
  /**
10014
10032
  * The default constraints used to request audio devices.
@@ -10059,10 +10077,13 @@ const getDeviceChangeObserver = memoizedObservable(() => {
10059
10077
  }).pipe(rxjs.debounceTime(500), rxjs.concatMap(() => rxjs.from(navigator.mediaDevices.enumerateDevices())), rxjs.shareReplay(1));
10060
10078
  });
10061
10079
  const getAudioDevicesObserver = memoizedObservable(() => {
10062
- return rxjs.merge(getDevices(audioDeviceConstraints), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
10080
+ return rxjs.merge(getDevices(audioDeviceConstraints, 'audioinput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
10081
+ });
10082
+ const getAudioOutputDevicesObserver = memoizedObservable(() => {
10083
+ return rxjs.merge(getDevices(audioDeviceConstraints, 'audiooutput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
10063
10084
  });
10064
10085
  const getVideoDevicesObserver = memoizedObservable(() => {
10065
- return rxjs.merge(getDevices(videoDeviceConstraints), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
10086
+ return rxjs.merge(getDevices(videoDeviceConstraints, 'videoinput'), getDeviceChangeObserver()).pipe(rxjs.shareReplay(1));
10066
10087
  });
10067
10088
  /**
10068
10089
  * Prompts the user for a permission to use audio devices (if not already granted) and lists the available 'audioinput' devices, if devices are added/removed the list is updated.
@@ -10080,7 +10101,7 @@ const getVideoDevices = () => {
10080
10101
  * Prompts the user for a permission to use audio devices (if not already granted) and lists the available 'audiooutput' devices, if devices are added/removed the list is updated. Selecting 'audiooutput' device only makes sense if [the browser has support for changing audio output on 'audio' elements](#checkifaudiooutputchangesupported)
10081
10102
  */
10082
10103
  const getAudioOutputDevices = () => {
10083
- return getAudioDevicesObserver().pipe(rxjs.map((values) => values.filter((d) => d.kind === 'audiooutput')));
10104
+ return getAudioOutputDevicesObserver().pipe(rxjs.map((values) => values.filter((d) => d.kind === 'audiooutput')));
10084
10105
  };
10085
10106
  const getStream = async (constraints) => {
10086
10107
  try {
@@ -10285,9 +10306,8 @@ class InputMediaDeviceManager {
10285
10306
  * Starts stream.
10286
10307
  */
10287
10308
  async enable() {
10288
- if (this.state.status === 'enabled') {
10309
+ if (this.state.status === 'enabled')
10289
10310
  return;
10290
- }
10291
10311
  this.enablePromise = this.unmuteStream();
10292
10312
  try {
10293
10313
  await this.enablePromise;
@@ -10304,10 +10324,10 @@ class InputMediaDeviceManager {
10304
10324
  */
10305
10325
  async disable() {
10306
10326
  this.state.prevStatus = this.state.status;
10307
- if (this.state.status === 'disabled') {
10327
+ if (this.state.status === 'disabled')
10308
10328
  return;
10309
- }
10310
- this.disablePromise = this.muteStream(this.state.disableMode === 'stop-tracks');
10329
+ const stopTracks = this.state.disableMode === 'stop-tracks';
10330
+ this.disablePromise = this.muteStream(stopTracks);
10311
10331
  try {
10312
10332
  await this.disablePromise;
10313
10333
  this.state.setStatus('disabled');
@@ -10344,7 +10364,7 @@ class InputMediaDeviceManager {
10344
10364
  *
10345
10365
  * @param constraints the constraints to set.
10346
10366
  */
10347
- async setDefaultConstraints(constraints) {
10367
+ setDefaultConstraints(constraints) {
10348
10368
  this.state.setDefaultConstraints(constraints);
10349
10369
  }
10350
10370
  /**
@@ -10374,25 +10394,23 @@ class InputMediaDeviceManager {
10374
10394
  return this.state.mediaStream?.getTracks() ?? [];
10375
10395
  }
10376
10396
  async muteStream(stopTracks = true) {
10377
- if (!this.state.mediaStream) {
10397
+ if (!this.state.mediaStream)
10378
10398
  return;
10379
- }
10380
10399
  this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
10381
10400
  if (this.call.state.callingState === exports.CallingState.JOINED) {
10382
10401
  await this.stopPublishStream(stopTracks);
10383
10402
  }
10384
10403
  this.muteLocalStream(stopTracks);
10385
- this.getTracks().forEach((track) => {
10386
- if (track.readyState === 'ended') {
10404
+ const allEnded = this.getTracks().every((t) => t.readyState === 'ended');
10405
+ if (allEnded) {
10406
+ if (this.state.mediaStream &&
10387
10407
  // @ts-expect-error release() is present in react-native-webrtc
10388
- // and must be called to dispose the stream
10389
- if (typeof this.state.mediaStream.release === 'function') {
10390
- // @ts-expect-error
10391
- this.state.mediaStream.release();
10392
- }
10393
- this.state.setMediaStream(undefined);
10408
+ typeof this.state.mediaStream.release === 'function') {
10409
+ // @ts-expect-error called to dispose the stream in RN
10410
+ this.state.mediaStream.release();
10394
10411
  }
10395
- });
10412
+ this.state.setMediaStream(undefined);
10413
+ }
10396
10414
  }
10397
10415
  muteTracks() {
10398
10416
  this.getTracks().forEach((track) => {
@@ -13966,7 +13984,7 @@ class StreamClient {
13966
13984
  });
13967
13985
  };
13968
13986
  this.getUserAgent = () => {
13969
- const version = "0.4.1" ;
13987
+ const version = "0.4.3" ;
13970
13988
  return (this.userAgent ||
13971
13989
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
13972
13990
  };