@stream-io/video-client 0.3.2 → 0.3.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.browser.es.js +77 -56
  3. package/dist/index.browser.es.js.map +1 -1
  4. package/dist/index.cjs.js +77 -56
  5. package/dist/index.cjs.js.map +1 -1
  6. package/dist/index.es.js +77 -56
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/src/Call.d.ts +2 -1
  9. package/dist/src/coordinator/connection/client.d.ts +9 -4
  10. package/dist/src/devices/CameraManager.d.ts +3 -9
  11. package/dist/src/devices/InputMediaDeviceManager.d.ts +11 -5
  12. package/dist/src/devices/InputMediaDeviceManagerState.d.ts +6 -1
  13. package/dist/src/devices/MicrophoneManager.d.ts +3 -9
  14. package/dist/src/devices/MicrophoneManagerState.d.ts +1 -0
  15. package/dist/src/rtc/Publisher.d.ts +2 -1
  16. package/dist/version.d.ts +1 -1
  17. package/package.json +1 -1
  18. package/src/Call.ts +3 -2
  19. package/src/StreamVideoClient.ts +1 -10
  20. package/src/__tests__/StreamVideoClient.test.ts +13 -0
  21. package/src/coordinator/connection/client.ts +28 -0
  22. package/src/devices/CameraManager.ts +8 -17
  23. package/src/devices/CameraManagerState.ts +1 -1
  24. package/src/devices/InputMediaDeviceManager.ts +39 -17
  25. package/src/devices/InputMediaDeviceManagerState.ts +12 -2
  26. package/src/devices/MicrophoneManager.ts +8 -17
  27. package/src/devices/MicrophoneManagerState.ts +4 -0
  28. package/src/devices/__tests__/CameraManager.test.ts +4 -14
  29. package/src/devices/__tests__/InputMediaDeviceManager.test.ts +48 -5
  30. package/src/devices/__tests__/MicrophoneManager.test.ts +8 -7
  31. package/src/rtc/Publisher.ts +8 -2
  32. package/src/rtc/__tests__/Publisher.test.ts +67 -1
