@stream-io/video-client 0.4.2 → 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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ### [0.4.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.4.2...@stream-io/video-client-0.4.3) (2023-11-01)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **client:** optimized device enumeration ([#1111](https://github.com/GetStream/stream-video-js/issues/1111)) ([435bd33](https://github.com/GetStream/stream-video-js/commit/435bd33afbe8b368413690f8f2d67d0b4918dbaa))
11
+
5
12
  ### [0.4.2](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.4.1...@stream-io/video-client-0.4.2) (2023-11-01)
6
13
 
7
14
 
@@ -6564,11 +6564,8 @@ class Publisher {
6564
6564
  ? transceiver.sender.track.stop()
6565
6565
  : (transceiver.sender.track.enabled = false);
6566
6566
  // We don't need to notify SFU if unpublishing in response to remote soft mute
6567
- if (!this.state.localParticipant?.publishedTracks.includes(trackType)) {
6568
- return;
6569
- }
6570
- else {
6571
- return this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
6567
+ if (this.state.localParticipant?.publishedTracks.includes(trackType)) {
6568
+ await this.notifyTrackMuteStateChanged(undefined, transceiver.sender.track, trackType, true);
6572
6569
  }
6573
6570
  }
6574
6571
  };
@@ -9956,22 +9953,43 @@ const CallTypes = new CallTypesRegistry([
9956
9953
  }),
9957
9954
  ]);
9958
9955
 
9959
- const getDevices = (constraints) => {
9956
+ /**
9957
+ * Returns an Observable that emits the list of available devices
9958
+ * that meet the given constraints.
9959
+ *
9960
+ * @param constraints the constraints to use when requesting the devices.
9961
+ * @param kind the kind of devices to enumerate.
9962
+ */
9963
+ const getDevices = (constraints, kind) => {
9960
9964
  return new Observable((subscriber) => {
9961
- navigator.mediaDevices
9962
- .getUserMedia(constraints)
9963
- .then((media) => {
9964
- // in Firefox, devices can be enumerated after userMedia is requested
9965
- // and permissions granted. Otherwise, device labels are empty
9966
- navigator.mediaDevices.enumerateDevices().then((devices) => {
9967
- subscriber.next(devices);
9968
- // If we stop the tracks before enumerateDevices -> the labels won't show up in Firefox
9969
- disposeOfMediaStream(media);
9970
- subscriber.complete();
9971
- });
9965
+ const enumerate = async () => {
9966
+ let devices = await navigator.mediaDevices.enumerateDevices();
9967
+ // some browsers report empty device labels (Firefox).
9968
+ // in that case, we need to request permissions (via getUserMedia)
9969
+ // to be able to get the device labels
9970
+ const needsGetUserMedia = devices.some((device) => device.kind === kind && device.label === '');
9971
+ if (needsGetUserMedia) {
9972
+ let mediaStream;
9973
+ try {
9974
+ mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
9975
+ devices = await navigator.mediaDevices.enumerateDevices();
9976
+ }
9977
+ finally {
9978
+ if (mediaStream)
9979
+ disposeOfMediaStream(mediaStream);
9980
+ }
9981
+ }
9982
+ return devices;
9983
+ };
9984
+ enumerate()
9985
+ .then((devices) => {
9986
+ // notify subscribers and complete
9987
+ subscriber.next(devices);
9988
+ subscriber.complete();
9972
9989
  })
9973
9990
  .catch((error) => {
9974
- getLogger(['devices'])('error', 'Failed to get devices', error);
9991
+ const logger = getLogger(['devices']);
9992
+ logger('error', 'Failed to enumerate devices', error);
9975
9993
  subscriber.error(error);
9976
9994
  });
9977
9995
  });
@@ -9985,7 +10003,7 @@ const checkIfAudioOutputChangeSupported = () => {
9985
10003
  if (typeof document === 'undefined')
9986
10004
  return false;
9987
10005
  const element = document.createElement('audio');
9988
- return element.sinkId !== undefined;
10006
+ return 'setSinkId' in element;
9989
10007
  };
9990
10008
  /**
9991
10009
  * The default constraints used to request audio devices.
@@ -10036,10 +10054,13 @@ const getDeviceChangeObserver = memoizedObservable(() => {
10036
10054
  }).pipe(debounceTime(500), concatMap(() => from(navigator.mediaDevices.enumerateDevices())), shareReplay(1));
10037
10055
  });
10038
10056
  const getAudioDevicesObserver = memoizedObservable(() => {
10039
- return merge(getDevices(audioDeviceConstraints), getDeviceChangeObserver()).pipe(shareReplay(1));
10057
+ return merge(getDevices(audioDeviceConstraints, 'audioinput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10058
+ });
10059
+ const getAudioOutputDevicesObserver = memoizedObservable(() => {
10060
+ return merge(getDevices(audioDeviceConstraints, 'audiooutput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10040
10061
  });
10041
10062
  const getVideoDevicesObserver = memoizedObservable(() => {
10042
- return merge(getDevices(videoDeviceConstraints), getDeviceChangeObserver()).pipe(shareReplay(1));
10063
+ return merge(getDevices(videoDeviceConstraints, 'videoinput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10043
10064
  });
10044
10065
  /**
10045
10066
  * 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.
@@ -10057,7 +10078,7 @@ const getVideoDevices = () => {
10057
10078
  * 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)
10058
10079
  */
10059
10080
  const getAudioOutputDevices = () => {
10060
- return getAudioDevicesObserver().pipe(map$1((values) => values.filter((d) => d.kind === 'audiooutput')));
10081
+ return getAudioOutputDevicesObserver().pipe(map$1((values) => values.filter((d) => d.kind === 'audiooutput')));
10061
10082
  };
10062
10083
  const getStream = async (constraints) => {
10063
10084
  try {
@@ -13939,7 +13960,7 @@ class StreamClient {
13939
13960
  });
13940
13961
  };
13941
13962
  this.getUserAgent = () => {
13942
- const version = "0.4.2" ;
13963
+ const version = "0.4.3" ;
13943
13964
  return (this.userAgent ||
13944
13965
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
13945
13966
  };