@stream-io/video-client 1.0.8 → 1.0.10

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
+ ### [1.0.10](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.9...@stream-io/video-client-1.0.10) (2024-05-31)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * improved input device error handling ([#1378](https://github.com/GetStream/stream-video-js/issues/1378)) ([90abc38](https://github.com/GetStream/stream-video-js/commit/90abc38762acc4b8095c281b3b06b1fc8237ec15))
11
+
12
+ ### [1.0.9](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.8...@stream-io/video-client-1.0.9) (2024-05-29)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * prevent double sound detectors set up ([#1371](https://github.com/GetStream/stream-video-js/issues/1371)) ([51c9198](https://github.com/GetStream/stream-video-js/commit/51c9198a96b956884554bc508e38c90af0cee30f))
18
+
5
19
  ### [1.0.8](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.0.7...@stream-io/video-client-1.0.8) (2024-05-23)
6
20
 
7
21
 
@@ -10808,7 +10808,7 @@ const getStream = async (constraints) => {
10808
10808
  return await navigator.mediaDevices.getUserMedia(constraints);
10809
10809
  }
10810
10810
  catch (e) {
10811
- getLogger(['devices'])('error', `Failed get user media`, {
10811
+ getLogger(['devices'])('error', `Failed to getUserMedia`, {
10812
10812
  error: e,
10813
10813
  constraints: constraints,
10814
10814
  });
@@ -11226,39 +11226,41 @@ class InputMediaDeviceManager {
11226
11226
  deviceIds$.pipe(pairwise()),
11227
11227
  this.state.selectedDevice$,
11228
11228
  ]), async ([[prevDevices, currentDevices], deviceId]) => {
11229
- if (!deviceId) {
11230
- return;
11231
- }
11232
- if (this.statusChangePromise) {
11229
+ try {
11230
+ if (!deviceId)
11231
+ return;
11233
11232
  await this.statusChangePromise;
11234
- }
11235
- let isDeviceDisconnected = false;
11236
- let isDeviceReplaced = false;
11237
- const currentDevice = this.findDeviceInList(currentDevices, deviceId);
11238
- const prevDevice = this.findDeviceInList(prevDevices, deviceId);
11239
- if (!currentDevice && prevDevice) {
11240
- isDeviceDisconnected = true;
11241
- }
11242
- else if (currentDevice &&
11243
- prevDevice &&
11244
- currentDevice.deviceId === prevDevice.deviceId &&
11245
- currentDevice.groupId !== prevDevice.groupId) {
11246
- isDeviceReplaced = true;
11247
- }
11248
- if (isDeviceDisconnected) {
11249
- await this.disable();
11250
- this.select(undefined);
11251
- }
11252
- if (isDeviceReplaced) {
11253
- if (this.isTrackStoppedDueToTrackEnd &&
11254
- this.state.status === 'disabled') {
11255
- await this.enable();
11256
- this.isTrackStoppedDueToTrackEnd = false;
11233
+ let isDeviceDisconnected = false;
11234
+ let isDeviceReplaced = false;
11235
+ const currentDevice = this.findDeviceInList(currentDevices, deviceId);
11236
+ const prevDevice = this.findDeviceInList(prevDevices, deviceId);
11237
+ if (!currentDevice && prevDevice) {
11238
+ isDeviceDisconnected = true;
11257
11239
  }
11258
- else {
11259
- await this.applySettingsToStream();
11240
+ else if (currentDevice &&
11241
+ prevDevice &&
11242
+ currentDevice.deviceId === prevDevice.deviceId &&
11243
+ currentDevice.groupId !== prevDevice.groupId) {
11244
+ isDeviceReplaced = true;
11245
+ }
11246
+ if (isDeviceDisconnected) {
11247
+ await this.disable();
11248
+ await this.select(undefined);
11249
+ }
11250
+ if (isDeviceReplaced) {
11251
+ if (this.isTrackStoppedDueToTrackEnd &&
11252
+ this.state.status === 'disabled') {
11253
+ await this.enable();
11254
+ this.isTrackStoppedDueToTrackEnd = false;
11255
+ }
11256
+ else {
11257
+ await this.applySettingsToStream();
11258
+ }
11260
11259
  }
11261
11260
  }
11261
+ catch (err) {
11262
+ this.logger('warn', 'Unexpected error while handling disconnected or replaced device', err);
11263
+ }
11262
11264
  }));
11263
11265
  }
11264
11266
  findDeviceInList(devices, deviceId) {
@@ -11762,23 +11764,28 @@ class MicrophoneManager extends InputMediaDeviceManager {
11762
11764
  this.state.selectedDevice$,
11763
11765
  this.state.status$,
11764
11766
  ]), async ([callingState, ownCapabilities, deviceId, status]) => {
11765
- if (callingState === CallingState.LEFT) {
11766
- await this.stopSpeakingWhileMutedDetection();
11767
- }
11768
- if (callingState !== CallingState.JOINED)
11769
- return;
11770
- if (!this.speakingWhileMutedNotificationEnabled)
11771
- return;
11772
- if (ownCapabilities.includes(OwnCapability.SEND_AUDIO)) {
11773
- if (status === 'disabled') {
11774
- await this.startSpeakingWhileMutedDetection(deviceId);
11767
+ try {
11768
+ if (callingState === CallingState.LEFT) {
11769
+ await this.stopSpeakingWhileMutedDetection();
11770
+ }
11771
+ if (callingState !== CallingState.JOINED)
11772
+ return;
11773
+ if (!this.speakingWhileMutedNotificationEnabled)
11774
+ return;
11775
+ if (ownCapabilities.includes(OwnCapability.SEND_AUDIO)) {
11776
+ if (status === 'disabled') {
11777
+ await this.startSpeakingWhileMutedDetection(deviceId);
11778
+ }
11779
+ else {
11780
+ await this.stopSpeakingWhileMutedDetection();
11781
+ }
11775
11782
  }
11776
11783
  else {
11777
11784
  await this.stopSpeakingWhileMutedDetection();
11778
11785
  }
11779
11786
  }
11780
- else {
11781
- await this.stopSpeakingWhileMutedDetection();
11787
+ catch (err) {
11788
+ this.logger('warn', 'Could not enable speaking while muted', err);
11782
11789
  }
11783
11790
  }));
11784
11791
  this.subscriptions.push(createSubscription(this.call.state.callingState$, (callingState) => {
@@ -11904,39 +11911,43 @@ class MicrophoneManager extends InputMediaDeviceManager {
11904
11911
  return this.call.stopPublish(TrackType.AUDIO, stopTracks);
11905
11912
  }
11906
11913
  async startSpeakingWhileMutedDetection(deviceId) {
11907
- await this.stopSpeakingWhileMutedDetection();
11908
- if (isReactNative()) {
11909
- this.rnSpeechDetector = new RNSpeechDetector();
11910
- await this.rnSpeechDetector.start();
11911
- const unsubscribe = this.rnSpeechDetector?.onSpeakingDetectedStateChange((event) => {
11912
- this.state.setSpeakingWhileMuted(event.isSoundDetected);
11913
- });
11914
- this.soundDetectorCleanup = () => {
11915
- unsubscribe();
11916
- this.rnSpeechDetector?.stop();
11917
- this.rnSpeechDetector = undefined;
11918
- };
11919
- }
11920
- else {
11921
- // Need to start a new stream that's not connected to publisher
11922
- const stream = await this.getStream({
11923
- deviceId,
11924
- });
11925
- this.soundDetectorCleanup = createSoundDetector(stream, (event) => {
11926
- this.state.setSpeakingWhileMuted(event.isSoundDetected);
11927
- });
11928
- }
11914
+ const startPromise = (async () => {
11915
+ await this.stopSpeakingWhileMutedDetection();
11916
+ if (isReactNative()) {
11917
+ this.rnSpeechDetector = new RNSpeechDetector();
11918
+ await this.rnSpeechDetector.start();
11919
+ const unsubscribe = this.rnSpeechDetector?.onSpeakingDetectedStateChange((event) => {
11920
+ this.state.setSpeakingWhileMuted(event.isSoundDetected);
11921
+ });
11922
+ return () => {
11923
+ unsubscribe();
11924
+ this.rnSpeechDetector?.stop();
11925
+ this.rnSpeechDetector = undefined;
11926
+ };
11927
+ }
11928
+ else {
11929
+ // Need to start a new stream that's not connected to publisher
11930
+ const stream = await this.getStream({
11931
+ deviceId,
11932
+ });
11933
+ return createSoundDetector(stream, (event) => {
11934
+ this.state.setSpeakingWhileMuted(event.isSoundDetected);
11935
+ });
11936
+ }
11937
+ })();
11938
+ this.soundDetectorCleanup = async () => {
11939
+ const cleanup = await startPromise;
11940
+ await cleanup();
11941
+ };
11942
+ await startPromise;
11929
11943
  }
11930
11944
  async stopSpeakingWhileMutedDetection() {
11931
11945
  if (!this.soundDetectorCleanup)
11932
11946
  return;
11947
+ const soundDetectorCleanup = this.soundDetectorCleanup;
11948
+ this.soundDetectorCleanup = undefined;
11933
11949
  this.state.setSpeakingWhileMuted(false);
11934
- try {
11935
- await this.soundDetectorCleanup();
11936
- }
11937
- finally {
11938
- this.soundDetectorCleanup = undefined;
11939
- }
11950
+ await soundDetectorCleanup();
11940
11951
  }
11941
11952
  }
11942
11953
 
@@ -12375,7 +12386,7 @@ class Call {
12375
12386
  this.watching = true;
12376
12387
  this.clientStore.registerCall(this);
12377
12388
  }
12378
- this.applyDeviceConfig();
12389
+ await this.applyDeviceConfig();
12379
12390
  return response;
12380
12391
  };
12381
12392
  /**
@@ -12395,7 +12406,7 @@ class Call {
12395
12406
  this.watching = true;
12396
12407
  this.clientStore.registerCall(this);
12397
12408
  }
12398
- this.applyDeviceConfig();
12409
+ await this.applyDeviceConfig();
12399
12410
  return response;
12400
12411
  };
12401
12412
  /**
@@ -13457,9 +13468,18 @@ class Call {
13457
13468
  this.sendCustomEvent = async (payload) => {
13458
13469
  return this.streamClient.post(`${this.streamClientBasePath}/event`, { custom: payload });
13459
13470
  };
13460
- this.applyDeviceConfig = () => {
13461
- this.initCamera({ setStatus: false });
13462
- this.initMic({ setStatus: false });
13471
+ /**
13472
+ * Applies the device configuration from the backend.
13473
+ *
13474
+ * @internal
13475
+ */
13476
+ this.applyDeviceConfig = async () => {
13477
+ await this.initCamera({ setStatus: false }).catch((err) => {
13478
+ this.logger('warn', 'Camera init failed', err);
13479
+ });
13480
+ await this.initMic({ setStatus: false }).catch((err) => {
13481
+ this.logger('warn', 'Mic init failed', err);
13482
+ });
13463
13483
  };
13464
13484
  /**
13465
13485
  * Will begin tracking the given element for visibility changes within the
@@ -13638,7 +13658,9 @@ class Call {
13638
13658
  const currentUserId = this.currentUserId;
13639
13659
  if (currentUserId && blockedUserIds.includes(currentUserId)) {
13640
13660
  this.logger('info', 'Leaving call because of being blocked');
13641
- await this.leave({ reason: 'user blocked' });
13661
+ await this.leave({ reason: 'user blocked' }).catch((err) => {
13662
+ this.logger('error', 'Error leaving call after being blocked', err);
13663
+ });
13642
13664
  }
13643
13665
  }));
13644
13666
  this.leaveCallHooks.add(
@@ -15265,7 +15287,7 @@ class StreamClient {
15265
15287
  });
15266
15288
  };
15267
15289
  this.getUserAgent = () => {
15268
- const version = "1.0.8" ;
15290
+ const version = "1.0.10" ;
15269
15291
  return (this.userAgent ||
15270
15292
  `stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
15271
15293
  };
@@ -15475,7 +15497,8 @@ class StreamVideoClient {
15475
15497
  */
15476
15498
  this.queryCalls = async (data = {}) => {
15477
15499
  const response = await this.streamClient.post('/calls', data);
15478
- const calls = response.calls.map((c) => {
15500
+ const calls = [];
15501
+ for (const c of response.calls) {
15479
15502
  const call = new Call({
15480
15503
  streamClient: this.streamClient,
15481
15504
  id: c.call.id,
@@ -15486,12 +15509,12 @@ class StreamVideoClient {
15486
15509
  clientStore: this.writeableStateStore,
15487
15510
  });
15488
15511
  call.state.updateFromCallResponse(c.call);
15489
- call.applyDeviceConfig();
15512
+ await call.applyDeviceConfig();
15490
15513
  if (data.watch) {
15491
15514
  this.writeableStateStore.registerCall(call);
15492
15515
  }
15493
- return call;
15494
- });
15516
+ calls.push(call);
15517
+ }
15495
15518
  return {
15496
15519
  ...response,
15497
15520
  calls: calls,