@@ -217,8 +217,9 @@ export declare class Call {
217
217
  *
218
218
  *
219
219
  * @param trackType the track type to stop publishing.
220
+ * @param stopTrack if `true` the track will be stopped, else it will be just disabled
220
221
  */
221
- stopPublish: (trackType: TrackType) => Promise<void>;
222
+ stopPublish: (trackType: TrackType, stopTrack?: boolean) => Promise<void>;
222
223
  /**
223
224
  * Update track subscription configuration for one or more participants.
224
225
  * You have to create a subscription for each participant for all the different kinds of tracks you want to receive.
@@ -4,8 +4,9 @@ import WebSocket from 'isomorphic-ws';
4
4
  import { StableWSConnection } from './connection';
5
5
  import { TokenManager } from './token_manager';
6
6
  import { WSConnectionFallback } from './connection_fallback';
7
- import { APIErrorResponse, ConnectAPIResponse, ErrorFromResponse, EventHandler, Logger, StreamClientOptions, StreamVideoEvent, TokenOrProvider, UserWithId } from './types';
7
+ import { APIErrorResponse, ConnectAPIResponse, ErrorFromResponse, EventHandler, Logger, StreamClientOptions, StreamVideoEvent, TokenOrProvider, User, UserWithId } from './types';
8
8
  import { InsightMetrics } from './insights';
9
+ import { CreateGuestResponse } from '../../gen/coordinator';
9
10
  export declare class StreamClient {
10
11
  _user?: UserWithId;
11
12
  anonymous: boolean;
@@ -38,6 +39,7 @@ export declare class StreamClient {
38
39
  resolveConnectionId?: Function;
39
40
  rejectConnectionId?: Function;
40
41
  connectionIdPromise?: Promise<string | undefined>;
42
+ guestUserCreatePromise?: Promise<CreateGuestResponse>;
41
43
  private nextRequestAbortController;
42
44
  /**
43
45
  * Initialize a client.
@@ -66,7 +68,7 @@ export declare class StreamClient {
66
68
  *
67
69
  * @return {ConnectAPIResponse} Returns a promise that resolves when the connection is setup
68
70
  */
69
- connectUser: (user: UserWithId, userTokenOrProvider: TokenOrProvider) => Promise<void | import("../../..").ConnectedEvent>;
71
+ connectUser: (user: UserWithId, userTokenOrProvider: TokenOrProvider) => Promise<void | import("../../gen/coordinator").ConnectedEvent>;
70
72
  _setToken: (user: UserWithId, userTokenOrProvider: TokenOrProvider, isAnonymous: boolean) => Promise<void>;
71
73
  _setUser: (user: UserWithId) => void;
72
74
  /**
@@ -86,7 +88,7 @@ export declare class StreamClient {
86
88
  /**
87
89
  * Creates a new WebSocket connection with the current user. Returns empty promise, if there is an active connection
88
90
  */
89
- openConnection: () => Promise<void | import("../../..").ConnectedEvent>;
91
+ openConnection: () => Promise<void | import("../../gen/coordinator").ConnectedEvent>;
90
92
  _normalizeDate: (before: Date | string | null) => string | null;
91
93
  /**
92
94
  * Disconnects the websocket and removes the user from client.
@@ -95,6 +97,9 @@ export declare class StreamClient {
95
97
  * https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent
96
98
  */
97
99
  disconnectUser: (timeout?: number) => Promise<void>;
100
+ connectGuestUser: (user: User & {
101
+ type: 'guest';
102
+ }) => Promise<void | import("../../gen/coordinator").ConnectedEvent>;
98
103
  /**
99
104
  * connectAnonymousUser - Set an anonymous user and open a WebSocket connection
100
105
  */
@@ -144,7 +149,7 @@ export declare class StreamClient {
144
149
  /**
145
150
  * @private
146
151
  */
147
- connect: () => Promise<void | import("../../..").ConnectedEvent>;
152
+ connect: () => Promise<void | import("../../gen/coordinator").ConnectedEvent>;
148
153
  /**
149
154
  * Check the connectivity with server for warmup purpose.
150
155
  *
@@ -19,13 +19,7 @@ export declare class CameraManager extends InputMediaDeviceManager<CameraManager
19
19
  protected getDevices(): Observable<MediaDeviceInfo[]>;
20
20
  protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
21
21
  protected publishStream(stream: MediaStream): Promise<void>;
22
- protected stopPublishStream(): Promise<void>;
23
- /**
24
- * Disables the video tracks of the camera
25
- */
26
- pause(): void;
27
- /**
28
- * (Re)enables the video tracks of the camera
29
- */
30
- resume(): void;
22
+ protected stopPublishStream(stopTracks: boolean): Promise<void>;
23
+ protected muteTracks(): void;
24
+ protected unmuteTracks(): void;
31
25
  }
@@ -19,11 +19,17 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
19
19
  enable(): Promise<void>;
20
20
  /**
21
21
  * Stops camera/microphone
22
+ *
22
23
  * @returns
23
24
  */
24
25
  disable(): Promise<void>;
26
+ /**
27
+ * If status was previously enabled, it will reenable the device.
28
+ */
29
+ resume(): Promise<void>;
25
30
  /**
26
31
  * If current device statis is disabled, it will enable the device, else it will disable it.
32
+ *
27
33
  * @returns
28
34
  */
29
35
  toggle(): Promise<void>;
@@ -36,12 +42,12 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
36
42
  */
37
43
  select(deviceId: string | undefined): Promise<void>;
38
44
  protected applySettingsToStream(): Promise<void>;
39
- abstract pause(): void;
40
- abstract resume(): void;
41
45
  protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
42
46
  protected abstract getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
43
47
  protected abstract publishStream(stream: MediaStream): Promise<void>;
44
- protected abstract stopPublishStream(): Promise<void>;
45
- private stopStream;
46
- private startStream;
48
+ protected abstract stopPublishStream(stopTracks: boolean): Promise<void>;
49
+ protected abstract muteTracks(): void;
50
+ protected abstract unmuteTracks(): void;
51
+ private muteStream;
52
+ private unmuteStream;
47
53
  }
@@ -2,9 +2,14 @@ import { BehaviorSubject, Observable } from 'rxjs';
2
2
  import { RxUtils } from '../store';
3
3
  export type InputDeviceStatus = 'enabled' | 'disabled' | undefined;
