@stream-io/video-client 1.44.3 → 1.44.5
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 +134 -45
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +134 -45
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +134 -45
- package/dist/index.es.js.map +1 -1
- package/dist/src/devices/BrowserPermission.d.ts +2 -0
- package/dist/src/devices/CameraManagerState.d.ts +2 -1
- package/dist/src/devices/MicrophoneManagerState.d.ts +2 -1
- package/dist/src/devices/devices.d.ts +2 -2
- package/dist/src/helpers/AudioBindingsWatchdog.d.ts +37 -0
- package/dist/src/helpers/DynascaleManager.d.ts +3 -1
- package/package.json +2 -2
- package/src/devices/BrowserPermission.ts +5 -0
- package/src/devices/CameraManager.ts +6 -1
- package/src/devices/CameraManagerState.ts +3 -2
- package/src/devices/MicrophoneManager.ts +1 -2
- package/src/devices/MicrophoneManagerState.ts +3 -2
- package/src/devices/devices.ts +26 -34
- package/src/helpers/AudioBindingsWatchdog.ts +118 -0
- package/src/helpers/DynascaleManager.ts +22 -24
- package/src/helpers/__tests__/AudioBindingsWatchdog.test.ts +325 -0
- package/src/helpers/__tests__/DynascaleManager.test.ts +64 -0
package/dist/index.cjs.js
CHANGED
|
@@ -6303,7 +6303,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6303
6303
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6304
6304
|
};
|
|
6305
6305
|
|
|
6306
|
-
const version = "1.44.
|
|
6306
|
+
const version = "1.44.5";
|
|
6307
6307
|
const [major, minor, patch] = version.split('.');
|
|
6308
6308
|
let sdkInfo = {
|
|
6309
6309
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -9511,6 +9511,96 @@ class ViewportTracker {
|
|
|
9511
9511
|
}
|
|
9512
9512
|
}
|
|
9513
9513
|
|
|
9514
|
+
const toBindingKey = (sessionId, trackType = 'audioTrack') => `${sessionId}/${trackType}`;
|
|
9515
|
+
/**
|
|
9516
|
+
* Tracks audio element bindings and periodically warns about
|
|
9517
|
+
* remote participants whose audio streams have no bound element.
|
|
9518
|
+
*/
|
|
9519
|
+
class AudioBindingsWatchdog {
|
|
9520
|
+
constructor(state, tracer) {
|
|
9521
|
+
this.state = state;
|
|
9522
|
+
this.tracer = tracer;
|
|
9523
|
+
this.bindings = new Map();
|
|
9524
|
+
this.enabled = true;
|
|
9525
|
+
this.logger = videoLoggerSystem.getLogger('AudioBindingsWatchdog');
|
|
9526
|
+
/**
|
|
9527
|
+
* Registers an audio element binding for the given session and track type.
|
|
9528
|
+
* Warns if a different element is already bound to the same key.
|
|
9529
|
+
*/
|
|
9530
|
+
this.register = (audioElement, sessionId, trackType) => {
|
|
9531
|
+
const key = toBindingKey(sessionId, trackType);
|
|
9532
|
+
const existing = this.bindings.get(key);
|
|
9533
|
+
if (existing && existing !== audioElement) {
|
|
9534
|
+
this.logger.warn(`Audio element already bound to ${sessionId} and ${trackType}`);
|
|
9535
|
+
this.tracer.trace('audioBinding.alreadyBoundWarning', trackType);
|
|
9536
|
+
}
|
|
9537
|
+
this.bindings.set(key, audioElement);
|
|
9538
|
+
};
|
|
9539
|
+
/**
|
|
9540
|
+
* Removes the audio element binding for the given session and track type.
|
|
9541
|
+
*/
|
|
9542
|
+
this.unregister = (sessionId, trackType) => {
|
|
9543
|
+
this.bindings.delete(toBindingKey(sessionId, trackType));
|
|
9544
|
+
};
|
|
9545
|
+
/**
|
|
9546
|
+
* Enables or disables the watchdog.
|
|
9547
|
+
* When disabled, the periodic check stops but bindings are still tracked.
|
|
9548
|
+
*/
|
|
9549
|
+
this.setEnabled = (enabled) => {
|
|
9550
|
+
this.enabled = enabled;
|
|
9551
|
+
if (enabled) {
|
|
9552
|
+
this.start();
|
|
9553
|
+
}
|
|
9554
|
+
else {
|
|
9555
|
+
this.stop();
|
|
9556
|
+
}
|
|
9557
|
+
};
|
|
9558
|
+
/**
|
|
9559
|
+
* Stops the watchdog and unsubscribes from callingState changes.
|
|
9560
|
+
*/
|
|
9561
|
+
this.dispose = () => {
|
|
9562
|
+
this.stop();
|
|
9563
|
+
this.unsubscribeCallingState();
|
|
9564
|
+
};
|
|
9565
|
+
this.start = () => {
|
|
9566
|
+
clearInterval(this.watchdogInterval);
|
|
9567
|
+
this.watchdogInterval = setInterval(() => {
|
|
9568
|
+
const danglingUserIds = [];
|
|
9569
|
+
for (const p of this.state.participants) {
|
|
9570
|
+
if (p.isLocalParticipant)
|
|
9571
|
+
continue;
|
|
9572
|
+
const { audioStream, screenShareAudioStream, sessionId, userId } = p;
|
|
9573
|
+
if (audioStream && !this.bindings.has(toBindingKey(sessionId))) {
|
|
9574
|
+
danglingUserIds.push(userId);
|
|
9575
|
+
}
|
|
9576
|
+
if (screenShareAudioStream &&
|
|
9577
|
+
!this.bindings.has(toBindingKey(sessionId, 'screenShareAudioTrack'))) {
|
|
9578
|
+
danglingUserIds.push(userId);
|
|
9579
|
+
}
|
|
9580
|
+
}
|
|
9581
|
+
if (danglingUserIds.length > 0) {
|
|
9582
|
+
const key = 'audioBinding.danglingWarning';
|
|
9583
|
+
this.tracer.traceOnce(key, key, danglingUserIds);
|
|
9584
|
+
this.logger.warn(`Dangling audio bindings detected. Did you forget to bind the audio element? user_ids: ${danglingUserIds}.`);
|
|
9585
|
+
}
|
|
9586
|
+
}, 3000);
|
|
9587
|
+
};
|
|
9588
|
+
this.stop = () => {
|
|
9589
|
+
clearInterval(this.watchdogInterval);
|
|
9590
|
+
};
|
|
9591
|
+
this.unsubscribeCallingState = createSubscription(state.callingState$, (callingState) => {
|
|
9592
|
+
if (!this.enabled)
|
|
9593
|
+
return;
|
|
9594
|
+
if (callingState !== exports.CallingState.JOINED) {
|
|
9595
|
+
this.stop();
|
|
9596
|
+
}
|
|
9597
|
+
else {
|
|
9598
|
+
this.start();
|
|
9599
|
+
}
|
|
9600
|
+
});
|
|
9601
|
+
}
|
|
9602
|
+
}
|
|
9603
|
+
|
|
9514
9604
|
const DEFAULT_VIEWPORT_VISIBILITY_STATE = {
|
|
9515
9605
|
videoTrack: exports.VisibilityState.UNKNOWN,
|
|
9516
9606
|
screenShareTrack: exports.VisibilityState.UNKNOWN,
|
|
@@ -9536,7 +9626,7 @@ class DynascaleManager {
|
|
|
9536
9626
|
*/
|
|
9537
9627
|
this.viewportTracker = new ViewportTracker();
|
|
9538
9628
|
this.logger = videoLoggerSystem.getLogger('DynascaleManager');
|
|
9539
|
-
this.useWebAudio =
|
|
9629
|
+
this.useWebAudio = false;
|
|
9540
9630
|
this.pendingSubscriptionsUpdate = null;
|
|
9541
9631
|
this.videoTrackSubscriptionOverridesSubject = new rxjs.BehaviorSubject({});
|
|
9542
9632
|
this.videoTrackSubscriptionOverrides$ = this.videoTrackSubscriptionOverridesSubject.asObservable();
|
|
@@ -9568,7 +9658,8 @@ class DynascaleManager {
|
|
|
9568
9658
|
if (this.pendingSubscriptionsUpdate) {
|
|
9569
9659
|
clearTimeout(this.pendingSubscriptionsUpdate);
|
|
9570
9660
|
}
|
|
9571
|
-
|
|
9661
|
+
this.audioBindingsWatchdog?.dispose();
|
|
9662
|
+
const context = this.audioContext;
|
|
9572
9663
|
if (context && context.state !== 'closed') {
|
|
9573
9664
|
document.removeEventListener('click', this.resumeAudioContext);
|
|
9574
9665
|
await context.close();
|
|
@@ -9767,12 +9858,13 @@ class DynascaleManager {
|
|
|
9767
9858
|
lastDimensions = currentDimensions;
|
|
9768
9859
|
});
|
|
9769
9860
|
resizeObserver?.observe(videoElement);
|
|
9861
|
+
const isVideoTrack = trackType === 'videoTrack';
|
|
9770
9862
|
// element renders and gets bound - track subscription gets
|
|
9771
9863
|
// triggered first other ones get skipped on initial subscriptions
|
|
9772
9864
|
const publishedTracksSubscription = boundParticipant.isLocalParticipant
|
|
9773
9865
|
? null
|
|
9774
9866
|
: participant$
|
|
9775
|
-
.pipe(rxjs.distinctUntilKeyChanged('publishedTracks'), rxjs.map((p) =>
|
|
9867
|
+
.pipe(rxjs.distinctUntilKeyChanged('publishedTracks'), rxjs.map((p) => (isVideoTrack ? hasVideo(p) : hasScreenShare(p))), rxjs.distinctUntilChanged())
|
|
9776
9868
|
.subscribe((isPublishing) => {
|
|
9777
9869
|
if (isPublishing) {
|
|
9778
9870
|
// the participant just started to publish a track
|
|
@@ -9792,10 +9884,11 @@ class DynascaleManager {
|
|
|
9792
9884
|
// without prior user interaction:
|
|
9793
9885
|
// https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide
|
|
9794
9886
|
videoElement.muted = true;
|
|
9887
|
+
const trackKey = isVideoTrack ? 'videoStream' : 'screenShareStream';
|
|
9795
9888
|
const streamSubscription = participant$
|
|
9796
|
-
.pipe(rxjs.distinctUntilKeyChanged(
|
|
9889
|
+
.pipe(rxjs.distinctUntilKeyChanged(trackKey))
|
|
9797
9890
|
.subscribe((p) => {
|
|
9798
|
-
const source =
|
|
9891
|
+
const source = isVideoTrack ? p.videoStream : p.screenShareStream;
|
|
9799
9892
|
if (videoElement.srcObject === source)
|
|
9800
9893
|
return;
|
|
9801
9894
|
videoElement.srcObject = source ?? null;
|
|
@@ -9834,6 +9927,7 @@ class DynascaleManager {
|
|
|
9834
9927
|
const participant = this.callState.findParticipantBySessionId(sessionId);
|
|
9835
9928
|
if (!participant || participant.isLocalParticipant)
|
|
9836
9929
|
return;
|
|
9930
|
+
this.audioBindingsWatchdog?.register(audioElement, sessionId, trackType);
|
|
9837
9931
|
const participant$ = this.callState.participants$.pipe(rxjs.map((ps) => ps.find((p) => p.sessionId === sessionId)), rxjs.takeWhile((p) => !!p), rxjs.distinctUntilChanged(), rxjs.shareReplay({ bufferSize: 1, refCount: true }));
|
|
9838
9932
|
const updateSinkId = (deviceId, audioContext) => {
|
|
9839
9933
|
if (!deviceId)
|
|
@@ -9852,14 +9946,12 @@ class DynascaleManager {
|
|
|
9852
9946
|
};
|
|
9853
9947
|
let sourceNode = undefined;
|
|
9854
9948
|
let gainNode = undefined;
|
|
9949
|
+
const isAudioTrack = trackType === 'audioTrack';
|
|
9950
|
+
const trackKey = isAudioTrack ? 'audioStream' : 'screenShareAudioStream';
|
|
9855
9951
|
const updateMediaStreamSubscription = participant$
|
|
9856
|
-
.pipe(rxjs.distinctUntilKeyChanged(
|
|
9857
|
-
? 'screenShareAudioStream'
|
|
9858
|
-
: 'audioStream'))
|
|
9952
|
+
.pipe(rxjs.distinctUntilKeyChanged(trackKey))
|
|
9859
9953
|
.subscribe((p) => {
|
|
9860
|
-
const source =
|
|
9861
|
-
? p.screenShareAudioStream
|
|
9862
|
-
: p.audioStream;
|
|
9954
|
+
const source = isAudioTrack ? p.audioStream : p.screenShareAudioStream;
|
|
9863
9955
|
if (audioElement.srcObject === source)
|
|
9864
9956
|
return;
|
|
9865
9957
|
setTimeout(() => {
|
|
@@ -9914,6 +10006,7 @@ class DynascaleManager {
|
|
|
9914
10006
|
});
|
|
9915
10007
|
audioElement.autoplay = true;
|
|
9916
10008
|
return () => {
|
|
10009
|
+
this.audioBindingsWatchdog?.unregister(sessionId, trackType);
|
|
9917
10010
|
sinkIdSubscription?.unsubscribe();
|
|
9918
10011
|
volumeSubscription.unsubscribe();
|
|
9919
10012
|
updateMediaStreamSubscription.unsubscribe();
|
|
@@ -9974,6 +10067,9 @@ class DynascaleManager {
|
|
|
9974
10067
|
this.callState = callState;
|
|
9975
10068
|
this.speaker = speaker;
|
|
9976
10069
|
this.tracer = tracer;
|
|
10070
|
+
if (!isReactNative()) {
|
|
10071
|
+
this.audioBindingsWatchdog = new AudioBindingsWatchdog(callState, tracer);
|
|
10072
|
+
}
|
|
9977
10073
|
}
|
|
9978
10074
|
setSfuClient(sfuClient) {
|
|
9979
10075
|
this.sfuClient = sfuClient;
|
|
@@ -10318,6 +10414,9 @@ class BrowserPermission {
|
|
|
10318
10414
|
}
|
|
10319
10415
|
setState(state) {
|
|
10320
10416
|
if (this.state !== state) {
|
|
10417
|
+
const { tracer, queryName } = this.permission;
|
|
10418
|
+
const traceKey = `navigator.mediaDevices.${queryName}.permission`;
|
|
10419
|
+
tracer?.trace(traceKey, { previous: this.state, state });
|
|
10321
10420
|
this.state = state;
|
|
10322
10421
|
this.listeners.forEach((listener) => listener(state));
|
|
10323
10422
|
}
|
|
@@ -10359,9 +10458,6 @@ const getDevices = (permission, kind, tracer) => {
|
|
|
10359
10458
|
const checkIfAudioOutputChangeSupported = () => {
|
|
10360
10459
|
if (typeof document === 'undefined')
|
|
10361
10460
|
return false;
|
|
10362
|
-
// Safari uses WebAudio API for playing audio, so we check the AudioContext prototype
|
|
10363
|
-
if (isSafari())
|
|
10364
|
-
return 'setSinkId' in AudioContext.prototype;
|
|
10365
10461
|
const element = document.createElement('audio');
|
|
10366
10462
|
return 'setSinkId' in element;
|
|
10367
10463
|
};
|
|
@@ -10388,17 +10484,19 @@ const videoDeviceConstraints = {
|
|
|
10388
10484
|
* Keeps track of the browser permission to use microphone. This permission also
|
|
10389
10485
|
* affects an ability to enumerate audio devices.
|
|
10390
10486
|
*/
|
|
10391
|
-
const getAudioBrowserPermission = lazy(() => new BrowserPermission({
|
|
10487
|
+
const getAudioBrowserPermission = lazy((tracer) => new BrowserPermission({
|
|
10392
10488
|
constraints: audioDeviceConstraints,
|
|
10393
10489
|
queryName: 'microphone',
|
|
10490
|
+
tracer,
|
|
10394
10491
|
}));
|
|
10395
10492
|
/**
|
|
10396
10493
|
* Keeps track of the browser permission to use camera. This permission also
|
|
10397
10494
|
* affects an ability to enumerate video devices.
|
|
10398
10495
|
*/
|
|
10399
|
-
const getVideoBrowserPermission = lazy(() => new BrowserPermission({
|
|
10496
|
+
const getVideoBrowserPermission = lazy((tracer) => new BrowserPermission({
|
|
10400
10497
|
constraints: videoDeviceConstraints,
|
|
10401
10498
|
queryName: 'camera',
|
|
10499
|
+
tracer,
|
|
10402
10500
|
}));
|
|
10403
10501
|
const getDeviceChangeObserver = lazy((tracer) => {
|
|
10404
10502
|
// 'addEventListener' is not available in React Native, returning
|
|
@@ -10414,7 +10512,7 @@ const getDeviceChangeObserver = lazy((tracer) => {
|
|
|
10414
10512
|
* the observable errors.
|
|
10415
10513
|
*/
|
|
10416
10514
|
const getAudioDevices = lazy((tracer) => {
|
|
10417
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(), 'audioinput', tracer)), rxjs.shareReplay(1));
|
|
10515
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audioinput', tracer)), rxjs.shareReplay(1));
|
|
10418
10516
|
});
|
|
10419
10517
|
/**
|
|
10420
10518
|
* Prompts the user for a permission to use video devices (if not already granted
|
|
@@ -10423,7 +10521,7 @@ const getAudioDevices = lazy((tracer) => {
|
|
|
10423
10521
|
* the observable errors.
|
|
10424
10522
|
*/
|
|
10425
10523
|
const getVideoDevices = lazy((tracer) => {
|
|
10426
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getVideoBrowserPermission(), 'videoinput', tracer)), rxjs.shareReplay(1));
|
|
10524
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getVideoBrowserPermission(tracer), 'videoinput', tracer)), rxjs.shareReplay(1));
|
|
10427
10525
|
});
|
|
10428
10526
|
/**
|
|
10429
10527
|
* Prompts the user for a permission to use video devices (if not already granted
|
|
@@ -10432,7 +10530,7 @@ const getVideoDevices = lazy((tracer) => {
|
|
|
10432
10530
|
* the observable errors.
|
|
10433
10531
|
*/
|
|
10434
10532
|
const getAudioOutputDevices = lazy((tracer) => {
|
|
10435
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(), 'audiooutput', tracer)), rxjs.shareReplay(1));
|
|
10533
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audiooutput', tracer)), rxjs.shareReplay(1));
|
|
10436
10534
|
});
|
|
10437
10535
|
let getUserMediaExecId = 0;
|
|
10438
10536
|
const getStream = async (constraints, tracer) => {
|
|
@@ -10498,25 +10596,21 @@ const getAudioStream = async (trackConstraints, tracer) => {
|
|
|
10498
10596
|
},
|
|
10499
10597
|
};
|
|
10500
10598
|
try {
|
|
10501
|
-
await getAudioBrowserPermission().prompt({
|
|
10599
|
+
await getAudioBrowserPermission(tracer).prompt({
|
|
10502
10600
|
throwOnNotAllowed: true,
|
|
10503
10601
|
forcePrompt: true,
|
|
10504
10602
|
});
|
|
10505
10603
|
return await getStream(constraints, tracer);
|
|
10506
10604
|
}
|
|
10507
10605
|
catch (error) {
|
|
10606
|
+
const logger = videoLoggerSystem.getLogger('devices');
|
|
10508
10607
|
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
10509
10608
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10510
10609
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
10511
|
-
|
|
10512
|
-
.getLogger('devices')
|
|
10513
|
-
.warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10610
|
+
logger.warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10514
10611
|
return getAudioStream(relaxedConstraints, tracer);
|
|
10515
10612
|
}
|
|
10516
|
-
|
|
10517
|
-
error,
|
|
10518
|
-
constraints,
|
|
10519
|
-
});
|
|
10613
|
+
logger.error('Failed to get audio stream', { error, constraints });
|
|
10520
10614
|
throw error;
|
|
10521
10615
|
}
|
|
10522
10616
|
};
|
|
@@ -10536,25 +10630,21 @@ const getVideoStream = async (trackConstraints, tracer) => {
|
|
|
10536
10630
|
},
|
|
10537
10631
|
};
|
|
10538
10632
|
try {
|
|
10539
|
-
await getVideoBrowserPermission().prompt({
|
|
10633
|
+
await getVideoBrowserPermission(tracer).prompt({
|
|
10540
10634
|
throwOnNotAllowed: true,
|
|
10541
10635
|
forcePrompt: true,
|
|
10542
10636
|
});
|
|
10543
10637
|
return await getStream(constraints, tracer);
|
|
10544
10638
|
}
|
|
10545
10639
|
catch (error) {
|
|
10640
|
+
const logger = videoLoggerSystem.getLogger('devices');
|
|
10546
10641
|
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
10547
10642
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10548
10643
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
10549
|
-
|
|
10550
|
-
|
|
10551
|
-
.warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10552
|
-
return getVideoStream(relaxedConstraints);
|
|
10644
|
+
logger.warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10645
|
+
return getVideoStream(relaxedConstraints, tracer);
|
|
10553
10646
|
}
|
|
10554
|
-
|
|
10555
|
-
error,
|
|
10556
|
-
constraints,
|
|
10557
|
-
});
|
|
10647
|
+
logger.error('Failed to get video stream', { error, constraints });
|
|
10558
10648
|
throw error;
|
|
10559
10649
|
}
|
|
10560
10650
|
};
|
|
@@ -11325,8 +11415,8 @@ class DeviceManagerState {
|
|
|
11325
11415
|
}
|
|
11326
11416
|
|
|
11327
11417
|
class CameraManagerState extends DeviceManagerState {
|
|
11328
|
-
constructor() {
|
|
11329
|
-
super('stop-tracks', getVideoBrowserPermission());
|
|
11418
|
+
constructor(tracer) {
|
|
11419
|
+
super('stop-tracks', getVideoBrowserPermission(tracer));
|
|
11330
11420
|
this.directionSubject = new rxjs.BehaviorSubject(undefined);
|
|
11331
11421
|
/**
|
|
11332
11422
|
* Observable that emits the preferred camera direction
|
|
@@ -11380,7 +11470,7 @@ class CameraManager extends DeviceManager {
|
|
|
11380
11470
|
* @param devicePersistence the device persistence preferences to use.
|
|
11381
11471
|
*/
|
|
11382
11472
|
constructor(call, devicePersistence) {
|
|
11383
|
-
super(call, new CameraManagerState(), TrackType.VIDEO, devicePersistence);
|
|
11473
|
+
super(call, new CameraManagerState(call.tracer), TrackType.VIDEO, devicePersistence);
|
|
11384
11474
|
this.targetResolution = {
|
|
11385
11475
|
width: 1280,
|
|
11386
11476
|
height: 720,
|
|
@@ -11591,8 +11681,8 @@ class AudioDeviceManagerState extends DeviceManagerState {
|
|
|
11591
11681
|
}
|
|
11592
11682
|
|
|
11593
11683
|
class MicrophoneManagerState extends AudioDeviceManagerState {
|
|
11594
|
-
constructor(disableMode) {
|
|
11595
|
-
super(disableMode, getAudioBrowserPermission(), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
|
|
11684
|
+
constructor(disableMode, tracer) {
|
|
11685
|
+
super(disableMode, getAudioBrowserPermission(tracer), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
|
|
11596
11686
|
this.speakingWhileMutedSubject = new rxjs.BehaviorSubject(false);
|
|
11597
11687
|
/**
|
|
11598
11688
|
* An Observable that emits `true` if the user's microphone is muted, but they're speaking.
|
|
@@ -11932,7 +12022,7 @@ class RNSpeechDetector {
|
|
|
11932
12022
|
|
|
11933
12023
|
class MicrophoneManager extends AudioDeviceManager {
|
|
11934
12024
|
constructor(call, devicePersistence, disableMode = 'stop-tracks') {
|
|
11935
|
-
super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO, devicePersistence);
|
|
12025
|
+
super(call, new MicrophoneManagerState(disableMode, call.tracer), TrackType.AUDIO, devicePersistence);
|
|
11936
12026
|
this.speakingWhileMutedNotificationEnabled = true;
|
|
11937
12027
|
this.soundDetectorConcurrencyTag = Symbol('soundDetectorConcurrencyTag');
|
|
11938
12028
|
this.silenceThresholdMs = 5000;
|
|
@@ -12034,7 +12124,6 @@ class MicrophoneManager extends AudioDeviceManager {
|
|
|
12034
12124
|
deviceId,
|
|
12035
12125
|
label,
|
|
12036
12126
|
};
|
|
12037
|
-
console.log(event);
|
|
12038
12127
|
this.call.tracer.trace('mic.capture_report', event);
|
|
12039
12128
|
this.call.streamClient.dispatchEvent(event);
|
|
12040
12129
|
},
|
|
@@ -15908,7 +15997,7 @@ class StreamClient {
|
|
|
15908
15997
|
this.getUserAgent = () => {
|
|
15909
15998
|
if (!this.cachedUserAgent) {
|
|
15910
15999
|
const { clientAppIdentifier = {} } = this.options;
|
|
15911
|
-
const { sdkName = 'js', sdkVersion = "1.44.
|
|
16000
|
+
const { sdkName = 'js', sdkVersion = "1.44.5", ...extras } = clientAppIdentifier;
|
|
15912
16001
|
this.cachedUserAgent = [
|
|
15913
16002
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
15914
16003
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|