@stream-io/video-client 0.3.9 → 0.3.11
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 +14 -0
- package/dist/index.browser.es.js +476 -154
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +475 -152
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.es.js +476 -154
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +50 -10
- package/dist/src/helpers/DynascaleManager.d.ts +70 -0
- package/dist/src/helpers/__tests__/DynascaleManager.test.d.ts +4 -0
- package/dist/src/types.d.ts +4 -5
- package/dist/version.d.ts +1 -1
- package/index.ts +2 -1
- package/package.json +8 -7
- package/src/Call.ts +134 -24
- package/src/events/__tests__/participant.test.ts +4 -1
- package/src/events/participant.ts +4 -1
- package/src/helpers/DynascaleManager.ts +345 -0
- package/src/helpers/__tests__/DynascaleManager.test.ts +391 -0
- package/src/rtc/codecs.ts +2 -2
- package/src/sorting/__tests__/participant-data.ts +24 -6
- package/src/sorting/presets.ts +2 -2
- package/src/store/__tests__/CallState.test.ts +3 -3
- package/src/store/rxUtils.ts +10 -1
- package/src/types.ts +5 -5
package/dist/index.browser.es.js
CHANGED
|
@@ -4,7 +4,7 @@ import { ServiceType, stackIntercept } from '@protobuf-ts/runtime-rpc';
|
|
|
4
4
|
import axios, { AxiosHeaders } from 'axios';
|
|
5
5
|
export { AxiosError } from 'axios';
|
|
6
6
|
import { TwirpFetchTransport } from '@protobuf-ts/twirp-transport';
|
|
7
|
-
import { ReplaySubject, BehaviorSubject, distinctUntilChanged as distinctUntilChanged$1, Observable, debounceTime, concatMap, from, shareReplay, merge,
|
|
7
|
+
import { ReplaySubject, BehaviorSubject, map as map$2, takeWhile, distinctUntilChanged as distinctUntilChanged$1, distinctUntilKeyChanged, Observable, debounceTime, concatMap, from, shareReplay, merge, combineLatest, filter, pairwise, tap, debounce, timer } from 'rxjs';
|
|
8
8
|
import * as SDP from 'sdp-transform';
|
|
9
9
|
import { UAParser } from 'ua-parser-js';
|
|
10
10
|
import WebSocket from 'isomorphic-ws';
|
|
@@ -5711,7 +5711,7 @@ var VisibilityState;
|
|
|
5711
5711
|
})(VisibilityState || (VisibilityState = {}));
|
|
5712
5712
|
var DebounceType;
|
|
5713
5713
|
(function (DebounceType) {
|
|
5714
|
-
DebounceType[DebounceType["IMMEDIATE"] =
|
|
5714
|
+
DebounceType[DebounceType["IMMEDIATE"] = 20] = "IMMEDIATE";
|
|
5715
5715
|
DebounceType[DebounceType["FAST"] = 100] = "FAST";
|
|
5716
5716
|
DebounceType[DebounceType["MEDIUM"] = 600] = "MEDIUM";
|
|
5717
5717
|
DebounceType[DebounceType["SLOW"] = 1200] = "SLOW";
|
|
@@ -6100,10 +6100,10 @@ const getPreferredCodecs = (kind, preferredCodec, codecToRemove) => {
|
|
|
6100
6100
|
cap.codecs.forEach((c) => {
|
|
6101
6101
|
const codec = c.mimeType.toLowerCase();
|
|
6102
6102
|
logger === null || logger === void 0 ? void 0 : logger('debug', `Found supported codec: ${codec}`);
|
|
6103
|
-
const shouldRemoveCodec = codecToRemove && codec === `${kind}/${codecToRemove}`;
|
|
6103
|
+
const shouldRemoveCodec = codecToRemove && codec === `${kind}/${codecToRemove.toLowerCase()}`;
|
|
6104
6104
|
if (shouldRemoveCodec)
|
|
6105
6105
|
return;
|
|
6106
|
-
const matchesCodec = codec === `${kind}/${preferredCodec}`;
|
|
6106
|
+
const matchesCodec = codec === `${kind}/${preferredCodec.toLowerCase()}`;
|
|
6107
6107
|
if (!matchesCodec) {
|
|
6108
6108
|
unmatched.push(c);
|
|
6109
6109
|
return;
|
|
@@ -7586,10 +7586,20 @@ const retryable = (rpc, logger) => __awaiter(void 0, void 0, void 0, function* (
|
|
|
7586
7586
|
*/
|
|
7587
7587
|
const getCurrentValue = (observable$) => {
|
|
7588
7588
|
let value;
|
|
7589
|
+
let err = undefined;
|
|
7589
7590
|
observable$
|
|
7590
7591
|
.pipe(take(1))
|
|
7591
|
-
.subscribe(
|
|
7592
|
+
.subscribe({
|
|
7593
|
+
next: (v) => {
|
|
7594
|
+
value = v;
|
|
7595
|
+
},
|
|
7596
|
+
error: (e) => {
|
|
7597
|
+
err = e;
|
|
7598
|
+
},
|
|
7599
|
+
})
|
|
7592
7600
|
.unsubscribe();
|
|
7601
|
+
if (err)
|
|
7602
|
+
throw err;
|
|
7593
7603
|
return value;
|
|
7594
7604
|
};
|
|
7595
7605
|
/**
|
|
@@ -7948,8 +7958,11 @@ const hasAudio = (p) => p.publishedTracks.includes(TrackType.AUDIO);
|
|
|
7948
7958
|
// a comparator decorator which applies the decorated comparator only if the
|
|
7949
7959
|
// participant is invisible.
|
|
7950
7960
|
// This ensures stable sorting when all participants are visible.
|
|
7951
|
-
const ifInvisibleBy = conditional((a, b) =>
|
|
7952
|
-
|
|
7961
|
+
const ifInvisibleBy = conditional((a, b) => {
|
|
7962
|
+
var _a, _b;
|
|
7963
|
+
return ((_a = a.viewportVisibilityState) === null || _a === void 0 ? void 0 : _a.videoTrack) === VisibilityState.INVISIBLE ||
|
|
7964
|
+
((_b = b.viewportVisibilityState) === null || _b === void 0 ? void 0 : _b.videoTrack) === VisibilityState.INVISIBLE;
|
|
7965
|
+
});
|
|
7953
7966
|
/**
|
|
7954
7967
|
* The default sorting preset.
|
|
7955
7968
|
*/
|
|
@@ -8826,7 +8839,10 @@ const watchParticipantJoined = (state) => {
|
|
|
8826
8839
|
// response and then follow up with a `participantJoined` event for
|
|
8827
8840
|
// already announced participants.
|
|
8828
8841
|
state.updateOrAddParticipant(participant.sessionId, Object.assign(participant, {
|
|
8829
|
-
viewportVisibilityState:
|
|
8842
|
+
viewportVisibilityState: {
|
|
8843
|
+
videoTrack: VisibilityState.UNKNOWN,
|
|
8844
|
+
screenShareTrack: VisibilityState.UNKNOWN,
|
|
8845
|
+
},
|
|
8830
8846
|
}));
|
|
8831
8847
|
};
|
|
8832
8848
|
};
|
|
@@ -9383,6 +9399,234 @@ class ViewportTracker {
|
|
|
9383
9399
|
}
|
|
9384
9400
|
}
|
|
9385
9401
|
|
|
9402
|
+
const DEFAULT_VIEWPORT_VISIBILITY_STATE = {
|
|
9403
|
+
videoTrack: VisibilityState.UNKNOWN,
|
|
9404
|
+
screenShareTrack: VisibilityState.UNKNOWN,
|
|
9405
|
+
};
|
|
9406
|
+
/**
|
|
9407
|
+
* A manager class that handles dynascale related tasks like:
|
|
9408
|
+
*
|
|
9409
|
+
* - binding video elements to session ids
|
|
9410
|
+
* - binding audio elements to session ids
|
|
9411
|
+
* - tracking element visibility
|
|
9412
|
+
* - updating subscriptions based on viewport visibility
|
|
9413
|
+
* - updating subscriptions based on video element dimensions
|
|
9414
|
+
* - updating subscriptions based on published tracks
|
|
9415
|
+
*/
|
|
9416
|
+
class DynascaleManager {
|
|
9417
|
+
/**
|
|
9418
|
+
* Creates a new DynascaleManager instance.
|
|
9419
|
+
*
|
|
9420
|
+
* @param call the call to manage.
|
|
9421
|
+
*/
|
|
9422
|
+
constructor(call) {
|
|
9423
|
+
/**
|
|
9424
|
+
* The viewport tracker instance.
|
|
9425
|
+
*/
|
|
9426
|
+
this.viewportTracker = new ViewportTracker();
|
|
9427
|
+
this.logger = getLogger(['DynascaleManager']);
|
|
9428
|
+
/**
|
|
9429
|
+
* Will begin tracking the given element for visibility changes within the
|
|
9430
|
+
* configured viewport element (`call.setViewport`).
|
|
9431
|
+
*
|
|
9432
|
+
* @param element the element to track.
|
|
9433
|
+
* @param sessionId the session id.
|
|
9434
|
+
* @param trackType the kind of video.
|
|
9435
|
+
* @returns Untrack.
|
|
9436
|
+
*/
|
|
9437
|
+
this.trackElementVisibility = (element, sessionId, trackType) => {
|
|
9438
|
+
const cleanup = this.viewportTracker.observe(element, (entry) => {
|
|
9439
|
+
this.call.state.updateParticipant(sessionId, (participant) => {
|
|
9440
|
+
var _a;
|
|
9441
|
+
const previousVisibilityState = (_a = participant.viewportVisibilityState) !== null && _a !== void 0 ? _a : DEFAULT_VIEWPORT_VISIBILITY_STATE;
|
|
9442
|
+
// observer triggers when the element is "moved" to be a fullscreen element
|
|
9443
|
+
// keep it VISIBLE if that happens to prevent fullscreen with placeholder
|
|
9444
|
+
const isVisible = entry.isIntersecting || document.fullscreenElement === element
|
|
9445
|
+
? VisibilityState.VISIBLE
|
|
9446
|
+
: VisibilityState.INVISIBLE;
|
|
9447
|
+
return Object.assign(Object.assign({}, participant), { viewportVisibilityState: Object.assign(Object.assign({}, previousVisibilityState), { [trackType]: isVisible }) });
|
|
9448
|
+
});
|
|
9449
|
+
});
|
|
9450
|
+
return () => {
|
|
9451
|
+
cleanup();
|
|
9452
|
+
// reset visibility state to UNKNOWN upon cleanup
|
|
9453
|
+
// so that the layouts that are not actively observed
|
|
9454
|
+
// can still function normally (runtime layout switching)
|
|
9455
|
+
this.call.state.updateParticipant(sessionId, (participant) => {
|
|
9456
|
+
var _a;
|
|
9457
|
+
const previousVisibilityState = (_a = participant.viewportVisibilityState) !== null && _a !== void 0 ? _a : DEFAULT_VIEWPORT_VISIBILITY_STATE;
|
|
9458
|
+
return Object.assign(Object.assign({}, participant), { viewportVisibilityState: Object.assign(Object.assign({}, previousVisibilityState), { [trackType]: VisibilityState.UNKNOWN }) });
|
|
9459
|
+
});
|
|
9460
|
+
};
|
|
9461
|
+
};
|
|
9462
|
+
/**
|
|
9463
|
+
* Sets the viewport element to track bound video elements for visibility.
|
|
9464
|
+
*
|
|
9465
|
+
* @param element the viewport element.
|
|
9466
|
+
*/
|
|
9467
|
+
this.setViewport = (element) => {
|
|
9468
|
+
return this.viewportTracker.setViewport(element);
|
|
9469
|
+
};
|
|
9470
|
+
/**
|
|
9471
|
+
* Binds a DOM <video> element to the given session id.
|
|
9472
|
+
* This method will make sure that the video element will play
|
|
9473
|
+
* the correct video stream for the given session id.
|
|
9474
|
+
*
|
|
9475
|
+
* Under the hood, it would also keep track of the video element dimensions
|
|
9476
|
+
* and update the subscription accordingly in order to optimize the bandwidth.
|
|
9477
|
+
*
|
|
9478
|
+
* If a "viewport" is configured, the video element will be automatically
|
|
9479
|
+
* tracked for visibility and the subscription will be updated accordingly.
|
|
9480
|
+
*
|
|
9481
|
+
* @param videoElement the video element to bind to.
|
|
9482
|
+
* @param sessionId the session id.
|
|
9483
|
+
* @param trackType the kind of video.
|
|
9484
|
+
*/
|
|
9485
|
+
this.bindVideoElement = (videoElement, sessionId, trackType) => {
|
|
9486
|
+
const boundParticipant = this.call.state.findParticipantBySessionId(sessionId);
|
|
9487
|
+
if (!boundParticipant)
|
|
9488
|
+
return;
|
|
9489
|
+
const requestTrackWithDimensions = (debounceType, dimension) => {
|
|
9490
|
+
this.call.updateSubscriptionsPartial(trackType, { [sessionId]: { dimension } }, debounceType);
|
|
9491
|
+
};
|
|
9492
|
+
const participant$ = this.call.state.participants$.pipe(map$2((participants) => participants.find((participant) => participant.sessionId === sessionId)), takeWhile((participant) => !!participant), distinctUntilChanged$1());
|
|
9493
|
+
// keep copy for resize observer handler
|
|
9494
|
+
let viewportVisibilityState;
|
|
9495
|
+
const viewportVisibilityStateSubscription = boundParticipant.isLocalParticipant
|
|
9496
|
+
? null
|
|
9497
|
+
: participant$
|
|
9498
|
+
.pipe(map$2((p) => { var _a; return (_a = p.viewportVisibilityState) === null || _a === void 0 ? void 0 : _a[trackType]; }), distinctUntilChanged$1())
|
|
9499
|
+
.subscribe((nextViewportVisibilityState) => {
|
|
9500
|
+
// skip initial trigger
|
|
9501
|
+
if (!viewportVisibilityState) {
|
|
9502
|
+
viewportVisibilityState =
|
|
9503
|
+
nextViewportVisibilityState !== null && nextViewportVisibilityState !== void 0 ? nextViewportVisibilityState : VisibilityState.UNKNOWN;
|
|
9504
|
+
return;
|
|
9505
|
+
}
|
|
9506
|
+
viewportVisibilityState =
|
|
9507
|
+
nextViewportVisibilityState !== null && nextViewportVisibilityState !== void 0 ? nextViewportVisibilityState : VisibilityState.UNKNOWN;
|
|
9508
|
+
if (nextViewportVisibilityState === VisibilityState.INVISIBLE) {
|
|
9509
|
+
return requestTrackWithDimensions(DebounceType.MEDIUM, undefined);
|
|
9510
|
+
}
|
|
9511
|
+
requestTrackWithDimensions(DebounceType.MEDIUM, {
|
|
9512
|
+
width: videoElement.clientWidth,
|
|
9513
|
+
height: videoElement.clientHeight,
|
|
9514
|
+
});
|
|
9515
|
+
});
|
|
9516
|
+
let lastDimensions;
|
|
9517
|
+
const resizeObserver = boundParticipant.isLocalParticipant
|
|
9518
|
+
? null
|
|
9519
|
+
: new ResizeObserver(() => {
|
|
9520
|
+
const currentDimensions = `${videoElement.clientWidth},${videoElement.clientHeight}`;
|
|
9521
|
+
// skip initial trigger
|
|
9522
|
+
if (!lastDimensions) {
|
|
9523
|
+
lastDimensions = currentDimensions;
|
|
9524
|
+
return;
|
|
9525
|
+
}
|
|
9526
|
+
if (lastDimensions === currentDimensions ||
|
|
9527
|
+
viewportVisibilityState === VisibilityState.INVISIBLE) {
|
|
9528
|
+
return;
|
|
9529
|
+
}
|
|
9530
|
+
requestTrackWithDimensions(DebounceType.SLOW, {
|
|
9531
|
+
width: videoElement.clientWidth,
|
|
9532
|
+
height: videoElement.clientHeight,
|
|
9533
|
+
});
|
|
9534
|
+
lastDimensions = currentDimensions;
|
|
9535
|
+
});
|
|
9536
|
+
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.observe(videoElement);
|
|
9537
|
+
const publishedTracksSubscription = boundParticipant.isLocalParticipant
|
|
9538
|
+
? null
|
|
9539
|
+
: participant$
|
|
9540
|
+
.pipe(distinctUntilKeyChanged('publishedTracks'), map$2((p) => p.publishedTracks.includes(trackType === 'videoTrack'
|
|
9541
|
+
? TrackType.VIDEO
|
|
9542
|
+
: TrackType.SCREEN_SHARE)), distinctUntilChanged$1())
|
|
9543
|
+
.subscribe((isPublishing) => {
|
|
9544
|
+
if (isPublishing) {
|
|
9545
|
+
// the participant just started to publish a track
|
|
9546
|
+
requestTrackWithDimensions(DebounceType.IMMEDIATE, {
|
|
9547
|
+
width: videoElement.clientWidth,
|
|
9548
|
+
height: videoElement.clientHeight,
|
|
9549
|
+
});
|
|
9550
|
+
}
|
|
9551
|
+
else {
|
|
9552
|
+
// the participant just stopped publishing a track
|
|
9553
|
+
requestTrackWithDimensions(DebounceType.IMMEDIATE, undefined);
|
|
9554
|
+
}
|
|
9555
|
+
});
|
|
9556
|
+
const streamSubscription = participant$
|
|
9557
|
+
.pipe(distinctUntilKeyChanged(trackType === 'videoTrack' ? 'videoStream' : 'screenShareStream'))
|
|
9558
|
+
.subscribe((p) => {
|
|
9559
|
+
const source = trackType === 'videoTrack' ? p.videoStream : p.screenShareStream;
|
|
9560
|
+
if (videoElement.srcObject === source)
|
|
9561
|
+
return;
|
|
9562
|
+
setTimeout(() => {
|
|
9563
|
+
videoElement.srcObject = source !== null && source !== void 0 ? source : null;
|
|
9564
|
+
if (videoElement.srcObject) {
|
|
9565
|
+
videoElement.play().catch((e) => {
|
|
9566
|
+
this.logger('warn', `Failed to play stream`, e);
|
|
9567
|
+
});
|
|
9568
|
+
}
|
|
9569
|
+
}, 0);
|
|
9570
|
+
});
|
|
9571
|
+
videoElement.playsInline = true;
|
|
9572
|
+
videoElement.autoplay = true;
|
|
9573
|
+
// explicitly marking the element as muted will allow autoplay to work
|
|
9574
|
+
// without prior user interaction:
|
|
9575
|
+
// https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide
|
|
9576
|
+
videoElement.muted = true;
|
|
9577
|
+
return () => {
|
|
9578
|
+
viewportVisibilityStateSubscription === null || viewportVisibilityStateSubscription === void 0 ? void 0 : viewportVisibilityStateSubscription.unsubscribe();
|
|
9579
|
+
publishedTracksSubscription === null || publishedTracksSubscription === void 0 ? void 0 : publishedTracksSubscription.unsubscribe();
|
|
9580
|
+
streamSubscription.unsubscribe();
|
|
9581
|
+
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
|
|
9582
|
+
};
|
|
9583
|
+
};
|
|
9584
|
+
/**
|
|
9585
|
+
* Binds a DOM <audio> element to the given session id.
|
|
9586
|
+
*
|
|
9587
|
+
* This method will make sure that the audio element will
|
|
9588
|
+
* play the correct audio stream for the given session id.
|
|
9589
|
+
*
|
|
9590
|
+
* @param audioElement the audio element to bind to.
|
|
9591
|
+
* @param sessionId the session id.
|
|
9592
|
+
* @returns a cleanup function that will unbind the audio element.
|
|
9593
|
+
*/
|
|
9594
|
+
this.bindAudioElement = (audioElement, sessionId) => {
|
|
9595
|
+
const participant = this.call.state.findParticipantBySessionId(sessionId);
|
|
9596
|
+
if (!participant || participant.isLocalParticipant)
|
|
9597
|
+
return;
|
|
9598
|
+
const participant$ = this.call.state.participants$.pipe(map$2((participants) => participants.find((p) => p.sessionId === sessionId)), takeWhile((p) => !!p), distinctUntilChanged$1());
|
|
9599
|
+
const updateMediaStreamSubscription = participant$
|
|
9600
|
+
.pipe(distinctUntilKeyChanged('audioStream'))
|
|
9601
|
+
.subscribe((p) => {
|
|
9602
|
+
const source = p.audioStream;
|
|
9603
|
+
if (audioElement.srcObject === source)
|
|
9604
|
+
return;
|
|
9605
|
+
setTimeout(() => {
|
|
9606
|
+
audioElement.srcObject = source !== null && source !== void 0 ? source : null;
|
|
9607
|
+
if (audioElement.srcObject) {
|
|
9608
|
+
audioElement.play().catch((e) => {
|
|
9609
|
+
this.logger('warn', `Failed to play stream`, e);
|
|
9610
|
+
});
|
|
9611
|
+
}
|
|
9612
|
+
});
|
|
9613
|
+
});
|
|
9614
|
+
const sinkIdSubscription = this.call.state.localParticipant$.subscribe((p) => {
|
|
9615
|
+
if (p && p.audioOutputDeviceId && 'setSinkId' in audioElement) {
|
|
9616
|
+
// @ts-expect-error setSinkId is not yet in the lib
|
|
9617
|
+
audioElement.setSinkId(p.audioOutputDeviceId);
|
|
9618
|
+
}
|
|
9619
|
+
});
|
|
9620
|
+
audioElement.autoplay = true;
|
|
9621
|
+
return () => {
|
|
9622
|
+
sinkIdSubscription.unsubscribe();
|
|
9623
|
+
updateMediaStreamSubscription.unsubscribe();
|
|
9624
|
+
};
|
|
9625
|
+
};
|
|
9626
|
+
this.call = call;
|
|
9627
|
+
}
|
|
9628
|
+
}
|
|
9629
|
+
|
|
9386
9630
|
/**
|
|
9387
9631
|
* Stores the permissions for the current user and exposes
|
|
9388
9632
|
* a few helper methods which make it easier to work with permissions.
|
|
@@ -9522,127 +9766,6 @@ const CallTypes = new CallTypesRegistry([
|
|
|
9522
9766
|
}),
|
|
9523
9767
|
]);
|
|
9524
9768
|
|
|
9525
|
-
class InputMediaDeviceManagerState {
|
|
9526
|
-
constructor(disableMode = 'stop-tracks') {
|
|
9527
|
-
this.disableMode = disableMode;
|
|
9528
|
-
this.statusSubject = new BehaviorSubject(undefined);
|
|
9529
|
-
this.mediaStreamSubject = new BehaviorSubject(undefined);
|
|
9530
|
-
this.selectedDeviceSubject = new BehaviorSubject(undefined);
|
|
9531
|
-
/**
|
|
9532
|
-
* Gets the current value of an observable, or undefined if the observable has
|
|
9533
|
-
* not emitted a value yet.
|
|
9534
|
-
*
|
|
9535
|
-
* @param observable$ the observable to get the value from.
|
|
9536
|
-
*/
|
|
9537
|
-
this.getCurrentValue = getCurrentValue;
|
|
9538
|
-
/**
|
|
9539
|
-
* Updates the value of the provided Subject.
|
|
9540
|
-
* An `update` can either be a new value or a function which takes
|
|
9541
|
-
* the current value and returns a new value.
|
|
9542
|
-
*
|
|
9543
|
-
* @internal
|
|
9544
|
-
*
|
|
9545
|
-
* @param subject the subject to update.
|
|
9546
|
-
* @param update the update to apply to the subject.
|
|
9547
|
-
* @return the updated value.
|
|
9548
|
-
*/
|
|
9549
|
-
this.setCurrentValue = setCurrentValue;
|
|
9550
|
-
this.mediaStream$ = this.mediaStreamSubject.asObservable();
|
|
9551
|
-
this.selectedDevice$ = this.selectedDeviceSubject
|
|
9552
|
-
.asObservable()
|
|
9553
|
-
.pipe(distinctUntilChanged$1());
|
|
9554
|
-
this.status$ = this.statusSubject
|
|
9555
|
-
.asObservable()
|
|
9556
|
-
.pipe(distinctUntilChanged$1());
|
|
9557
|
-
}
|
|
9558
|
-
/**
|
|
9559
|
-
* The device status
|
|
9560
|
-
*/
|
|
9561
|
-
get status() {
|
|
9562
|
-
return this.getCurrentValue(this.status$);
|
|
9563
|
-
}
|
|
9564
|
-
/**
|
|
9565
|
-
* The currently selected device
|
|
9566
|
-
*/
|
|
9567
|
-
get selectedDevice() {
|
|
9568
|
-
return this.getCurrentValue(this.selectedDevice$);
|
|
9569
|
-
}
|
|
9570
|
-
/**
|
|
9571
|
-
* The current media stream, or `undefined` if the device is currently disabled.
|
|
9572
|
-
*/
|
|
9573
|
-
get mediaStream() {
|
|
9574
|
-
return this.getCurrentValue(this.mediaStream$);
|
|
9575
|
-
}
|
|
9576
|
-
/**
|
|
9577
|
-
* @internal
|
|
9578
|
-
* @param status
|
|
9579
|
-
*/
|
|
9580
|
-
setStatus(status) {
|
|
9581
|
-
this.setCurrentValue(this.statusSubject, status);
|
|
9582
|
-
}
|
|
9583
|
-
/**
|
|
9584
|
-
* @internal
|
|
9585
|
-
* @param stream
|
|
9586
|
-
*/
|
|
9587
|
-
setMediaStream(stream) {
|
|
9588
|
-
this.setCurrentValue(this.mediaStreamSubject, stream);
|
|
9589
|
-
if (stream) {
|
|
9590
|
-
this.setDevice(this.getDeviceIdFromStream(stream));
|
|
9591
|
-
}
|
|
9592
|
-
}
|
|
9593
|
-
/**
|
|
9594
|
-
* @internal
|
|
9595
|
-
* @param stream
|
|
9596
|
-
*/
|
|
9597
|
-
setDevice(deviceId) {
|
|
9598
|
-
this.setCurrentValue(this.selectedDeviceSubject, deviceId);
|
|
9599
|
-
}
|
|
9600
|
-
}
|
|
9601
|
-
|
|
9602
|
-
class CameraManagerState extends InputMediaDeviceManagerState {
|
|
9603
|
-
constructor() {
|
|
9604
|
-
super('stop-tracks');
|
|
9605
|
-
this.directionSubject = new BehaviorSubject(undefined);
|
|
9606
|
-
this.direction$ = this.directionSubject
|
|
9607
|
-
.asObservable()
|
|
9608
|
-
.pipe(distinctUntilChanged$1());
|
|
9609
|
-
}
|
|
9610
|
-
/**
|
|
9611
|
-
* The preferred camera direction
|
|
9612
|
-
* front - means the camera facing the user
|
|
9613
|
-
* back - means the camera facing the environment
|
|
9614
|
-
*/
|
|
9615
|
-
get direction() {
|
|
9616
|
-
return this.getCurrentValue(this.direction$);
|
|
9617
|
-
}
|
|
9618
|
-
/**
|
|
9619
|
-
* @internal
|
|
9620
|
-
*/
|
|
9621
|
-
setDirection(direction) {
|
|
9622
|
-
this.setCurrentValue(this.directionSubject, direction);
|
|
9623
|
-
}
|
|
9624
|
-
/**
|
|
9625
|
-
* @internal
|
|
9626
|
-
*/
|
|
9627
|
-
setMediaStream(stream) {
|
|
9628
|
-
var _a;
|
|
9629
|
-
super.setMediaStream(stream);
|
|
9630
|
-
if (stream) {
|
|
9631
|
-
// RN getSettings() doesn't return facingMode, so we don't verify camera direction
|
|
9632
|
-
const direction = isReactNative()
|
|
9633
|
-
? this.direction
|
|
9634
|
-
: ((_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().facingMode) === 'environment'
|
|
9635
|
-
? 'back'
|
|
9636
|
-
: 'front';
|
|
9637
|
-
this.setDirection(direction);
|
|
9638
|
-
}
|
|
9639
|
-
}
|
|
9640
|
-
getDeviceIdFromStream(stream) {
|
|
9641
|
-
var _a;
|
|
9642
|
-
return (_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
|
|
9643
|
-
}
|
|
9644
|
-
}
|
|
9645
|
-
|
|
9646
9769
|
const getDevices = (constraints) => {
|
|
9647
9770
|
return new Observable((subscriber) => {
|
|
9648
9771
|
navigator.mediaDevices
|
|
@@ -10038,6 +10161,127 @@ class InputMediaDeviceManager {
|
|
|
10038
10161
|
}
|
|
10039
10162
|
}
|
|
10040
10163
|
|
|
10164
|
+
class InputMediaDeviceManagerState {
|
|
10165
|
+
constructor(disableMode = 'stop-tracks') {
|
|
10166
|
+
this.disableMode = disableMode;
|
|
10167
|
+
this.statusSubject = new BehaviorSubject(undefined);
|
|
10168
|
+
this.mediaStreamSubject = new BehaviorSubject(undefined);
|
|
10169
|
+
this.selectedDeviceSubject = new BehaviorSubject(undefined);
|
|
10170
|
+
/**
|
|
10171
|
+
* Gets the current value of an observable, or undefined if the observable has
|
|
10172
|
+
* not emitted a value yet.
|
|
10173
|
+
*
|
|
10174
|
+
* @param observable$ the observable to get the value from.
|
|
10175
|
+
*/
|
|
10176
|
+
this.getCurrentValue = getCurrentValue;
|
|
10177
|
+
/**
|
|
10178
|
+
* Updates the value of the provided Subject.
|
|
10179
|
+
* An `update` can either be a new value or a function which takes
|
|
10180
|
+
* the current value and returns a new value.
|
|
10181
|
+
*
|
|
10182
|
+
* @internal
|
|
10183
|
+
*
|
|
10184
|
+
* @param subject the subject to update.
|
|
10185
|
+
* @param update the update to apply to the subject.
|
|
10186
|
+
* @return the updated value.
|
|
10187
|
+
*/
|
|
10188
|
+
this.setCurrentValue = setCurrentValue;
|
|
10189
|
+
this.mediaStream$ = this.mediaStreamSubject.asObservable();
|
|
10190
|
+
this.selectedDevice$ = this.selectedDeviceSubject
|
|
10191
|
+
.asObservable()
|
|
10192
|
+
.pipe(distinctUntilChanged$1());
|
|
10193
|
+
this.status$ = this.statusSubject
|
|
10194
|
+
.asObservable()
|
|
10195
|
+
.pipe(distinctUntilChanged$1());
|
|
10196
|
+
}
|
|
10197
|
+
/**
|
|
10198
|
+
* The device status
|
|
10199
|
+
*/
|
|
10200
|
+
get status() {
|
|
10201
|
+
return this.getCurrentValue(this.status$);
|
|
10202
|
+
}
|
|
10203
|
+
/**
|
|
10204
|
+
* The currently selected device
|
|
10205
|
+
*/
|
|
10206
|
+
get selectedDevice() {
|
|
10207
|
+
return this.getCurrentValue(this.selectedDevice$);
|
|
10208
|
+
}
|
|
10209
|
+
/**
|
|
10210
|
+
* The current media stream, or `undefined` if the device is currently disabled.
|
|
10211
|
+
*/
|
|
10212
|
+
get mediaStream() {
|
|
10213
|
+
return this.getCurrentValue(this.mediaStream$);
|
|
10214
|
+
}
|
|
10215
|
+
/**
|
|
10216
|
+
* @internal
|
|
10217
|
+
* @param status
|
|
10218
|
+
*/
|
|
10219
|
+
setStatus(status) {
|
|
10220
|
+
this.setCurrentValue(this.statusSubject, status);
|
|
10221
|
+
}
|
|
10222
|
+
/**
|
|
10223
|
+
* @internal
|
|
10224
|
+
* @param stream
|
|
10225
|
+
*/
|
|
10226
|
+
setMediaStream(stream) {
|
|
10227
|
+
this.setCurrentValue(this.mediaStreamSubject, stream);
|
|
10228
|
+
if (stream) {
|
|
10229
|
+
this.setDevice(this.getDeviceIdFromStream(stream));
|
|
10230
|
+
}
|
|
10231
|
+
}
|
|
10232
|
+
/**
|
|
10233
|
+
* @internal
|
|
10234
|
+
* @param stream
|
|
10235
|
+
*/
|
|
10236
|
+
setDevice(deviceId) {
|
|
10237
|
+
this.setCurrentValue(this.selectedDeviceSubject, deviceId);
|
|
10238
|
+
}
|
|
10239
|
+
}
|
|
10240
|
+
|
|
10241
|
+
class CameraManagerState extends InputMediaDeviceManagerState {
|
|
10242
|
+
constructor() {
|
|
10243
|
+
super('stop-tracks');
|
|
10244
|
+
this.directionSubject = new BehaviorSubject(undefined);
|
|
10245
|
+
this.direction$ = this.directionSubject
|
|
10246
|
+
.asObservable()
|
|
10247
|
+
.pipe(distinctUntilChanged$1());
|
|
10248
|
+
}
|
|
10249
|
+
/**
|
|
10250
|
+
* The preferred camera direction
|
|
10251
|
+
* front - means the camera facing the user
|
|
10252
|
+
* back - means the camera facing the environment
|
|
10253
|
+
*/
|
|
10254
|
+
get direction() {
|
|
10255
|
+
return this.getCurrentValue(this.direction$);
|
|
10256
|
+
}
|
|
10257
|
+
/**
|
|
10258
|
+
* @internal
|
|
10259
|
+
*/
|
|
10260
|
+
setDirection(direction) {
|
|
10261
|
+
this.setCurrentValue(this.directionSubject, direction);
|
|
10262
|
+
}
|
|
10263
|
+
/**
|
|
10264
|
+
* @internal
|
|
10265
|
+
*/
|
|
10266
|
+
setMediaStream(stream) {
|
|
10267
|
+
var _a;
|
|
10268
|
+
super.setMediaStream(stream);
|
|
10269
|
+
if (stream) {
|
|
10270
|
+
// RN getSettings() doesn't return facingMode, so we don't verify camera direction
|
|
10271
|
+
const direction = isReactNative()
|
|
10272
|
+
? this.direction
|
|
10273
|
+
: ((_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().facingMode) === 'environment'
|
|
10274
|
+
? 'back'
|
|
10275
|
+
: 'front';
|
|
10276
|
+
this.setDirection(direction);
|
|
10277
|
+
}
|
|
10278
|
+
}
|
|
10279
|
+
getDeviceIdFromStream(stream) {
|
|
10280
|
+
var _a;
|
|
10281
|
+
return (_a = stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
|
|
10282
|
+
}
|
|
10283
|
+
}
|
|
10284
|
+
|
|
10041
10285
|
class CameraManager extends InputMediaDeviceManager {
|
|
10042
10286
|
constructor(call) {
|
|
10043
10287
|
super(call, new CameraManagerState());
|
|
@@ -10173,14 +10417,14 @@ class Call {
|
|
|
10173
10417
|
* method to construct a `Call` instance.
|
|
10174
10418
|
*/
|
|
10175
10419
|
constructor({ type, id, streamClient, members, ownCapabilities, sortParticipantsBy, clientStore, ringing = false, watching = false, }) {
|
|
10176
|
-
/**
|
|
10177
|
-
* ViewportTracker instance
|
|
10178
|
-
*/
|
|
10179
|
-
this.viewportTracker = new ViewportTracker();
|
|
10180
10420
|
/**
|
|
10181
10421
|
* The state of this call.
|
|
10182
10422
|
*/
|
|
10183
10423
|
this.state = new CallState();
|
|
10424
|
+
/**
|
|
10425
|
+
* The DynascaleManager instance.
|
|
10426
|
+
*/
|
|
10427
|
+
this.dynascaleManager = new DynascaleManager(this);
|
|
10184
10428
|
/**
|
|
10185
10429
|
* The permissions context of this call.
|
|
10186
10430
|
*/
|
|
@@ -10198,7 +10442,7 @@ class Call {
|
|
|
10198
10442
|
* A typical use case is to clean up some global event handlers.
|
|
10199
10443
|
* @private
|
|
10200
10444
|
*/
|
|
10201
|
-
this.leaveCallHooks =
|
|
10445
|
+
this.leaveCallHooks = new Set();
|
|
10202
10446
|
this.streamClientEventHandlers = new Map();
|
|
10203
10447
|
/**
|
|
10204
10448
|
* Leave the call and stop the media streams that were published by the call.
|
|
@@ -10504,7 +10748,7 @@ class Call {
|
|
|
10504
10748
|
unsubscribeOfflineEvent();
|
|
10505
10749
|
this.state.setCallingState(CallingState.OFFLINE);
|
|
10506
10750
|
});
|
|
10507
|
-
this.leaveCallHooks.
|
|
10751
|
+
this.leaveCallHooks.add(() => {
|
|
10508
10752
|
unsubscribeOnlineEvent();
|
|
10509
10753
|
unsubscribeOfflineEvent();
|
|
10510
10754
|
});
|
|
@@ -10581,7 +10825,10 @@ class Call {
|
|
|
10581
10825
|
return currentParticipants.map((p) => {
|
|
10582
10826
|
const participant = Object.assign(p, {
|
|
10583
10827
|
isLocalParticipant: p.sessionId === sfuClient.sessionId,
|
|
10584
|
-
viewportVisibilityState:
|
|
10828
|
+
viewportVisibilityState: {
|
|
10829
|
+
videoTrack: VisibilityState.UNKNOWN,
|
|
10830
|
+
screenShareTrack: VisibilityState.UNKNOWN,
|
|
10831
|
+
},
|
|
10585
10832
|
});
|
|
10586
10833
|
// We need to preserve the local state of the participant
|
|
10587
10834
|
// (e.g. videoDimension, visibilityState, pinnedAt, etc.)
|
|
@@ -10738,11 +10985,19 @@ class Call {
|
|
|
10738
10985
|
* You have to create a subscription for each participant for all the different kinds of tracks you want to receive.
|
|
10739
10986
|
* You can only subscribe for tracks after the participant started publishing the given kind of track.
|
|
10740
10987
|
*
|
|
10741
|
-
* @param
|
|
10988
|
+
* @param trackType the kind of subscription to update.
|
|
10742
10989
|
* @param changes the list of subscription changes to do.
|
|
10743
10990
|
* @param type the debounce type to use for the update.
|
|
10744
10991
|
*/
|
|
10745
|
-
this.updateSubscriptionsPartial = (
|
|
10992
|
+
this.updateSubscriptionsPartial = (trackType, changes, type = DebounceType.SLOW) => {
|
|
10993
|
+
if (trackType === 'video') {
|
|
10994
|
+
this.logger('warn', `updateSubscriptionsPartial: ${trackType} is deprecated. Please switch to 'videoTrack'`);
|
|
10995
|
+
trackType = 'videoTrack';
|
|
10996
|
+
}
|
|
10997
|
+
else if (trackType === 'screen') {
|
|
10998
|
+
this.logger('warn', `updateSubscriptionsPartial: ${trackType} is deprecated. Please switch to 'screenShareTrack'`);
|
|
10999
|
+
trackType = 'screenShareTrack';
|
|
11000
|
+
}
|
|
10746
11001
|
const participants = this.state.updateParticipants(Object.entries(changes).reduce((acc, [sessionId, change]) => {
|
|
10747
11002
|
var _a, _b;
|
|
10748
11003
|
if ((_a = change.dimension) === null || _a === void 0 ? void 0 : _a.height) {
|
|
@@ -10751,9 +11006,9 @@ class Call {
|
|
|
10751
11006
|
if ((_b = change.dimension) === null || _b === void 0 ? void 0 : _b.width) {
|
|
10752
11007
|
change.dimension.width = Math.ceil(change.dimension.width);
|
|
10753
11008
|
}
|
|
10754
|
-
const prop =
|
|
11009
|
+
const prop = trackType === 'videoTrack'
|
|
10755
11010
|
? 'videoDimension'
|
|
10756
|
-
:
|
|
11011
|
+
: trackType === 'screenShareTrack'
|
|
10757
11012
|
? 'screenShareDimension'
|
|
10758
11013
|
: undefined;
|
|
10759
11014
|
if (prop) {
|
|
@@ -10769,10 +11024,10 @@ class Call {
|
|
|
10769
11024
|
};
|
|
10770
11025
|
this.updateSubscriptions = (participants, type = DebounceType.SLOW) => {
|
|
10771
11026
|
const subscriptions = [];
|
|
10772
|
-
|
|
11027
|
+
for (const p of participants) {
|
|
10773
11028
|
// we don't want to subscribe to our own tracks
|
|
10774
11029
|
if (p.isLocalParticipant)
|
|
10775
|
-
|
|
11030
|
+
continue;
|
|
10776
11031
|
// NOTE: audio tracks don't have to be requested explicitly
|
|
10777
11032
|
// as the SFU will implicitly subscribe us to all of them,
|
|
10778
11033
|
// once they become available.
|
|
@@ -10793,7 +11048,7 @@ class Call {
|
|
|
10793
11048
|
dimension: p.screenShareDimension,
|
|
10794
11049
|
});
|
|
10795
11050
|
}
|
|
10796
|
-
}
|
|
11051
|
+
}
|
|
10797
11052
|
// schedule update
|
|
10798
11053
|
this.trackSubscriptionsSubject.next({ type, data: subscriptions });
|
|
10799
11054
|
};
|
|
@@ -11182,7 +11437,7 @@ class Call {
|
|
|
11182
11437
|
this.dropTimeout = setTimeout(() => this.leave(), timeoutMs);
|
|
11183
11438
|
}), takeWhile(() => !!this.clientStore.calls.find((call) => call.cid === this.cid)))
|
|
11184
11439
|
.subscribe();
|
|
11185
|
-
this.leaveCallHooks.
|
|
11440
|
+
this.leaveCallHooks.add(() => {
|
|
11186
11441
|
!subscription.closed && subscription.unsubscribe();
|
|
11187
11442
|
});
|
|
11188
11443
|
};
|
|
@@ -11209,6 +11464,69 @@ class Call {
|
|
|
11209
11464
|
this.sendCustomEvent = (payload) => __awaiter(this, void 0, void 0, function* () {
|
|
11210
11465
|
return this.streamClient.post(`${this.streamClientBasePath}/event`, { custom: payload });
|
|
11211
11466
|
});
|
|
11467
|
+
/**
|
|
11468
|
+
* Will begin tracking the given element for visibility changes within the
|
|
11469
|
+
* configured viewport element (`call.setViewport`).
|
|
11470
|
+
*
|
|
11471
|
+
* @param element the element to track.
|
|
11472
|
+
* @param sessionId the session id.
|
|
11473
|
+
* @param trackType the video mode.
|
|
11474
|
+
*/
|
|
11475
|
+
this.trackElementVisibility = (element, sessionId, trackType) => {
|
|
11476
|
+
return this.dynascaleManager.trackElementVisibility(element, sessionId, trackType);
|
|
11477
|
+
};
|
|
11478
|
+
/**
|
|
11479
|
+
* Sets the viewport element to track bound video elements for visibility.
|
|
11480
|
+
*
|
|
11481
|
+
* @param element the viewport element.
|
|
11482
|
+
*/
|
|
11483
|
+
this.setViewport = (element) => {
|
|
11484
|
+
return this.dynascaleManager.setViewport(element);
|
|
11485
|
+
};
|
|
11486
|
+
/**
|
|
11487
|
+
* Binds a DOM <video> element to the given session id.
|
|
11488
|
+
* This method will make sure that the video element will play
|
|
11489
|
+
* the correct video stream for the given session id.
|
|
11490
|
+
*
|
|
11491
|
+
* Under the hood, it would also keep track of the video element dimensions
|
|
11492
|
+
* and update the subscription accordingly in order to optimize the bandwidth.
|
|
11493
|
+
*
|
|
11494
|
+
* If a "viewport" is configured, the video element will be automatically
|
|
11495
|
+
* tracked for visibility and the subscription will be updated accordingly.
|
|
11496
|
+
*
|
|
11497
|
+
* @param videoElement the video element to bind to.
|
|
11498
|
+
* @param sessionId the session id.
|
|
11499
|
+
* @param trackType the kind of video.
|
|
11500
|
+
*/
|
|
11501
|
+
this.bindVideoElement = (videoElement, sessionId, trackType) => {
|
|
11502
|
+
const unbind = this.dynascaleManager.bindVideoElement(videoElement, sessionId, trackType);
|
|
11503
|
+
if (!unbind)
|
|
11504
|
+
return;
|
|
11505
|
+
this.leaveCallHooks.add(unbind);
|
|
11506
|
+
return () => {
|
|
11507
|
+
this.leaveCallHooks.delete(unbind);
|
|
11508
|
+
unbind();
|
|
11509
|
+
};
|
|
11510
|
+
};
|
|
11511
|
+
/**
|
|
11512
|
+
* Binds a DOM <audio> element to the given session id.
|
|
11513
|
+
*
|
|
11514
|
+
* This method will make sure that the audio element will
|
|
11515
|
+
* play the correct audio stream for the given session id.
|
|
11516
|
+
*
|
|
11517
|
+
* @param audioElement the audio element to bind to.
|
|
11518
|
+
* @param sessionId the session id.
|
|
11519
|
+
*/
|
|
11520
|
+
this.bindAudioElement = (audioElement, sessionId) => {
|
|
11521
|
+
const unbind = this.dynascaleManager.bindAudioElement(audioElement, sessionId);
|
|
11522
|
+
if (!unbind)
|
|
11523
|
+
return;
|
|
11524
|
+
this.leaveCallHooks.add(unbind);
|
|
11525
|
+
return () => {
|
|
11526
|
+
this.leaveCallHooks.delete(unbind);
|
|
11527
|
+
unbind();
|
|
11528
|
+
};
|
|
11529
|
+
};
|
|
11212
11530
|
this.type = type;
|
|
11213
11531
|
this.id = id;
|
|
11214
11532
|
this.cid = `${type}:${id}`;
|
|
@@ -11230,20 +11548,21 @@ class Call {
|
|
|
11230
11548
|
// update state with the latest event data
|
|
11231
11549
|
this.state.updateFromEvent(event);
|
|
11232
11550
|
});
|
|
11233
|
-
this.leaveCallHooks.
|
|
11551
|
+
this.leaveCallHooks.add(registerEventHandlers(this, this.state, this.dispatcher));
|
|
11234
11552
|
this.registerEffects();
|
|
11235
|
-
this.leaveCallHooks.
|
|
11553
|
+
this.leaveCallHooks.add(createSubscription(this.trackSubscriptionsSubject.pipe(debounce((v) => timer(v.type)), map$2((v) => v.data)), (subscriptions) => { var _a; return (_a = this.sfuClient) === null || _a === void 0 ? void 0 : _a.updateSubscriptions(subscriptions); }));
|
|
11236
11554
|
this.camera = new CameraManager(this);
|
|
11237
11555
|
this.microphone = new MicrophoneManager(this);
|
|
11238
11556
|
}
|
|
11239
11557
|
registerEffects() {
|
|
11240
|
-
this.leaveCallHooks.
|
|
11558
|
+
this.leaveCallHooks.add(
|
|
11241
11559
|
// handles updating the permissions context when the settings change.
|
|
11242
11560
|
createSubscription(this.state.settings$, (settings) => {
|
|
11243
11561
|
if (!settings)
|
|
11244
11562
|
return;
|
|
11245
11563
|
this.permissionsContext.setCallSettings(settings);
|
|
11246
|
-
})
|
|
11564
|
+
}));
|
|
11565
|
+
this.leaveCallHooks.add(
|
|
11247
11566
|
// handle the case when the user permissions are modified.
|
|
11248
11567
|
createSubscription(this.state.ownCapabilities$, (ownCapabilities) => {
|
|
11249
11568
|
// update the permission context.
|
|
@@ -11264,7 +11583,8 @@ class Call {
|
|
|
11264
11583
|
});
|
|
11265
11584
|
}
|
|
11266
11585
|
}
|
|
11267
|
-
})
|
|
11586
|
+
}));
|
|
11587
|
+
this.leaveCallHooks.add(
|
|
11268
11588
|
// handles the case when the user is blocked by the call owner.
|
|
11269
11589
|
createSubscription(this.state.blockedUserIds$, (blockedUserIds) => __awaiter(this, void 0, void 0, function* () {
|
|
11270
11590
|
if (!blockedUserIds)
|
|
@@ -11274,7 +11594,8 @@ class Call {
|
|
|
11274
11594
|
this.logger('info', 'Leaving call because of being blocked');
|
|
11275
11595
|
yield this.leave();
|
|
11276
11596
|
}
|
|
11277
|
-
}))
|
|
11597
|
+
})));
|
|
11598
|
+
this.leaveCallHooks.add(
|
|
11278
11599
|
// watch for auto drop cancellation
|
|
11279
11600
|
createSubscription(this.state.callingState$, (callingState) => {
|
|
11280
11601
|
if (!this.ringing)
|
|
@@ -11285,7 +11606,8 @@ class Call {
|
|
|
11285
11606
|
clearTimeout(this.dropTimeout);
|
|
11286
11607
|
this.dropTimeout = undefined;
|
|
11287
11608
|
}
|
|
11288
|
-
})
|
|
11609
|
+
}));
|
|
11610
|
+
this.leaveCallHooks.add(
|
|
11289
11611
|
// "ringing" mode effects and event handlers
|
|
11290
11612
|
createSubscription(this.ringingSubject, (isRinging) => {
|
|
11291
11613
|
if (!isRinging)
|
|
@@ -11294,7 +11616,7 @@ class Call {
|
|
|
11294
11616
|
if (this.state.callingState === CallingState.IDLE) {
|
|
11295
11617
|
this.state.setCallingState(CallingState.RINGING);
|
|
11296
11618
|
}
|
|
11297
|
-
this.leaveCallHooks.
|
|
11619
|
+
this.leaveCallHooks.add(registerRingingCallEventHandlers(this));
|
|
11298
11620
|
}));
|
|
11299
11621
|
}
|
|
11300
11622
|
on(eventName, fn) {
|
|
@@ -12520,7 +12842,7 @@ class WSConnectionFallback {
|
|
|
12520
12842
|
}
|
|
12521
12843
|
}
|
|
12522
12844
|
|
|
12523
|
-
const version = '0.3.
|
|
12845
|
+
const version = '0.3.11';
|
|
12524
12846
|
|
|
12525
12847
|
const logger = getLogger(['location']);
|
|
12526
12848
|
const HINT_URL = `https://hint.stream-io-video.com/`;
|
|
@@ -13580,5 +13902,5 @@ var browsers = /*#__PURE__*/Object.freeze({
|
|
|
13580
13902
|
isSafari: isSafari
|
|
13581
13903
|
});
|
|
13582
13904
|
|
|
13583
|
-
export { AudioSettingsDefaultDeviceEnum, AudioSettingsRequestDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, ErrorFromResponse, InputMediaDeviceManager, InputMediaDeviceManagerState, MicrophoneManager, MicrophoneManagerState, OwnCapability, RecordSettingsModeEnum, RecordSettingsQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, events as SfuEvents, models as SfuModels, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoServerClient, StreamVideoWriteableStateStore, TranscriptionSettingsModeEnum, TranscriptionSettingsRequestModeEnum, VideoSettingsCameraFacingEnum, VideoSettingsRequestCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, disposeOfMediaStream, dominantSpeaker, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceInfo, getLogger, getOSInfo, getScreenShareStream, getSdkInfo, getVideoDevices, getVideoStream, isStreamVideoLocalParticipant, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, pinned, publishingAudio, publishingVideo, reactionType, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setSdkInfo, speakerLayoutSortPreset, speaking, watchForAddedDefaultAudioDevice, watchForAddedDefaultAudioOutputDevice, watchForAddedDefaultVideoDevice, watchForDisconnectedAudioDevice, watchForDisconnectedAudioOutputDevice, watchForDisconnectedVideoDevice };
|
|
13905
|
+
export { AudioSettingsDefaultDeviceEnum, AudioSettingsRequestDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DynascaleManager, ErrorFromResponse, InputMediaDeviceManager, InputMediaDeviceManagerState, MicrophoneManager, MicrophoneManagerState, OwnCapability, RecordSettingsModeEnum, RecordSettingsQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, events as SfuEvents, models as SfuModels, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoServerClient, StreamVideoWriteableStateStore, TranscriptionSettingsModeEnum, TranscriptionSettingsRequestModeEnum, VideoSettingsCameraFacingEnum, VideoSettingsRequestCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, disposeOfMediaStream, dominantSpeaker, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceInfo, getLogger, getOSInfo, getScreenShareStream, getSdkInfo, getVideoDevices, getVideoStream, isStreamVideoLocalParticipant, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, pinned, publishingAudio, publishingVideo, reactionType, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setSdkInfo, speakerLayoutSortPreset, speaking, watchForAddedDefaultAudioDevice, watchForAddedDefaultAudioOutputDevice, watchForAddedDefaultVideoDevice, watchForDisconnectedAudioDevice, watchForDisconnectedAudioOutputDevice, watchForDisconnectedVideoDevice };
|
|
13584
13906
|
//# sourceMappingURL=index.browser.es.js.map
|