4
4
  export declare abstract class InputMediaDeviceManagerState {
5
+ readonly disableMode: 'stop-tracks' | 'disable-tracks';
5
6
  protected statusSubject: BehaviorSubject<InputDeviceStatus>;
6
7
  protected mediaStreamSubject: BehaviorSubject<MediaStream | undefined>;
7
8
  protected selectedDeviceSubject: BehaviorSubject<string | undefined>;
9
+ /**
10
+ * @internal
11
+ */
12
+ prevStatus: InputDeviceStatus;
8
13
  /**
9
14
  * An Observable that emits the current media stream, or `undefined` if the device is currently disabled.
10
15
  *
@@ -18,7 +23,7 @@ export declare abstract class InputMediaDeviceManagerState {
18
23
  * An Observable that emits the device status
19
24
  */
20
25
  status$: Observable<InputDeviceStatus>;
21
- constructor();
26
+ constructor(disableMode?: 'stop-tracks' | 'disable-tracks');
22
27
  /**
23
28
  * The device status
24
29
  */
@@ -7,13 +7,7 @@ export declare class MicrophoneManager extends InputMediaDeviceManager<Microphon
7
7
  protected getDevices(): Observable<MediaDeviceInfo[]>;
8
8
  protected getStream(constraints: MediaTrackConstraints): Promise<MediaStream>;
9
9
  protected publishStream(stream: MediaStream): Promise<void>;
10
- protected stopPublishStream(): Promise<void>;
11
- /**
12
- * Disables the audio tracks of the microphone
13
- */
14
- pause(): void;
15
- /**
16
- * (Re)enables the audio tracks of the microphone
17
- */
18
- resume(): void;
10
+ protected stopPublishStream(stopTracks: boolean): Promise<void>;
11
+ protected muteTracks(): void;
12
+ protected unmuteTracks(): void;
19
13
  }
@@ -1,4 +1,5 @@
1
1
  import { InputMediaDeviceManagerState } from './InputMediaDeviceManagerState';
2
2
  export declare class MicrophoneManagerState extends InputMediaDeviceManagerState {
3
+ constructor();
3
4
  protected getDeviceIdFromStream(stream: MediaStream): string | undefined;
4
5
  }
