@stream-io/video-client 0.5.1 → 0.5.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.
@@ -265,9 +265,10 @@ export declare class Call {
265
265
  */
266
266
  setSortParticipantsBy: CallState['setSortParticipantsBy'];
267
267
  /**
268
+ * Updates the list of video layers to publish.
269
+ *
268
270
  * @internal
269
- * @param enabledRids
270
- * @returns
271
+ * @param enabledLayers the list of layers to enable.
271
272
  */
272
273
  updatePublishQuality: (enabledLayers: VideoLayerSetting[]) => Promise<void | undefined>;
273
274
  private assertCallJoined;
@@ -434,6 +435,10 @@ export declare class Call {
434
435
  * @param data the request data.
435
436
  */
436
437
  updateCallMembers: (data: UpdateCallMembersRequest) => Promise<UpdateCallMembersResponse>;
438
+ /**
439
+ * Schedules an auto-drop timeout based on the call settings.
440
+ * Applicable only for ringing calls.
441
+ */
437
442
  private scheduleAutoDrop;
438
443
  /**
439
444
  * Retrieves the list of recordings for the current call or call session.
@@ -1,7 +1,7 @@
1
1
  import { BehaviorSubject, Observable } from 'rxjs';
2
2
  import type { Patch } from './rxUtils';
3
3
  import { Call } from '../Call';
4
- import type { OwnUserResponse } from '../coordinator/connection/types';
4
+ import type { OwnUserResponse } from '../gen/coordinator';
5
5
  export declare class StreamVideoWriteableStateStore {
6
6
  /**
7
7
  * A store keeping data of a successfully connected user over WS to the coordinator server.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-client",
3
- "version": "0.5.1",
3
+ "version": "0.5.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
@@ -82,10 +82,8 @@ import {
82
82
  debounce,
83
83
  filter,
84
84
  map,
85
- pairwise,
86
85
  Subject,
87
86
  takeWhile,
88
- tap,
89
87
  timer,
90
88
  } from 'rxjs';
91
89
  import { TrackSubscriptionDetails } from './gen/video/sfu/signal_rpc/signal';
@@ -1345,9 +1343,10 @@ export class Call {
1345
1343
  };
1346
1344
 
1347
1345
  /**
1346
+ * Updates the list of video layers to publish.
1347
+ *
1348
1348
  * @internal
1349
- * @param enabledRids
1350
- * @returns
1349
+ * @param enabledLayers the list of layers to enable.
1351
1350
  */
1352
1351
  updatePublishQuality = async (enabledLayers: VideoLayerSetting[]) => {
1353
1352
  return this.publisher?.updateVideoPublishQuality(enabledLayers);
@@ -1718,45 +1717,30 @@ export class Call {
1718
1717
  >(`${this.streamClientBasePath}/members`, data);
1719
1718
  };
1720
1719
 
1720
+ /**
1721
+ * Schedules an auto-drop timeout based on the call settings.
1722
+ * Applicable only for ringing calls.
1723
+ */
1721
1724
  private scheduleAutoDrop = () => {
1722
- if (this.dropTimeout) clearTimeout(this.dropTimeout);
1723
- const subscription = this.state.settings$
1724
- .pipe(
1725
- pairwise(),
1726
- tap(([prevSettings, currentSettings]) => {
1727
- if (!currentSettings || !this.clientStore.connectedUser) return;
1728
-
1729
- const isOutgoingCall =
1730
- this.currentUserId === this.state.createdBy?.id;
1731
-
1732
- const [prevTimeoutMs, timeoutMs] = isOutgoingCall
1733
- ? [
1734
- prevSettings?.ring.auto_cancel_timeout_ms,
1735
- currentSettings.ring.auto_cancel_timeout_ms,
1736
- ]
1737
- : [
1738
- prevSettings?.ring.incoming_call_timeout_ms,
1739
- currentSettings.ring.incoming_call_timeout_ms,
1740
- ];
1741
- if (
1742
- typeof timeoutMs === 'undefined' ||
1743
- timeoutMs === prevTimeoutMs ||
1744
- timeoutMs === 0
1745
- )
1746
- return;
1747
-
1748
- if (this.dropTimeout) clearTimeout(this.dropTimeout);
1749
- this.dropTimeout = setTimeout(() => this.leave(), timeoutMs);
1750
- }),
1751
- takeWhile(
1752
- () => !!this.clientStore.calls.find((call) => call.cid === this.cid),
1753
- ),
1754
- )
1755
- .subscribe();
1725
+ clearTimeout(this.dropTimeout);
1726
+ this.leaveCallHooks.add(
1727
+ createSubscription(this.state.settings$, (settings) => {
1728
+ if (!settings) return;
1729
+ // ignore if the call is not ringing
1730
+ if (this.state.callingState !== CallingState.RINGING) return;
1756
1731
 
1757
- this.leaveCallHooks.add(() => {
1758
- !subscription.closed && subscription.unsubscribe();
1759
- });
1732
+ const timeoutInMs = settings.ring.auto_cancel_timeout_ms;
1733
+ // 0 means no auto-drop
1734
+ if (timeoutInMs <= 0) return;
1735
+
1736
+ clearTimeout(this.dropTimeout);
1737
+ this.dropTimeout = setTimeout(() => {
1738
+ this.leave().catch((err) => {
1739
+ this.logger('error', 'Failed to drop call', err);
1740
+ });
1741
+ }, timeoutInMs);
1742
+ }),
1743
+ );
1760
1744
  };
1761
1745
 
1762
1746
  /**
@@ -58,7 +58,11 @@ describe('call API', () => {
58
58
  });
59
59
 
60
60
  it('RTMP address', async () => {
61
- const resp = await call.getOrCreate();
61
+ const resp = await call.getOrCreate({
62
+ data: {
63
+ created_by_id: 'john',
64
+ },
65
+ });
62
66
  const address = resp.call.ingress.rtmp.address;
63
67
 
64
68
  expect(address).toBeDefined();
@@ -218,12 +218,7 @@ export class Publisher {
218
218
  'info',
219
219
  `Track ${TrackType[trackType]} has ended, notifying the SFU`,
220
220
  );
221
- await this.notifyTrackMuteStateChanged(
222
- mediaStream,
223
- track,
224
- trackType,
225
- true,
226
- );
221
+ await this.notifyTrackMuteStateChanged(mediaStream, trackType, true);
227
222
  // clean-up, this event listener needs to run only once.
228
223
  track.removeEventListener('ended', handleTrackEnded);
229
224
  };
@@ -295,12 +290,7 @@ export class Publisher {
295
290
  await transceiver.sender.replaceTrack(track);
296
291
  }
297
292
 
298
- await this.notifyTrackMuteStateChanged(
299
- mediaStream,
300
- track,
301
- trackType,
302
- false,
303
- );
293
+ await this.notifyTrackMuteStateChanged(mediaStream, trackType, false);
304
294
  };
305
295
 
306
296
  /**
@@ -325,12 +315,7 @@ export class Publisher {
325
315
  : (transceiver.sender.track.enabled = false);
326
316
  // We don't need to notify SFU if unpublishing in response to remote soft mute
327
317
  if (this.state.localParticipant?.publishedTracks.includes(trackType)) {
328
- await this.notifyTrackMuteStateChanged(
329
- undefined,
330
- transceiver.sender.track,
331
- trackType,
332
- true,
333
- );
318
+ await this.notifyTrackMuteStateChanged(undefined, trackType, true);
334
319
  }
335
320
  }
336
321
  };
@@ -369,7 +354,6 @@ export class Publisher {
369
354
 
370
355
  private notifyTrackMuteStateChanged = async (
371
356
  mediaStream: MediaStream | undefined,
372
- track: MediaStreamTrack,
373
357
  trackType: TrackType,
374
358
  isMuted: boolean,
375
359
  ) => {
@@ -2,7 +2,8 @@ import { BehaviorSubject, Observable } from 'rxjs';
2
2
  import type { Patch } from './rxUtils';
3
3
  import * as RxUtils from './rxUtils';
4
4
  import { Call } from '../Call';
5
- import type { OwnUserResponse } from '../coordinator/connection/types';
5
+ import { CallingState } from './CallState';
6
+ import type { OwnUserResponse } from '../gen/coordinator';
6
7
  import { getLogger } from '../logger';
7
8
 
8
9
  export class StreamVideoWriteableStateStore {
@@ -22,12 +23,14 @@ export class StreamVideoWriteableStateStore {
22
23
  this.connectedUserSubject.subscribe(async (user) => {
23
24
  // leave all calls when the user disconnects.
24
25
  if (!user) {
26
+ const logger = getLogger(['client-state']);
25
27
  for (const call of this.calls) {
26
- getLogger(['client-state'])(
27
- 'info',
28
- `User disconnected, leaving call: ${call.cid}`,
29
- );
30
- await call.leave();
28
+ if (call.state.callingState === CallingState.LEFT) continue;
29
+
30
+ logger('info', `User disconnected, leaving call: ${call.cid}`);
31
+ await call.leave().catch((err) => {
32
+ logger('error', `Error leaving call: ${call.cid}`, err);
33
+ });
31
34
  }
32
35
  }
33
36
  });