@stream-io/video-client 0.3.20 → 0.3.21
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 +20 -4
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +20 -4
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +20 -4
- package/dist/index.es.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/__tests__/server-side/call.test.ts +1 -1
- package/src/helpers/DynascaleManager.ts +19 -3
- package/src/helpers/__tests__/DynascaleManager.test.ts +51 -11
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "0.3.
|
|
1
|
+
export declare const version = "0.3.21";
|
package/package.json
CHANGED
|
@@ -120,9 +120,9 @@ describe('call API', () => {
|
|
|
120
120
|
response = await call.update({
|
|
121
121
|
settings_override: {
|
|
122
122
|
recording: {
|
|
123
|
-
mode: RecordSettingsRequestModeEnum.AVAILABLE,
|
|
124
123
|
audio_only: false,
|
|
125
124
|
quality: RecordSettingsRequestQualityEnum._1080P,
|
|
125
|
+
mode: RecordSettingsRequestModeEnum.AUTO_ON,
|
|
126
126
|
},
|
|
127
127
|
},
|
|
128
128
|
});
|
|
@@ -152,6 +152,14 @@ export class DynascaleManager {
|
|
|
152
152
|
debounceType: DebounceType,
|
|
153
153
|
dimension: VideoDimension | undefined,
|
|
154
154
|
) => {
|
|
155
|
+
if (dimension && (dimension.width === 0 || dimension.height === 0)) {
|
|
156
|
+
// ignore 0x0 dimensions. this can happen when the video element
|
|
157
|
+
// is not visible (e.g., has display: none).
|
|
158
|
+
// we treat this as "unsubscription" as we don't want to keep
|
|
159
|
+
// consuming bandwidth for a video that is not visible on the screen.
|
|
160
|
+
this.logger('debug', `Ignoring 0x0 dimension`, boundParticipant);
|
|
161
|
+
dimension = undefined;
|
|
162
|
+
}
|
|
155
163
|
this.call.updateSubscriptionsPartial(
|
|
156
164
|
trackType,
|
|
157
165
|
{ [sessionId]: { dimension } },
|
|
@@ -171,6 +179,12 @@ export class DynascaleManager {
|
|
|
171
179
|
shareReplay(1),
|
|
172
180
|
);
|
|
173
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Since the video elements are now being removed from the DOM (React SDK) upon
|
|
184
|
+
* visibility change, this subscription is not in use an stays here only for the
|
|
185
|
+
* plain JS integrations where integrators might choose not to remove the video
|
|
186
|
+
* elements from the DOM.
|
|
187
|
+
*/
|
|
174
188
|
// keep copy for resize observer handler
|
|
175
189
|
let viewportVisibilityState: VisibilityState | undefined;
|
|
176
190
|
const viewportVisibilityStateSubscription =
|
|
@@ -231,6 +245,8 @@ export class DynascaleManager {
|
|
|
231
245
|
});
|
|
232
246
|
resizeObserver?.observe(videoElement);
|
|
233
247
|
|
|
248
|
+
// element renders and gets bound - track subscription gets
|
|
249
|
+
// triggered first other ones get skipped on initial subscriptions
|
|
234
250
|
const publishedTracksSubscription = boundParticipant.isLocalParticipant
|
|
235
251
|
? null
|
|
236
252
|
: participant$
|
|
@@ -248,13 +264,13 @@ export class DynascaleManager {
|
|
|
248
264
|
.subscribe((isPublishing) => {
|
|
249
265
|
if (isPublishing) {
|
|
250
266
|
// the participant just started to publish a track
|
|
251
|
-
requestTrackWithDimensions(DebounceType.
|
|
267
|
+
requestTrackWithDimensions(DebounceType.FAST, {
|
|
252
268
|
width: videoElement.clientWidth,
|
|
253
269
|
height: videoElement.clientHeight,
|
|
254
270
|
});
|
|
255
271
|
} else {
|
|
256
272
|
// the participant just stopped publishing a track
|
|
257
|
-
requestTrackWithDimensions(DebounceType.
|
|
273
|
+
requestTrackWithDimensions(DebounceType.FAST, undefined);
|
|
258
274
|
}
|
|
259
275
|
});
|
|
260
276
|
|
|
@@ -286,7 +302,7 @@ export class DynascaleManager {
|
|
|
286
302
|
videoElement.muted = true;
|
|
287
303
|
|
|
288
304
|
return () => {
|
|
289
|
-
requestTrackWithDimensions(DebounceType.
|
|
305
|
+
requestTrackWithDimensions(DebounceType.FAST, undefined);
|
|
290
306
|
viewportVisibilityStateSubscription?.unsubscribe();
|
|
291
307
|
publishedTracksSubscription?.unsubscribe();
|
|
292
308
|
streamSubscription.unsubscribe();
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import '../../rtc/__tests__/mocks/webrtc.mocks';
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { afterEach, beforeEach, describe, expect, it, Mock, vi } from 'vitest';
|
|
8
8
|
import { DynascaleManager } from '../DynascaleManager';
|
|
9
9
|
import { Call } from '../../Call';
|
|
10
10
|
import { StreamClient } from '../../coordinator/connection/client';
|
|
@@ -195,7 +195,7 @@ describe('DynascaleManager', () => {
|
|
|
195
195
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
196
196
|
'videoTrack',
|
|
197
197
|
{ 'session-id': { dimension: undefined } },
|
|
198
|
-
DebounceType.
|
|
198
|
+
DebounceType.FAST,
|
|
199
199
|
);
|
|
200
200
|
|
|
201
201
|
call.state.updateParticipant('session-id', {
|
|
@@ -212,7 +212,7 @@ describe('DynascaleManager', () => {
|
|
|
212
212
|
},
|
|
213
213
|
},
|
|
214
214
|
},
|
|
215
|
-
DebounceType.
|
|
215
|
+
DebounceType.FAST,
|
|
216
216
|
);
|
|
217
217
|
|
|
218
218
|
call.state.updateParticipant('session-id', {
|
|
@@ -222,7 +222,7 @@ describe('DynascaleManager', () => {
|
|
|
222
222
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
223
223
|
'videoTrack',
|
|
224
224
|
{ 'session-id': { dimension: undefined } },
|
|
225
|
-
DebounceType.
|
|
225
|
+
DebounceType.FAST,
|
|
226
226
|
);
|
|
227
227
|
|
|
228
228
|
cleanup?.();
|
|
@@ -230,7 +230,7 @@ describe('DynascaleManager', () => {
|
|
|
230
230
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
231
231
|
'videoTrack',
|
|
232
232
|
{ 'session-id': { dimension: undefined } },
|
|
233
|
-
DebounceType.
|
|
233
|
+
DebounceType.FAST,
|
|
234
234
|
);
|
|
235
235
|
});
|
|
236
236
|
|
|
@@ -271,7 +271,7 @@ describe('DynascaleManager', () => {
|
|
|
271
271
|
},
|
|
272
272
|
},
|
|
273
273
|
},
|
|
274
|
-
DebounceType.
|
|
274
|
+
DebounceType.FAST,
|
|
275
275
|
);
|
|
276
276
|
expect(play).toHaveBeenCalled();
|
|
277
277
|
expect(videoElement.srcObject).toBe(mediaStream);
|
|
@@ -281,7 +281,7 @@ describe('DynascaleManager', () => {
|
|
|
281
281
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
282
282
|
'videoTrack',
|
|
283
283
|
{ 'session-id': { dimension: undefined } },
|
|
284
|
-
DebounceType.
|
|
284
|
+
DebounceType.FAST,
|
|
285
285
|
);
|
|
286
286
|
});
|
|
287
287
|
|
|
@@ -308,7 +308,7 @@ describe('DynascaleManager', () => {
|
|
|
308
308
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
309
309
|
'videoTrack',
|
|
310
310
|
{ 'session-id': { dimension: undefined } },
|
|
311
|
-
DebounceType.
|
|
311
|
+
DebounceType.FAST,
|
|
312
312
|
);
|
|
313
313
|
|
|
314
314
|
call.state.updateParticipant('session-id', {
|
|
@@ -369,7 +369,7 @@ describe('DynascaleManager', () => {
|
|
|
369
369
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
370
370
|
'videoTrack',
|
|
371
371
|
{ 'session-id': { dimension: undefined } },
|
|
372
|
-
DebounceType.
|
|
372
|
+
DebounceType.FAST,
|
|
373
373
|
);
|
|
374
374
|
});
|
|
375
375
|
|
|
@@ -417,7 +417,7 @@ describe('DynascaleManager', () => {
|
|
|
417
417
|
},
|
|
418
418
|
},
|
|
419
419
|
},
|
|
420
|
-
DebounceType.
|
|
420
|
+
DebounceType.FAST,
|
|
421
421
|
);
|
|
422
422
|
|
|
423
423
|
// @ts-ignore simulate resize
|
|
@@ -439,7 +439,47 @@ describe('DynascaleManager', () => {
|
|
|
439
439
|
expect(updateSubscription).toHaveBeenCalledWith(
|
|
440
440
|
'videoTrack',
|
|
441
441
|
{ 'session-id': { dimension: undefined } },
|
|
442
|
-
DebounceType.
|
|
442
|
+
DebounceType.FAST,
|
|
443
|
+
);
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
it('video: should unsubscribe when element dimensions are zero', () => {
|
|
447
|
+
// @ts-ignore
|
|
448
|
+
call.state.updateOrAddParticipant('session-id', {
|
|
449
|
+
userId: 'user-id',
|
|
450
|
+
sessionId: 'session-id',
|
|
451
|
+
publishedTracks: [TrackType.VIDEO],
|
|
452
|
+
viewportVisibilityState: {
|
|
453
|
+
videoTrack: VisibilityState.VISIBLE,
|
|
454
|
+
screenShareTrack: VisibilityState.UNKNOWN,
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
let updateSubscription = vi.spyOn(call, 'updateSubscriptionsPartial');
|
|
459
|
+
|
|
460
|
+
// @ts-ignore simulate resize
|
|
461
|
+
videoElement.clientHeight = 0;
|
|
462
|
+
// @ts-ignore simulate resize
|
|
463
|
+
videoElement.clientWidth = 0;
|
|
464
|
+
|
|
465
|
+
const cleanup = dynascaleManager.bindVideoElement(
|
|
466
|
+
videoElement,
|
|
467
|
+
'session-id',
|
|
468
|
+
'videoTrack',
|
|
469
|
+
);
|
|
470
|
+
|
|
471
|
+
expect(updateSubscription).toHaveBeenCalledWith(
|
|
472
|
+
'videoTrack',
|
|
473
|
+
{ 'session-id': { dimension: undefined } },
|
|
474
|
+
DebounceType.FAST,
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
cleanup?.();
|
|
478
|
+
|
|
479
|
+
expect(updateSubscription).toHaveBeenLastCalledWith(
|
|
480
|
+
'videoTrack',
|
|
481
|
+
{ 'session-id': { dimension: undefined } },
|
|
482
|
+
DebounceType.FAST,
|
|
443
483
|
);
|
|
444
484
|
});
|
|
445
485
|
});
|