@@ -76,8 +76,9 @@ export declare class Publisher {
76
76
  * Stops publishing the given track type to the SFU, if it is currently being published.
77
77
  * Underlying track will be stopped and removed from the publisher.
78
78
  * @param trackType the track type to unpublish.
79
+ * @param stopTrack specifies whether track should be stopped or just disabled
79
80
  */
80
- unpublishStream: (trackType: TrackType) => Promise<void>;
81
+ unpublishStream: (trackType: TrackType, stopTrack: boolean) => Promise<void>;
81
82
  /**
82
83
  * Returns true if the given track type is currently being published to the SFU.
83
84
  *
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.3.2";
1
+ export declare const version = "0.3.4";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "packageManager": "yarn@3.2.4",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.es.js",
package/src/Call.ts CHANGED
@@ -1092,10 +1092,11 @@ export class Call {
1092
1092
  *
1093
1093
  *
1094
1094
  * @param trackType the track type to stop publishing.
1095
+ * @param stopTrack if `true` the track will be stopped, else it will be just disabled
1095
1096
  */
1096
- stopPublish = async (trackType: TrackType) => {
1097
+ stopPublish = async (trackType: TrackType, stopTrack: boolean = true) => {
1097
1098
  this.logger('info', `stopPublish ${TrackType[trackType]}`);
1098
- await this.publisher?.unpublishStream(trackType);
1099
+ await this.publisher?.unpublishStream(trackType, stopTrack);
1099
1100
  };
1100
1101
 
1101
1102
  /**
@@ -152,16 +152,7 @@ export class StreamVideoClient {
152
152
  };
153
153
  if (user.type === 'guest') {
154
154
  connectUser = async () => {
155
- const response = await this.createGuestUser({
156
- user: {
157
- ...user,
158
- role: 'guest',
159
- },
160
- });
161
- return this.streamClient.connectUser(
162
- response.user,
163
- response.access_token,
164
- );
155
+ return this.streamClient.connectGuestUser(user);
165
156
  };
166
157
  }
167
158
  this.connectionPromise = this.disconnectionPromise
@@ -3,6 +3,7 @@ import { StreamVideoClient } from '../StreamVideoClient';
3
3
  import 'dotenv/config';
4
4
  import { generateUUIDv4 } from '../coordinator/connection/utils';
5
5
  import { StreamVideoServerClient } from '../StreamVideoServerClient';
6
+ import { User } from '../coordinator/connection/types';
6
7
 
7
8
  const apiKey = process.env.STREAM_API_KEY!;
8
9
  const secret = process.env.STREAM_SECRET!;
@@ -87,6 +88,18 @@ describe('StreamVideoClient', () => {
87
88
  );
88
89
  });
89
90
 
91
+ it('API calls should be hold until auth is done - guest user', async () => {
92
+ const user: User = {
93
+ id: 'jane-guest',
94
+ type: 'guest',
95
+ };
96
+
97
+ client.connectUser(user);
98
+ const response = await client.queryCalls({});
99
+
100
+ expect(response.calls).toBeDefined();
101
+ });
102
+
90
103
  afterEach(() => {
91
104
  client.disconnectUser();
92
105
  });
@@ -30,11 +30,13 @@ import {
30
30
  StreamClientOptions,
31
31
  StreamVideoEvent,
32
32
  TokenOrProvider,
33
+ User,
33
34
  UserWithId,
34
35
  } from './types';
35
36
  import { InsightMetrics, postInsights } from './insights';
36
37
  import { version } from '../../../version';
37
38
  import { getLocationHint } from './location';
39
+ import { CreateGuestRequest, CreateGuestResponse } from '../../gen/coordinator';
38
40
 
39
41
  export class StreamClient {
40
42
  _user?: UserWithId;
@@ -70,6 +72,7 @@ export class StreamClient {
70
72
  resolveConnectionId?: Function;
71
73
  rejectConnectionId?: Function;
72
74
  connectionIdPromise?: Promise<string | undefined>;
75
+ guestUserCreatePromise?: Promise<CreateGuestResponse>;
73
76
  private nextRequestAbortController: AbortController | null = null;
74
77
 
75
78
  /**
@@ -402,6 +405,30 @@ export class StreamClient {
402
405
  this.resolveConnectionId = undefined;
403
406
  };
404
407
 
408
+ connectGuestUser = async (user: User & { type: 'guest' }) => {
409
+ this.guestUserCreatePromise = this.doAxiosRequest<
410
+ CreateGuestResponse,
411
+ CreateGuestRequest
412
+ >(
413
+ 'post',
414
+ '/guest',
415
+ {
416
+ user: {
417
+ ...user,
418
+ role: 'guest',
419
+ },
420
+ },
421
+ { publicEndpoint: true },
422
+ );
423
+
424
+ const response = await this.guestUserCreatePromise;
425
+ this.guestUserCreatePromise.finally(
426
+ () => (this.guestUserCreatePromise = undefined),
427
+ );
428
+
429
+ return this.connectUser(response.user, response.access_token);
430
+ };
431
+
405
432
  /**
406
433
  * connectAnonymousUser - Set an anonymous user and open a WebSocket connection
407
434
  */
@@ -524,6 +551,7 @@ export class StreamClient {
524
551
  if (!options.publicEndpoint) {
525
552
  await Promise.all([
526
553
  this.tokenManager.tokenReady(),
554
+ this.guestUserCreatePromise,
527
555
  this.connectionIdPromise,
528
556
  ]);
529
557
  }
@@ -49,25 +49,16 @@ export class CameraManager extends InputMediaDeviceManager<CameraManagerState> {
49
49
  protected publishStream(stream: MediaStream): Promise<void> {
50
50
  return this.call.publishVideoStream(stream);
51
51
  }
52
- protected stopPublishStream(): Promise<void> {
53
- return this.call.stopPublish(TrackType.VIDEO);
52
+ protected stopPublishStream(stopTracks: boolean): Promise<void> {
53
+ return this.call.stopPublish(TrackType.VIDEO, stopTracks);
54
54
  }
55
55
 
56
- /**
57
- * Disables the video tracks of the camera
58
- */
59
- pause() {
60
- this.state.mediaStream?.getVideoTracks().forEach((track) => {
61
- track.enabled = false;
62
- });
56
+ protected muteTracks(): void {
57
+ this.state.mediaStream
58
+ ?.getVideoTracks()
59
+ .forEach((t) => (t.enabled = false));
63
60
  }
64
-
65
- /**
66
- * (Re)enables the video tracks of the camera
67
- */
68
- resume() {
69
- this.state.mediaStream?.getVideoTracks().forEach((track) => {
70
- track.enabled = true;
71
- });
61
+ protected unmuteTracks(): void {
62
+ this.state.mediaStream?.getVideoTracks().forEach((t) => (t.enabled = true));
72
63
  }
73
64
  }
@@ -15,7 +15,7 @@ export class CameraManagerState extends InputMediaDeviceManagerState {
15
15
  direction$: Observable<CameraDirection>;
16
16
 
17
17
  constructor() {
18
- super();
18
+ super('stop-tracks');
19
19
  this.direction$ = this.directionSubject
20
20
  .asObservable()
21
21
  .pipe(distinctUntilChanged());
@@ -28,24 +28,39 @@ export abstract class InputMediaDeviceManager<
28
28
  if (this.state.status === 'enabled') {
29
29
  return;
30
30
  }
31
- await this.startStream();
31
+ await this.unmuteStream();
32
32
  this.state.setStatus('enabled');
33
33
  }
34
34
 
35
35
  /**
36
36
  * Stops camera/microphone
37
+ *
37
38
  * @returns
38
39
  */
39
40
  async disable() {
40
41
  if (this.state.status === 'disabled') {
41
42
  return;
42
43
  }
43
- await this.stopStream();
44
+ this.state.prevStatus = this.state.status;
45
+ await this.muteStream(this.state.disableMode === 'stop-tracks');
44
46
  this.state.setStatus('disabled');
45
47
  }
46
48
 
49
+ /**
50
+ * If status was previously enabled, it will reenable the device.
51
+ */
52
+ async resume() {
53
+ if (
54
+ this.state.prevStatus === 'enabled' &&
55
+ this.state.status === 'disabled'
56
+ ) {
57
+ this.enable();
58
+ }
59
+ }
60
+
47
61
  /**
48
62
  * If current device statis is disabled, it will enable the device, else it will disable it.
63
+ *
49
64
  * @returns
50
65
  */
51
66
  async toggle() {
@@ -76,15 +91,11 @@ export abstract class InputMediaDeviceManager<
76
91
 
77
92
  protected async applySettingsToStream() {
78
93
  if (this.state.status === 'enabled') {
79
- await this.stopStream();
80
- await this.startStream();
94
+ await this.muteStream();
95
+ await this.unmuteStream();
81
96
  }
82
97
  }
83
98
 
84
- abstract pause(): void;
85
-
86
- abstract resume(): void;
87
-
88
99
  protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
89
100
 
90
101
  protected abstract getStream(
@@ -93,26 +104,37 @@ export abstract class InputMediaDeviceManager<
93
104
 
94
105
  protected abstract publishStream(stream: MediaStream): Promise<void>;
95
106
 
96
- protected abstract stopPublishStream(): Promise<void>;
107
+ protected abstract stopPublishStream(stopTracks: boolean): Promise<void>;
108
+
109
+ protected abstract muteTracks(): void;
110
+
111
+ protected abstract unmuteTracks(): void;
97
112
 
98
- private async stopStream() {
113
+ private async muteStream(stopTracks: boolean = true) {
99
114
  if (!this.state.mediaStream) {
100
115
  return;
101
116
  }
102
117
  if (this.call.state.callingState === CallingState.JOINED) {
103
- await this.stopPublishStream();
118
+ await this.stopPublishStream(stopTracks);
104
119
  } else if (this.state.mediaStream) {
105
- disposeOfMediaStream(this.state.mediaStream);
120
+ stopTracks
121
+ ? disposeOfMediaStream(this.state.mediaStream)
122
+ : this.muteTracks();
123
+ }
124
+ if (stopTracks) {
125
+ this.state.setMediaStream(undefined);
106
126
  }
107
- this.state.setMediaStream(undefined);
108
127
  }
109
128
 
110
- private async startStream() {
129
+ private async unmuteStream() {
130
+ let stream: MediaStream;
111
131
  if (this.state.mediaStream) {
112
- return;
132
+ stream = this.state.mediaStream;
133
+ this.unmuteTracks();
134
+ } else {
135
+ const constraints = { deviceId: this.state.selectedDevice };
136
+ stream = await this.getStream(constraints);
113
137
  }
114
- const constraints = { deviceId: this.state.selectedDevice };
115
- const stream = await this.getStream(constraints);
116
138
  if (this.call.state.callingState === CallingState.JOINED) {
117
139
  await this.publishStream(stream);
118
140
  }
@@ -11,6 +11,10 @@ export abstract class InputMediaDeviceManagerState {
11
11
  protected selectedDeviceSubject = new BehaviorSubject<string | undefined>(
12
12
  undefined,
13
13
  );
14
+ /**
15
+ * @internal
16
+ */
17
+ prevStatus: InputDeviceStatus;
14
18
 
15
19
  /**
16
20
  * An Observable that emits the current media stream, or `undefined` if the device is currently disabled.
@@ -28,12 +32,18 @@ export abstract class InputMediaDeviceManagerState {
28
32
  */
29
33
  status$: Observable<InputDeviceStatus>;
30
34
 
31
- constructor() {
35
+ constructor(
36
+ public readonly disableMode:
37
+ | 'stop-tracks'
38
+ | 'disable-tracks' = 'stop-tracks',
39
+ ) {
32
40
  this.mediaStream$ = this.mediaStreamSubject.asObservable();
33
41
  this.selectedDevice$ = this.selectedDeviceSubject
34
42
  .asObservable()
35
43
  .pipe(distinctUntilChanged());
36
- this.status$ = this.statusSubject.asObservable();
44
+ this.status$ = this.statusSubject
45
+ .asObservable()
46
+ .pipe(distinctUntilChanged());
37
47
  }
38
48
 
39
49
  /**
@@ -21,25 +21,16 @@ export class MicrophoneManager extends InputMediaDeviceManager<MicrophoneManager
21
21
  protected publishStream(stream: MediaStream): Promise<void> {
22
22
  return this.call.publishAudioStream(stream);
23
23
  }
24
- protected stopPublishStream(): Promise<void> {
25
- return this.call.stopPublish(TrackType.AUDIO);
24
+ protected stopPublishStream(stopTracks: boolean): Promise<void> {
25
+ return this.call.stopPublish(TrackType.AUDIO, stopTracks);
26
26
  }
27
27
 
28
- /**
29
- * Disables the audio tracks of the microphone
30
- */
31
- pause() {
32
- this.state.mediaStream?.getAudioTracks().forEach((track) => {
33
- track.enabled = false;
34
- });
28
+ protected muteTracks(): void {
29
+ this.state.mediaStream
30
+ ?.getAudioTracks()
31
+ .forEach((t) => (t.enabled = false));
35
32
  }
36
-
37
- /**
38
- * (Re)enables the audio tracks of the microphone
39
- */
40
- resume() {
41
- this.state.mediaStream?.getAudioTracks().forEach((track) => {
42
- track.enabled = true;
43
- });
33
+ protected unmuteTracks(): void {
34
+ this.state.mediaStream?.getAudioTracks().forEach((t) => (t.enabled = true));
44
35
  }
45
36
  }
@@ -1,6 +1,10 @@
1
1
  import { InputMediaDeviceManagerState } from './InputMediaDeviceManagerState';
2
2
 
3
3
  export class MicrophoneManagerState extends InputMediaDeviceManagerState {
4
+ constructor() {
5
+ super('disable-tracks');
6
+ }
7
+
4
8
  protected getDeviceIdFromStream(stream: MediaStream): string | undefined {
5
9
  return stream.getAudioTracks()[0]?.getSettings().deviceId as
6
10
  | string
@@ -8,7 +8,6 @@ import { getVideoStream } from '../devices';
8
8
  import { TrackType } from '../../gen/video/sfu/models/models';
9
9
  import { CameraManager } from '../CameraManager';
10
10
  import { of } from 'rxjs';
11
- import { CallSettingsResponse } from '../../gen/coordinator';
12
11
 
13
12
  vi.mock('../devices.ts', () => {
14
13
  console.log('MOCKING devices API');
@@ -83,7 +82,10 @@ describe('CameraManager', () => {
83
82
 
84
83
  await manager.disable();
85
84
 
86
- expect(manager['call'].stopPublish).toHaveBeenCalledWith(TrackType.VIDEO);
85
+ expect(manager['call'].stopPublish).toHaveBeenCalledWith(
86
+ TrackType.VIDEO,
87
+ true,
88
+ );
87
89
  });
88
90
 
89
91
  it('flip', async () => {
@@ -131,18 +133,6 @@ describe('CameraManager', () => {
131
133
  });
132
134
  });
133
135
 
134
- it('should pause and resume tracks', async () => {
135
- await manager.enable();
136
-
137
- manager.pause();
138
-
139
- expect(manager.state.mediaStream?.getVideoTracks()[0].enabled).toBe(false);
140
-
141
- manager.resume();
142
-
143
- expect(manager.state.mediaStream?.getVideoTracks()[0].enabled).toBe(true);
144
- });
145
-
146
136
  afterEach(() => {
147
137
  vi.clearAllMocks();
148
138
  vi.resetModules();