@stream-io/video-client 0.4.2 → 0.4.4

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,20 @@
2
2
 
3
3
  This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
4
4
 
5
+ ### [0.4.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-0.4.3...@stream-io/video-client-0.4.4) (2023-11-02)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * allow audio and screen share audio tracks, delay setSinkId ([#1176](https://github.com/GetStream/stream-video-js/issues/1176)) ([6a099c5](https://github.com/GetStream/stream-video-js/commit/6a099c5c7cc6f5d389961a7c594e914e19be4ddb))
11
+
12
+ ### [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)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **client:** optimized device enumeration ([#1111](https://github.com/GetStream/stream-video-js/issues/1111)) ([435bd33](https://github.com/GetStream/stream-video-js/commit/435bd33afbe8b368413690f8f2d67d0b4918dbaa))
18
+
5
19
  ### [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
20
 
7
21
 
@@ -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
  };
@@ -9791,6 +9788,14 @@ class DynascaleManager {
9791
9788
  audioElement.play().catch((e) => {
9792
9789
  this.logger('warn', `Failed to play stream`, e);
9793
9790
  });
9791
+ // audio output device shall be set after the audio element is played
9792
+ // otherwise, the browser will not pick it up, and will always
9793
+ // play audio through the system's default device
9794
+ const { selectedDevice } = this.call.speaker.state;
9795
+ if (selectedDevice && 'setSinkId' in audioElement) {
9796
+ // @ts-expect-error setSinkId is not yet in the lib
9797
+ audioElement.setSinkId(selectedDevice);
9798
+ }
9794
9799
  }
9795
9800
  });
9796
9801
  });
@@ -9956,22 +9961,43 @@ const CallTypes = new CallTypesRegistry([
9956
9961
  }),
9957
9962
  ]);
9958
9963
 
9959
- const getDevices = (constraints) => {
9964
+ /**
9965
+ * Returns an Observable that emits the list of available devices
9966
+ * that meet the given constraints.
9967
+ *
9968
+ * @param constraints the constraints to use when requesting the devices.
9969
+ * @param kind the kind of devices to enumerate.
9970
+ */
9971
+ const getDevices = (constraints, kind) => {
9960
9972
  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
- });
9973
+ const enumerate = async () => {
9974
+ let devices = await navigator.mediaDevices.enumerateDevices();
9975
+ // some browsers report empty device labels (Firefox).
9976
+ // in that case, we need to request permissions (via getUserMedia)
9977
+ // to be able to get the device labels
9978
+ const needsGetUserMedia = devices.some((device) => device.kind === kind && device.label === '');
9979
+ if (needsGetUserMedia) {
9980
+ let mediaStream;
9981
+ try {
9982
+ mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
9983
+ devices = await navigator.mediaDevices.enumerateDevices();
9984
+ }
9985
+ finally {
9986
+ if (mediaStream)
9987
+ disposeOfMediaStream(mediaStream);
9988
+ }
9989
+ }
9990
+ return devices;
9991
+ };
9992
+ enumerate()
9993
+ .then((devices) => {
9994
+ // notify subscribers and complete
9995
+ subscriber.next(devices);
9996
+ subscriber.complete();
9972
9997
  })
9973
9998
  .catch((error) => {
9974
- getLogger(['devices'])('error', 'Failed to get devices', error);
9999
+ const logger = getLogger(['devices']);
10000
+ logger('error', 'Failed to enumerate devices', error);
9975
10001
  subscriber.error(error);
9976
10002
  });
9977
10003
  });
@@ -9985,7 +10011,7 @@ const checkIfAudioOutputChangeSupported = () => {
9985
10011
  if (typeof document === 'undefined')
9986
10012
  return false;
9987
10013
  const element = document.createElement('audio');
9988
- return element.sinkId !== undefined;
10014
+ return 'setSinkId' in element;
9989
10015
  };
9990
10016
  /**
9991
10017
  * The default constraints used to request audio devices.
@@ -10036,10 +10062,13 @@ const getDeviceChangeObserver = memoizedObservable(() => {
10036
10062
  }).pipe(debounceTime(500), concatMap(() => from(navigator.mediaDevices.enumerateDevices())), shareReplay(1));
10037
10063
  });
10038
10064
  const getAudioDevicesObserver = memoizedObservable(() => {
10039
- return merge(getDevices(audioDeviceConstraints), getDeviceChangeObserver()).pipe(shareReplay(1));
10065
+ return merge(getDevices(audioDeviceConstraints, 'audioinput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10066
+ });
10067
+ const getAudioOutputDevicesObserver = memoizedObservable(() => {
10068
+ return merge(getDevices(audioDeviceConstraints, 'audiooutput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10040
10069
  });
10041
10070
  const getVideoDevicesObserver = memoizedObservable(() => {
10042
- return merge(getDevices(videoDeviceConstraints), getDeviceChangeObserver()).pipe(shareReplay(1));
10071
+ return merge(getDevices(videoDeviceConstraints, 'videoinput'), getDeviceChangeObserver()).pipe(shareReplay(1));
10043
10072
  });
10044
10073
  /**
10045
10074
  * 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 +10086,7 @@ const getVideoDevices = () => {
10057
10086
  * 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
10087
  */
10059
10088
  const getAudioOutputDevices = () => {
10060
- return getAudioDevicesObserver().pipe(map$1((values) => values.filter((d) => d.kind === 'audiooutput')));
10089
+ return getAudioOutputDevicesObserver().pipe(map$1((values) => values.filter((d) => d.kind === 'audiooutput')));
10061
10090
  };
10062
10091
  const getStream = async (constraints) => {
10063
10092
  try {
@@ -13939,7 +13968,7 @@ class StreamClient {
13939
13968
  });
13940
13969
  };
13941
13970
  this.getUserAgent = () => {
13942
- const version = "0.4.2" ;
13971
+ const version = "0.4.4" ;
13943
13972
  return (this.userAgent ||
13944
13973
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
13945
13974
  };