@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.
- package/CHANGELOG.md +7 -0
- package/dist/index.browser.es.js +159 -159
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +158 -158
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +159 -159
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +7 -2
- package/dist/src/store/stateStore.d.ts +1 -1
- package/package.json +1 -1
- package/src/Call.ts +25 -41
- package/src/__tests__/server-side/call.test.ts +5 -1
- package/src/rtc/Publisher.ts +3 -19
- package/src/store/stateStore.ts +9 -6
package/dist/src/Call.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
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
|
|
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
|
-
|
|
1723
|
-
|
|
1724
|
-
.
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
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
|
-
|
|
1758
|
-
|
|
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();
|
package/src/rtc/Publisher.ts
CHANGED
|
@@ -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
|
) => {
|
package/src/store/stateStore.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
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
|
});
|