@stream-io/video-client 0.3.36 → 0.4.0

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.
@@ -252,38 +252,6 @@ export declare class Call {
252
252
  * @param sessionId the sessionId to stop reporting for.
253
253
  */
254
254
  stopReportingStatsFor: (sessionId: string) => void | undefined;
255
- /**
256
- * Sets the used audio output device (`audioOutputDeviceId` of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore).
257
- *
258
- * This method only stores the selection, if you're using custom UI components, you'll have to implement the audio switching, for more information see: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/sinkId.
259
- *
260
- *
261
- * @param deviceId the selected device, `undefined` means the user wants to use the system's default audio output
262
- *
263
- * @deprecated use `call.speaker` instead
264
- */
265
- setAudioOutputDevice: (deviceId?: string) => void;
266
- /**
267
- * Sets the `audioDeviceId` property of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore)).
268
- *
269
- * This method only stores the selection, if you want to start publishing a media stream call the [`publishAudioStream` method](#publishaudiostream) that will set `audioDeviceId` as well.
270
- *
271
- *
272
- * @param deviceId the selected device, pass `undefined` to clear the device selection
273
- *
274
- * @deprecated use call.microphone.select
275
- */
276
- setAudioDevice: (deviceId?: string) => void;
277
- /**
278
- * Sets the `videoDeviceId` property of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore).
279
- *
280
- * This method only stores the selection, if you want to start publishing a media stream call the [`publishVideoStream` method](#publishvideostream) that will set `videoDeviceId` as well.
281
- *
282
- * @param deviceId the selected device, pass `undefined` to clear the device selection
283
- *
284
- * @deprecated use call.camera.select
285
- */
286
- setVideoDevice: (deviceId?: string) => void;
287
255
  /**
288
256
  * Resets the last sent reaction for the user holding the given `sessionId`. This is a local action, it won't reset the reaction on the backend.
289
257
  *
@@ -24,7 +24,7 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
24
24
  *
25
25
  * @returns an Observable that will be updated if a device is connected or disconnected
26
26
  */
27
- listDevices(): Observable<MediaDeviceInfo[]>;
27
+ listDevices(): Observable<MediaDeviceInfo[] | undefined>;
28
28
  /**
29
29
  * Starts stream.
30
30
  */
@@ -57,7 +57,7 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
57
57
  */
58
58
  select(deviceId: string | undefined): Promise<void>;
59
59
  protected applySettingsToStream(): Promise<void>;
60
- protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
60
+ protected abstract getDevices(): Observable<MediaDeviceInfo[] | undefined>;
61
61
  protected abstract getStream(constraints: C): Promise<MediaStream>;
62
62
  protected abstract publishStream(stream: MediaStream): Promise<void>;
63
63
  protected abstract stopPublishStream(stopTracks: boolean): Promise<void>;
@@ -33,6 +33,7 @@ export declare class PermissionsContext {
33
33
  * within the call.
34
34
  *
35
35
  * @param permission the permission to check for.
36
+ * @param settings the call settings to check against (optional).
36
37
  */
37
- canRequest: (permission: OwnCapability) => boolean;
38
+ canRequest: (permission: OwnCapability, settings?: CallSettingsResponse | undefined) => boolean;
38
39
  }
@@ -1,4 +1,4 @@
1
- import { JoinCallData, StreamVideoLocalParticipant, StreamVideoParticipant } from '../../types';
1
+ import { JoinCallData, StreamVideoParticipant } from '../../types';
2
2
  import { StreamClient } from '../../coordinator/connection/client';
3
3
  /**
4
4
  * Collects all necessary information to join a call, talks to the coordinator
@@ -23,4 +23,4 @@ export declare const join: (httpClient: StreamClient, type: string, id: string,
23
23
  * @param target the participant to reconcile into.
24
24
  * @param source the participant to reconcile from.
25
25
  */
26
- export declare const reconcileParticipantLocalState: (target: StreamVideoParticipant | StreamVideoLocalParticipant, source?: StreamVideoParticipant | StreamVideoLocalParticipant) => StreamVideoParticipant | StreamVideoLocalParticipant;
26
+ export declare const reconcileParticipantLocalState: (target: StreamVideoParticipant, source?: StreamVideoParticipant) => StreamVideoParticipant;
@@ -1,6 +1,5 @@
1
1
  import { TrackType } from '../../gen/video/sfu/models/models';
2
- import type { StreamVideoLocalParticipant, StreamVideoParticipant } from '../../types';
2
+ import type { StreamVideoParticipant } from '../../types';
3
3
  import { TrackMuteType } from '../../types';
4
4
  export declare const trackTypeToParticipantStreamKey: (trackType: TrackType) => keyof StreamVideoParticipant;
5
- export declare const trackTypeToDeviceIdKey: (trackType: TrackType) => keyof StreamVideoLocalParticipant | undefined;
6
5
  export declare const muteTypeToTrackType: (muteType: TrackMuteType) => TrackType;
@@ -1,6 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import type { Patch } from './rxUtils';
3
- import { StreamVideoLocalParticipant, StreamVideoParticipant, StreamVideoParticipantPatch, StreamVideoParticipantPatches } from '../types';
3
+ import { StreamVideoParticipant, StreamVideoParticipantPatch, StreamVideoParticipantPatches } from '../types';
4
4
  import { CallStatsReport } from '../stats/types';
5
5
  import { CallIngressResponse, CallResponse, CallSessionResponse, CallSettingsResponse, EgressResponse, MemberResponse, OwnCapability, ThumbnailResponse, UserResponse, VideoEvent } from '../gen/coordinator';
6
6
  import { Pin } from '../gen/video/sfu/models/models';
@@ -99,7 +99,7 @@ export declare class CallState {
99
99
  /**
100
100
  * All participants of the current call (this includes the current user and other participants as well).
101
101
  */
102
- participants$: Observable<(StreamVideoParticipant | StreamVideoLocalParticipant)[]>;
102
+ participants$: Observable<StreamVideoParticipant[]>;
103
103
  /**
104
104
  * Remote participants of the current call (this includes every participant except the logged-in user).
105
105
  */
@@ -107,7 +107,7 @@ export declare class CallState {
107
107
  /**
108
108
  * The local participant of the current call (the logged-in user).
109
109
  */
110
- localParticipant$: Observable<StreamVideoLocalParticipant | undefined>;
110
+ localParticipant$: Observable<StreamVideoParticipant | undefined>;
111
111
  /**
112
112
  * Pinned participants of the current call.
113
113
  */
@@ -289,7 +289,7 @@ export declare class CallState {
289
289
  /**
290
290
  * The list of participants in the current call.
291
291
  */
292
- get participants(): (StreamVideoParticipant | StreamVideoLocalParticipant)[];
292
+ get participants(): StreamVideoParticipant[];
293
293
  /**
294
294
  * Sets the list of participants in the current call.
295
295
  *
@@ -301,7 +301,7 @@ export declare class CallState {
301
301
  /**
302
302
  * The local participant in the current call.
303
303
  */
304
- get localParticipant(): StreamVideoLocalParticipant | undefined;
304
+ get localParticipant(): StreamVideoParticipant | undefined;
305
305
  /**
306
306
  * The list of remote participants in the current call.
307
307
  */
@@ -437,7 +437,7 @@ export declare class CallState {
437
437
  * Returns a new lookup table of participants indexed by their session ID.
438
438
  */
439
439
  getParticipantLookupBySessionId: () => {
440
- [sessionId: string]: StreamVideoParticipant | StreamVideoLocalParticipant | undefined;
440
+ [sessionId: string]: StreamVideoParticipant | undefined;
441
441
  };
442
442
  /**
443
443
  * Updates a participant in the current call identified by the given `sessionId`.
@@ -449,7 +449,7 @@ export declare class CallState {
449
449
  * @param patch the patch to apply to the participant.
450
450
  * @returns the updated participant or `undefined` if the participant couldn't be found.
451
451
  */
452
- updateParticipant: (sessionId: string, patch: StreamVideoParticipantPatch | ((p: StreamVideoParticipant) => StreamVideoParticipantPatch)) => StreamVideoParticipant[] | undefined;
452
+ updateParticipant: (sessionId: string, patch: Partial<StreamVideoParticipant> | ((p: StreamVideoParticipant) => StreamVideoParticipantPatch)) => StreamVideoParticipant[] | undefined;
453
453
  /**
454
454
  * Updates a participant in the current call identified by the given `sessionId`.
455
455
  * If a participant with matching `sessionId` can't be found, the provided
@@ -65,28 +65,6 @@ export interface StreamVideoParticipant extends Participant {
65
65
  */
66
66
  viewportVisibilityState?: Record<VideoTrackType, VisibilityState>;
67
67
  }
68
- export interface StreamVideoLocalParticipant extends StreamVideoParticipant {
69
- /**
70
- * The device ID of the currently selected audio input device of the local participant (returned by the [MediaDevices API](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia))
71
- *
72
- * @deprecated use call.microphone.state.selectedDevice
73
- */
74
- audioDeviceId?: string;
75
- /**
76
- * The device ID of the currently selected video input device of the local participant (returned by the [MediaDevices API](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia))
77
- *
78
- * @deprecated use call.camera.state.selectedDevice
79
- */
80
- videoDeviceId?: string;
81
- /**
82
- * The device ID of the currently selected audio output device of the local participant (returned by the [MediaDevices API](https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia))
83
- *
84
- * If the value is not defined, the user hasn't selected any device (in these cases the default system audio output could be used)
85
- *
86
- * @deprecated use call.speaker.state.selectedDevice
87
- */
88
- audioOutputDeviceId?: string;
89
- }
90
68
  export type VideoTrackType = 'videoTrack' | 'screenShareTrack';
91
69
  export type AudioTrackType = 'audioTrack' | 'screenShareAudioTrack';
92
70
  export type TrackMuteType = 'audio' | 'video' | 'screenshare' | 'screenshare_audio';
@@ -104,11 +82,10 @@ export type ParticipantPin = {
104
82
  */
105
83
  pinnedAt: number;
106
84
  };
107
- export declare const isStreamVideoLocalParticipant: (p: StreamVideoParticipant | StreamVideoLocalParticipant) => p is StreamVideoLocalParticipant;
108
85
  /**
109
86
  * A partial representation of the StreamVideoParticipant.
110
87
  */
111
- export type StreamVideoParticipantPatch = Partial<StreamVideoParticipant | StreamVideoLocalParticipant>;
88
+ export type StreamVideoParticipantPatch = Partial<StreamVideoParticipant>;
112
89
  /**
113
90
  * A collection of {@link StreamVideoParticipantPatch} organized by sessionId.
114
91
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.3.36",
3
+ "version": "0.4.0",
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
@@ -9,11 +9,7 @@ import {
9
9
  Subscriber,
10
10
  } from './rtc';
11
11
  import { muteTypeToTrackType } from './rtc/helpers/tracks';
12
- import {
13
- GoAwayReason,
14
- SdkType,
15
- TrackType,
16
- } from './gen/video/sfu/models/models';
12
+ import { GoAwayReason, TrackType } from './gen/video/sfu/models/models';
17
13
  import {
18
14
  registerEventHandlers,
19
15
  registerRingingCallEventHandlers,
@@ -120,7 +116,7 @@ import {
120
116
  Logger,
121
117
  StreamCallEvent,
122
118
  } from './coordinator/connection/types';
123
- import { getClientDetails, getSdkInfo } from './client-details';
119
+ import { getClientDetails } from './client-details';
124
120
  import { getLogger } from './logger';
125
121
  import {
126
122
  CameraDirection,
@@ -1004,14 +1000,11 @@ export class Call {
1004
1000
  this.reconnectAttempts = 0; // reset the reconnect attempts counter
1005
1001
  this.state.setCallingState(CallingState.JOINED);
1006
1002
 
1007
- // React uses a different device management for now
1008
- if (getSdkInfo()?.type !== SdkType.REACT) {
1009
- try {
1010
- await this.initCamera();
1011
- await this.initMic();
1012
- } catch (error) {
1013
- this.logger('warn', 'Camera and/or mic init failed during join call');
1014
- }
1003
+ try {
1004
+ await this.initCamera();
1005
+ await this.initMic();
1006
+ } catch (error) {
1007
+ this.logger('warn', 'Camera and/or mic init failed during join call');
1015
1008
  }
1016
1009
 
1017
1010
  // 3. once we have the "joinResponse", and possibly reconciled the local state
@@ -1322,56 +1315,6 @@ export class Call {
1322
1315
  return this.statsReporter?.stopReportingStatsFor(sessionId);
1323
1316
  };
1324
1317
 
1325
- /**
1326
- * Sets the used audio output device (`audioOutputDeviceId` of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore).
1327
- *
1328
- * This method only stores the selection, if you're using custom UI components, you'll have to implement the audio switching, for more information see: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/sinkId.
1329
- *
1330
- *
1331
- * @param deviceId the selected device, `undefined` means the user wants to use the system's default audio output
1332
- *
1333
- * @deprecated use `call.speaker` instead
1334
- */
1335
- setAudioOutputDevice = (deviceId?: string) => {
1336
- if (!this.sfuClient) return;
1337
- this.state.updateParticipant(this.sfuClient.sessionId, {
1338
- audioOutputDeviceId: deviceId,
1339
- });
1340
- };
1341
-
1342
- /**
1343
- * Sets the `audioDeviceId` property of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore)).
1344
- *
1345
- * This method only stores the selection, if you want to start publishing a media stream call the [`publishAudioStream` method](#publishaudiostream) that will set `audioDeviceId` as well.
1346
- *
1347
- *
1348
- * @param deviceId the selected device, pass `undefined` to clear the device selection
1349
- *
1350
- * @deprecated use call.microphone.select
1351
- */
1352
- setAudioDevice = (deviceId?: string) => {
1353
- if (!this.sfuClient) return;
1354
- this.state.updateParticipant(this.sfuClient.sessionId, {
1355
- audioDeviceId: deviceId,
1356
- });
1357
- };
1358
-
1359
- /**
1360
- * Sets the `videoDeviceId` property of the [`localParticipant$`](./StreamVideoClient.md/#readonlystatestore).
1361
- *
1362
- * This method only stores the selection, if you want to start publishing a media stream call the [`publishVideoStream` method](#publishvideostream) that will set `videoDeviceId` as well.
1363
- *
1364
- * @param deviceId the selected device, pass `undefined` to clear the device selection
1365
- *
1366
- * @deprecated use call.camera.select
1367
- */
1368
- setVideoDevice = (deviceId?: string) => {
1369
- if (!this.sfuClient) return;
1370
- this.state.updateParticipant(this.sfuClient.sessionId, {
1371
- videoDeviceId: deviceId,
1372
- });
1373
- };
1374
-
1375
1318
  /**
1376
1319
  * Resets the last sent reaction for the user holding the given `sessionId`. This is a local action, it won't reset the reaction on the backend.
1377
1320
  *
@@ -136,7 +136,7 @@ export abstract class InputMediaDeviceManager<
136
136
  }
137
137
  }
138
138
 
139
- protected abstract getDevices(): Observable<MediaDeviceInfo[]>;
139
+ protected abstract getDevices(): Observable<MediaDeviceInfo[] | undefined>;
140
140
 
141
141
  protected abstract getStream(constraints: C): Promise<MediaStream>;
142
142
 
@@ -2,18 +2,12 @@ import { Call } from '../Call';
2
2
  import {
3
3
  AudioTrackType,
4
4
  DebounceType,
5
- StreamVideoLocalParticipant,
6
5
  StreamVideoParticipant,
7
6
  VideoTrackType,
8
7
  VisibilityState,
9
8
  } from '../types';
9
+ import { TrackType, VideoDimension } from '../gen/video/sfu/models/models';
10
10
  import {
11
- SdkType,
12
- TrackType,
13
- VideoDimension,
14
- } from '../gen/video/sfu/models/models';
15
- import {
16
- combineLatest,
17
11
  distinctUntilChanged,
18
12
  distinctUntilKeyChanged,
19
13
  map,
@@ -22,7 +16,6 @@ import {
22
16
  } from 'rxjs';
23
17
  import { ViewportTracker } from './ViewportTracker';
24
18
  import { getLogger } from '../logger';
25
- import { getSdkInfo } from '../client-details';
26
19
  import { isFirefox, isSafari } from './browsers';
27
20
 
28
21
  const DEFAULT_VIEWPORT_VISIBILITY_STATE: Record<
@@ -174,7 +167,7 @@ export class DynascaleManager {
174
167
  (participants) =>
175
168
  participants.find(
176
169
  (participant) => participant.sessionId === sessionId,
177
- ) as StreamVideoLocalParticipant | StreamVideoParticipant,
170
+ ) as StreamVideoParticipant,
178
171
  ),
179
172
  takeWhile((participant) => !!participant),
180
173
  distinctUntilChanged(),
@@ -339,9 +332,9 @@ export class DynascaleManager {
339
332
  const participant$ = this.call.state.participants$.pipe(
340
333
  map(
341
334
  (participants) =>
342
- participants.find((p) => p.sessionId === sessionId) as
343
- | StreamVideoLocalParticipant
344
- | StreamVideoParticipant,
335
+ participants.find(
336
+ (p) => p.sessionId === sessionId,
337
+ ) as StreamVideoParticipant,
345
338
  ),
346
339
  takeWhile((p) => !!p),
347
340
  distinctUntilChanged(),
@@ -373,20 +366,14 @@ export class DynascaleManager {
373
366
  });
374
367
  });
375
368
 
376
- const sinkIdSubscription = combineLatest([
377
- this.call.state.localParticipant$,
378
- this.call.speaker.state.selectedDevice$,
379
- ]).subscribe(([p, selectedDevice]) => {
380
- const deviceId =
381
- getSdkInfo()?.type === SdkType.REACT
382
- ? p?.audioOutputDeviceId
383
- : selectedDevice;
384
-
385
- if ('setSinkId' in audioElement && typeof deviceId === 'string') {
386
- // @ts-expect-error setSinkId is not yet in the lib
387
- audioElement.setSinkId(deviceId);
388
- }
389
- });
369
+ const sinkIdSubscription = !('setSinkId' in audioElement)
370
+ ? null
371
+ : this.call.speaker.state.selectedDevice$.subscribe((deviceId) => {
372
+ if (deviceId) {
373
+ // @ts-expect-error setSinkId is not yet in the lib
374
+ audioElement.setSinkId(deviceId);
375
+ }
376
+ });
390
377
 
391
378
  const volumeSubscription = this.call.speaker.state.volume$.subscribe(
392
379
  (volume) => {
@@ -397,7 +384,7 @@ export class DynascaleManager {
397
384
  audioElement.autoplay = true;
398
385
 
399
386
  return () => {
400
- sinkIdSubscription.unsubscribe();
387
+ sinkIdSubscription?.unsubscribe();
401
388
  volumeSubscription.unsubscribe();
402
389
  updateMediaStreamSubscription.unsubscribe();
403
390
  };
@@ -4,21 +4,14 @@
4
4
 
5
5
  import '../../rtc/__tests__/mocks/webrtc.mocks';
6
6
 
7
- import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
7
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
8
8
  import { DynascaleManager } from '../DynascaleManager';
9
9
  import { Call } from '../../Call';
10
10
  import { StreamClient } from '../../coordinator/connection/client';
11
11
  import { StreamVideoWriteableStateStore } from '../../store';
12
12
  import { DebounceType, VisibilityState } from '../../types';
13
13
  import { noopComparator } from '../../sorting';
14
- import { SdkType, TrackType } from '../../gen/video/sfu/models/models';
15
- import { getSdkInfo } from '../../client-details';
16
-
17
- vi.mock('../../client-details.ts', () => {
18
- return {
19
- getSdkInfo: vi.fn(),
20
- };
21
- });
14
+ import { TrackType } from '../../gen/video/sfu/models/models';
22
15
 
23
16
  describe('DynascaleManager', () => {
24
17
  let dynascaleManager: DynascaleManager;
@@ -145,7 +138,7 @@ describe('DynascaleManager', () => {
145
138
  expect(audioElement.volume).toBe(1);
146
139
 
147
140
  // @ts-expect-error setSinkId is not defined in types
148
- expect(audioElement.setSinkId).toHaveBeenCalledWith('');
141
+ expect(audioElement.setSinkId).not.toHaveBeenCalled();
149
142
 
150
143
  call.speaker.select('different-device-id');
151
144
 
@@ -154,18 +147,6 @@ describe('DynascaleManager', () => {
154
147
  'different-device-id',
155
148
  );
156
149
 
157
- const mock = getSdkInfo as Mock;
158
- mock.mockImplementation(() => ({
159
- type: SdkType.REACT,
160
- }));
161
-
162
- call.state.updateParticipant('session-id-local', {
163
- audioOutputDeviceId: 'new-device-id',
164
- });
165
-
166
- // @ts-expect-error setSinkId is not defined in types
167
- expect(audioElement.setSinkId).toHaveBeenCalledWith('new-device-id');
168
-
169
150
  call.speaker.setVolume(0.5);
170
151
 
171
152
  expect(audioElement.volume).toBe(0.5);
@@ -44,11 +44,15 @@ export class PermissionsContext {
44
44
  * within the call.
45
45
  *
46
46
  * @param permission the permission to check for.
47
+ * @param settings the call settings to check against (optional).
47
48
  */
48
- canRequest = (permission: OwnCapability) => {
49
- if (!this.settings) return false;
49
+ canRequest = (
50
+ permission: OwnCapability,
51
+ settings: CallSettingsResponse | undefined = this.settings,
52
+ ) => {
53
+ if (!settings) return false;
50
54
 
51
- const { audio, video, screensharing } = this.settings;
55
+ const { audio, video, screensharing } = settings;
52
56
  switch (permission) {
53
57
  case OwnCapability.SEND_AUDIO:
54
58
  return audio.access_request_enabled;
@@ -14,10 +14,7 @@ import {
14
14
  OptimalVideoLayer,
15
15
  } from './videoLayers';
16
16
  import { getPreferredCodecs } from './codecs';
17
- import {
18
- trackTypeToDeviceIdKey,
19
- trackTypeToParticipantStreamKey,
20
- } from './helpers/tracks';
17
+ import { trackTypeToParticipantStreamKey } from './helpers/tracks';
21
18
  import { CallState } from '../store';
22
19
  import { PublishOptions } from '../types';
23
20
  import { isReactNative } from '../helpers/platforms';
@@ -388,14 +385,11 @@ export class Publisher {
388
385
  [audioOrVideoOrScreenShareStream]: undefined,
389
386
  }));
390
387
  } else {
391
- const deviceId = track.getSettings().deviceId;
392
- const audioOrVideoDeviceKey = trackTypeToDeviceIdKey(trackType);
393
388
  this.state.updateParticipant(this.sfuClient.sessionId, (p) => {
394
389
  return {
395
390
  publishedTracks: p.publishedTracks.includes(trackType)
396
391
  ? p.publishedTracks
397
392
  : [...p.publishedTracks, trackType],
398
- ...(audioOrVideoDeviceKey && { [audioOrVideoDeviceKey]: deviceId }),
399
393
  [audioOrVideoOrScreenShareStream]: mediaStream,
400
394
  };
401
395
  });
@@ -99,7 +99,6 @@ describe('Publisher', () => {
99
99
  // initial publish
100
100
  await publisher.publishStream(mediaStream, track, TrackType.VIDEO);
101
101
 
102
- expect(state.localParticipant?.videoDeviceId).toEqual('test-device-id');
103
102
  expect(state.localParticipant?.publishedTracks).toContain(TrackType.VIDEO);
104
103
  expect(state.localParticipant?.videoStream).toEqual(mediaStream);
105
104
  expect(transceiver.setCodecPreferences).toHaveBeenCalled();
@@ -136,7 +135,6 @@ describe('Publisher', () => {
136
135
  expect.any(Function),
137
136
  );
138
137
  expect(transceiver.sender.replaceTrack).toHaveBeenCalledWith(newTrack);
139
- expect(state.localParticipant?.videoDeviceId).toEqual('test-device-id-2');
140
138
 
141
139
  // stop publishing
142
140
  await publisher.unpublishStream(TrackType.VIDEO, true);
@@ -144,7 +142,6 @@ describe('Publisher', () => {
144
142
  expect(state.localParticipant?.publishedTracks).not.toContain(
145
143
  TrackType.VIDEO,
146
144
  );
147
- expect(state.localParticipant?.videoDeviceId).toEqual('test-device-id-2');
148
145
  });
149
146
 
150
147
  it('can publish and un-pubish with just enabling and disabling tracks', async () => {
@@ -178,7 +175,6 @@ describe('Publisher', () => {
178
175
  // initial publish
179
176
  await publisher.publishStream(mediaStream, track, TrackType.VIDEO);
180
177
 
181
- expect(state.localParticipant?.videoDeviceId).toEqual('test-device-id');
182
178
  expect(state.localParticipant?.publishedTracks).toContain(TrackType.VIDEO);
183
179
  expect(track.enabled).toBe(true);
184
180
  expect(state.localParticipant?.videoStream).toEqual(mediaStream);
@@ -3,12 +3,7 @@ import {
3
3
  JoinCallRequest,
4
4
  JoinCallResponse,
5
5
  } from '../../gen/coordinator';
6
- import {
7
- isStreamVideoLocalParticipant,
8
- JoinCallData,
9
- StreamVideoLocalParticipant,
10
- StreamVideoParticipant,
11
- } from '../../types';
6
+ import { JoinCallData, StreamVideoParticipant } from '../../types';
12
7
  import { StreamClient } from '../../coordinator/connection/client';
13
8
 
14
9
  /**
@@ -107,21 +102,11 @@ const getCascadingModeParams = () => {
107
102
  * @param source the participant to reconcile from.
108
103
  */
109
104
  export const reconcileParticipantLocalState = (
110
- target: StreamVideoParticipant | StreamVideoLocalParticipant,
111
- source?: StreamVideoParticipant | StreamVideoLocalParticipant,
105
+ target: StreamVideoParticipant,
106
+ source?: StreamVideoParticipant,
112
107
  ) => {
113
108
  if (!source) return target;
114
109
 
115
110
  // copy everything from source to target
116
- Object.assign(target, source);
117
-
118
- if (
119
- isStreamVideoLocalParticipant(source) &&
120
- isStreamVideoLocalParticipant(target)
121
- ) {
122
- target.audioDeviceId = source.audioDeviceId;
123
- target.videoDeviceId = source.videoDeviceId;
124
- target.audioOutputDeviceId = source.audioOutputDeviceId;
125
- }
126
- return target;
111
+ return Object.assign(target, source);
127
112
  };
@@ -1,8 +1,5 @@
1
1
  import { TrackType } from '../../gen/video/sfu/models/models';
2
- import type {
3
- StreamVideoLocalParticipant,
4
- StreamVideoParticipant,
5
- } from '../../types';
2
+ import type { StreamVideoParticipant } from '../../types';
6
3
  import { TrackMuteType } from '../../types';
7
4
 
8
5
  export const trackTypeToParticipantStreamKey = (
@@ -25,24 +22,6 @@ export const trackTypeToParticipantStreamKey = (
25
22
  }
26
23
  };
27
24
 
28
- export const trackTypeToDeviceIdKey = (
29
- trackType: TrackType,
30
- ): keyof StreamVideoLocalParticipant | undefined => {
31
- switch (trackType) {
32
- case TrackType.AUDIO:
33
- return 'audioDeviceId';
34
- case TrackType.VIDEO:
35
- return 'videoDeviceId';
36
- case TrackType.SCREEN_SHARE:
37
- case TrackType.SCREEN_SHARE_AUDIO:
38
- case TrackType.UNSPECIFIED:
39
- return undefined;
40
- default:
41
- const exhaustiveTrackTypeCheck: never = trackType;
42
- throw new Error(`Unknown track type: ${exhaustiveTrackTypeCheck}`);
43
- }
44
- };
45
-
46
25
  export const muteTypeToTrackType = (muteType: TrackMuteType): TrackType => {
47
26
  switch (muteType) {
48
27
  case 'audio':