@stream-io/video-client 0.4.0 → 0.4.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.
@@ -452,6 +452,7 @@ export declare class Call {
452
452
  sendCustomEvent: (payload: {
453
453
  [key: string]: any;
454
454
  }) => Promise<SendEventResponse>;
455
+ applyDeviceConfig: () => void;
455
456
  private initCamera;
456
457
  private initMic;
457
458
  /**
@@ -47,7 +47,7 @@ export declare abstract class InputMediaDeviceManager<T extends InputMediaDevice
47
47
  *
48
48
  * @param constraints the constraints to set.
49
49
  */
50
- setDefaultConstraints(constraints: C): Promise<void>;
50
+ setDefaultConstraints(constraints: C): void;
51
51
  /**
52
52
  * Select device
53
53
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
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
@@ -560,6 +560,8 @@ export class Call {
560
560
  this.clientStore.registerCall(this);
561
561
  }
562
562
 
563
+ this.applyDeviceConfig();
564
+
563
565
  return response;
564
566
  };
565
567
 
@@ -587,6 +589,8 @@ export class Call {
587
589
  this.clientStore.registerCall(this);
588
590
  }
589
591
 
592
+ this.applyDeviceConfig();
593
+
590
594
  return response;
591
595
  };
592
596
 
@@ -1001,8 +1005,8 @@ export class Call {
1001
1005
  this.state.setCallingState(CallingState.JOINED);
1002
1006
 
1003
1007
  try {
1004
- await this.initCamera();
1005
- await this.initMic();
1008
+ await this.initCamera({ setStatus: true });
1009
+ await this.initMic({ setStatus: true });
1006
1010
  } catch (error) {
1007
1011
  this.logger('warn', 'Camera and/or mic init failed during join call');
1008
1012
  }
@@ -1782,7 +1786,12 @@ export class Call {
1782
1786
  );
1783
1787
  };
1784
1788
 
1785
- private async initCamera() {
1789
+ applyDeviceConfig = () => {
1790
+ this.initCamera({ setStatus: false });
1791
+ this.initMic({ setStatus: false });
1792
+ };
1793
+
1794
+ private async initCamera(options: { setStatus: boolean }) {
1786
1795
  // Wait for any in progress camera operation
1787
1796
  if (this.camera.enablePromise) {
1788
1797
  await this.camera.enablePromise;
@@ -1814,25 +1823,27 @@ export class Call {
1814
1823
  await this.camera.selectTargetResolution(targetResolution);
1815
1824
  }
1816
1825
 
1817
- // Publish already that was set before we joined
1818
- if (
1819
- this.camera.state.status === 'enabled' &&
1820
- this.camera.state.mediaStream &&
1821
- !this.publisher?.isPublishing(TrackType.VIDEO)
1822
- ) {
1823
- await this.publishVideoStream(this.camera.state.mediaStream);
1824
- }
1826
+ if (options.setStatus) {
1827
+ // Publish already that was set before we joined
1828
+ if (
1829
+ this.camera.state.status === 'enabled' &&
1830
+ this.camera.state.mediaStream &&
1831
+ !this.publisher?.isPublishing(TrackType.VIDEO)
1832
+ ) {
1833
+ await this.publishVideoStream(this.camera.state.mediaStream);
1834
+ }
1825
1835
 
1826
- // Start camera if backend config speicifies, and there is no local setting
1827
- if (
1828
- this.camera.state.status === undefined &&
1829
- this.state.settings?.video.camera_default_on
1830
- ) {
1831
- await this.camera.enable();
1836
+ // Start camera if backend config speicifies, and there is no local setting
1837
+ if (
1838
+ this.camera.state.status === undefined &&
1839
+ this.state.settings?.video.camera_default_on
1840
+ ) {
1841
+ await this.camera.enable();
1842
+ }
1832
1843
  }
1833
1844
  }
1834
1845
 
1835
- private async initMic() {
1846
+ private async initMic(options: { setStatus: boolean }) {
1836
1847
  // Wait for any in progress mic operation
1837
1848
  if (this.microphone.enablePromise) {
1838
1849
  await this.microphone.enablePromise;
@@ -1848,21 +1859,23 @@ export class Call {
1848
1859
  return;
1849
1860
  }
1850
1861
 
1851
- // Publish media stream that was set before we joined
1852
- if (
1853
- this.microphone.state.status === 'enabled' &&
1854
- this.microphone.state.mediaStream &&
1855
- !this.publisher?.isPublishing(TrackType.AUDIO)
1856
- ) {
1857
- await this.publishAudioStream(this.microphone.state.mediaStream);
1858
- }
1862
+ if (options.setStatus) {
1863
+ // Publish media stream that was set before we joined
1864
+ if (
1865
+ this.microphone.state.status === 'enabled' &&
1866
+ this.microphone.state.mediaStream &&
1867
+ !this.publisher?.isPublishing(TrackType.AUDIO)
1868
+ ) {
1869
+ await this.publishAudioStream(this.microphone.state.mediaStream);
1870
+ }
1859
1871
 
1860
- // Start mic if backend config specifies, and there is no local setting
1861
- if (
1862
- this.microphone.state.status === undefined &&
1863
- this.state.settings?.audio.mic_default_on
1864
- ) {
1865
- await this.microphone.enable();
1872
+ // Start mic if backend config specifies, and there is no local setting
1873
+ if (
1874
+ this.microphone.state.status === undefined &&
1875
+ this.state.settings?.audio.mic_default_on
1876
+ ) {
1877
+ await this.microphone.enable();
1878
+ }
1866
1879
  }
1867
1880
  }
1868
1881
 
@@ -352,6 +352,7 @@ export class StreamVideoClient {
352
352
  clientStore: this.writeableStateStore,
353
353
  });
354
354
  call.state.updateFromCallResponse(c.call);
355
+ call.applyDeviceConfig();
355
356
  if (data.watch) {
356
357
  this.writeableStateStore.registerCall(call);
357
358
  }
@@ -8,9 +8,6 @@ import { User } from '../coordinator/connection/types';
8
8
  const apiKey = process.env.STREAM_API_KEY!;
9
9
  const secret = process.env.STREAM_SECRET!;
10
10
 
11
- vi.mock('../devices/CameraManager.ts');
12
- vi.mock('../devices/MicrophoneManager.ts');
13
-
14
11
  const tokenProvider = (userId: string) => {
15
12
  const serverClient = new StreamVideoServerClient(apiKey, { secret });
16
13
  return async () => {
@@ -44,13 +44,12 @@ export abstract class InputMediaDeviceManager<
44
44
  * Starts stream.
45
45
  */
46
46
  async enable() {
47
- if (this.state.status === 'enabled') {
48
- return;
49
- }
47
+ if (this.state.status === 'enabled') return;
50
48
  this.enablePromise = this.unmuteStream();
51
49
  try {
52
50
  await this.enablePromise;
53
51
  this.state.setStatus('enabled');
52
+ this.enablePromise = undefined;
54
53
  } catch (error) {
55
54
  this.enablePromise = undefined;
56
55
  throw error;
@@ -62,12 +61,9 @@ export abstract class InputMediaDeviceManager<
62
61
  */
63
62
  async disable() {
64
63
  this.state.prevStatus = this.state.status;
65
- if (this.state.status === 'disabled') {
66
- return;
67
- }
68
- this.disablePromise = this.muteStream(
69
- this.state.disableMode === 'stop-tracks',
70
- );
64
+ if (this.state.status === 'disabled') return;
65
+ const stopTracks = this.state.disableMode === 'stop-tracks';
66
+ this.disablePromise = this.muteStream(stopTracks);
71
67
  try {
72
68
  await this.disablePromise;
73
69
  this.state.setStatus('disabled');
@@ -107,7 +103,7 @@ export abstract class InputMediaDeviceManager<
107
103
  *
108
104
  * @param constraints the constraints to set.
109
105
  */
110
- async setDefaultConstraints(constraints: C) {
106
+ setDefaultConstraints(constraints: C) {
111
107
  this.state.setDefaultConstraints(constraints);
112
108
  }
113
109
 
@@ -149,25 +145,24 @@ export abstract class InputMediaDeviceManager<
149
145
  }
150
146
 
151
147
  protected async muteStream(stopTracks: boolean = true) {
152
- if (!this.state.mediaStream) {
153
- return;
154
- }
148
+ if (!this.state.mediaStream) return;
155
149
  this.logger('debug', `${stopTracks ? 'Stopping' : 'Disabling'} stream`);
156
150
  if (this.call.state.callingState === CallingState.JOINED) {
157
151
  await this.stopPublishStream(stopTracks);
158
152
  }
159
153
  this.muteLocalStream(stopTracks);
160
- this.getTracks().forEach((track) => {
161
- if (track.readyState === 'ended') {
154
+ const allEnded = this.getTracks().every((t) => t.readyState === 'ended');
155
+ if (allEnded) {
156
+ if (
157
+ this.state.mediaStream &&
162
158
  // @ts-expect-error release() is present in react-native-webrtc
163
- // and must be called to dispose the stream
164
- if (typeof this.state.mediaStream.release === 'function') {
165
- // @ts-expect-error
166
- this.state.mediaStream.release();
167
- }
168
- this.state.setMediaStream(undefined);
159
+ typeof this.state.mediaStream.release === 'function'
160
+ ) {
161
+ // @ts-expect-error called to dispose the stream in RN
162
+ this.state.mediaStream.release();
169
163
  }
170
- });
164
+ this.state.setMediaStream(undefined);
165
+ }
171
166
  }
172
167
 
173
168
  private muteTracks() {