@stream-io/video-client 1.25.1 → 1.25.2

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.
@@ -72,3 +72,11 @@ export declare const deviceIds$: import("rxjs").Observable<MediaDeviceInfo[]> |
72
72
  * @returns void
73
73
  */
74
74
  export declare const disposeOfMediaStream: (stream: MediaStream) => void;
75
+ /**
76
+ * Resolves `default` device id into the real device id. Some browsers (notably,
77
+ * Chromium-based) report device with id `default` among audio input and output
78
+ * devices. Since not every browser does that, we never want `default` id to be
79
+ * used within our SDK. This function tries to find the real id for the `default`
80
+ * device.
81
+ */
82
+ export declare function resolveDeviceId(deviceId: string | undefined, kind: MediaDeviceKind): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "1.25.1",
3
+ "version": "1.25.2",
4
4
  "main": "dist/index.cjs.js",
5
5
  "module": "dist/index.es.js",
6
6
  "browser": "dist/index.browser.es.js",
@@ -1,10 +1,10 @@
1
1
  import { BehaviorSubject, distinctUntilChanged, Observable } from 'rxjs';
2
+ import { RxUtils } from '../store';
2
3
  import {
3
4
  InputMediaDeviceManagerState,
4
5
  TrackDisableMode,
5
6
  } from './InputMediaDeviceManagerState';
6
- import { getAudioBrowserPermission } from './devices';
7
- import { RxUtils } from '../store';
7
+ import { getAudioBrowserPermission, resolveDeviceId } from './devices';
8
8
 
9
9
  export class MicrophoneManagerState extends InputMediaDeviceManagerState {
10
10
  private speakingWhileMutedSubject = new BehaviorSubject<boolean>(false);
@@ -42,6 +42,7 @@ export class MicrophoneManagerState extends InputMediaDeviceManagerState {
42
42
 
43
43
  protected getDeviceIdFromStream(stream: MediaStream): string | undefined {
44
44
  const [track] = stream.getAudioTracks();
45
- return track?.getSettings().deviceId;
45
+ const unresolvedDeviceId = track?.getSettings().deviceId;
46
+ return resolveDeviceId(unresolvedDeviceId, 'audioinput');
46
47
  }
47
48
  }
@@ -31,6 +31,7 @@ vi.mock('../devices.ts', () => {
31
31
  getAudioBrowserPermission: () => mockBrowserPermission,
32
32
  getVideoBrowserPermission: () => mockBrowserPermission,
33
33
  deviceIds$: mockDeviceIds$(),
34
+ resolveDeviceId: (deviceId) => deviceId,
34
35
  };
35
36
  });
36
37
 
@@ -30,6 +30,7 @@ vi.mock('../devices.ts', () => {
30
30
  getAudioBrowserPermission: () => mockBrowserPermission,
31
31
  getVideoBrowserPermission: () => mockBrowserPermission,
32
32
  deviceIds$: mockDeviceIds$(),
33
+ resolveDeviceId: (deviceId) => deviceId,
33
34
  };
34
35
  });
35
36
 
@@ -37,6 +37,7 @@ vi.mock('../devices.ts', () => {
37
37
  getAudioBrowserPermission: () => mockBrowserPermission,
38
38
  getVideoBrowserPermission: () => mockBrowserPermission,
39
39
  deviceIds$: mockDeviceIds$(),
40
+ resolveDeviceId: (deviceId) => deviceId,
40
41
  };
41
42
  });
42
43
 
@@ -33,6 +33,7 @@ vi.mock('../devices.ts', () => {
33
33
  getAudioBrowserPermission: () => mockBrowserPermission,
34
34
  getVideoBrowserPermission: () => mockBrowserPermission,
35
35
  deviceIds$: {},
36
+ resolveDeviceId: (deviceId) => deviceId,
36
37
  };
37
38
  });
38
39
 
@@ -16,6 +16,7 @@ vi.mock('../devices.ts', () => {
16
16
  getScreenShareStream: vi.fn(() => Promise.resolve(mockScreenShareStream())),
17
17
  checkIfAudioOutputChangeSupported: vi.fn(() => Promise.resolve(true)),
18
18
  deviceIds$: () => mockDeviceIds$(),
19
+ resolveDeviceId: (deviceId) => deviceId,
19
20
  };
20
21
  });
21
22
 
@@ -20,6 +20,7 @@ vi.mock('../devices.ts', () => {
20
20
  getAudioBrowserPermission: () => mockBrowserPermission,
21
21
  getVideoBrowserPermission: () => mockBrowserPermission,
22
22
  deviceIds$: mockDeviceIds$(),
23
+ resolveDeviceId: (deviceId) => deviceId,
23
24
  };
24
25
  });
25
26
 
@@ -13,6 +13,7 @@ import { BrowserPermission } from './BrowserPermission';
13
13
  import { lazy } from '../helpers/lazy';
14
14
  import { isFirefox } from '../helpers/browsers';
15
15
  import { dumpStream, Tracer } from '../stats';
16
+ import { getCurrentValue } from '../store/rxUtils';
16
17
 
17
18
  /**
18
19
  * Returns an Observable that emits the list of available devices
@@ -386,3 +387,26 @@ export const disposeOfMediaStream = (stream: MediaStream) => {
386
387
  stream.release();
387
388
  }
388
389
  };
390
+
391
+ /**
392
+ * Resolves `default` device id into the real device id. Some browsers (notably,
393
+ * Chromium-based) report device with id `default` among audio input and output
394
+ * devices. Since not every browser does that, we never want `default` id to be
395
+ * used within our SDK. This function tries to find the real id for the `default`
396
+ * device.
397
+ */
398
+ export function resolveDeviceId(
399
+ deviceId: string | undefined,
400
+ kind: MediaDeviceKind,
401
+ ): string | undefined {
402
+ if (deviceId !== 'default') return deviceId;
403
+ const devices = deviceIds$ && getCurrentValue(deviceIds$);
404
+ if (!devices) return deviceId;
405
+ const defaultDeviceInfo = devices.find((d) => d.deviceId === deviceId);
406
+ if (!defaultDeviceInfo) return deviceId;
407
+ const groupId = defaultDeviceInfo.groupId;
408
+ const candidates = devices.filter(
409
+ (d) => d.kind === kind && d.deviceId !== 'default' && d.groupId === groupId,
410
+ );
411
+ return candidates.length === 1 ? candidates[0].deviceId : deviceId;
412
+ }