@stream-io/video-client 1.44.2 → 1.44.4
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 +34 -33
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +34 -33
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +34 -33
- package/dist/index.es.js.map +1 -1
- package/dist/src/StreamSfuClient.d.ts +1 -0
- 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/package.json +2 -2
- package/src/StreamSfuClient.ts +15 -9
- 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 +25 -31
- package/src/rpc/retryable.ts +2 -0
package/dist/index.cjs.js
CHANGED
|
@@ -4025,6 +4025,8 @@ const retryable = async (rpc, signal, maxRetries = Number.POSITIVE_INFINITY) =>
|
|
|
4025
4025
|
do {
|
|
4026
4026
|
if (attempt > 0)
|
|
4027
4027
|
await sleep(retryInterval(attempt));
|
|
4028
|
+
if (signal?.aborted)
|
|
4029
|
+
throw new Error(signal.reason);
|
|
4028
4030
|
try {
|
|
4029
4031
|
result = await rpc({ attempt });
|
|
4030
4032
|
}
|
|
@@ -6301,7 +6303,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6301
6303
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6302
6304
|
};
|
|
6303
6305
|
|
|
6304
|
-
const version = "1.44.
|
|
6306
|
+
const version = "1.44.4";
|
|
6305
6307
|
const [major, minor, patch] = version.split('.');
|
|
6306
6308
|
let sdkInfo = {
|
|
6307
6309
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -8602,6 +8604,7 @@ class StreamSfuClient {
|
|
|
8602
8604
|
this.isClosingClean = false;
|
|
8603
8605
|
this.pingIntervalInMs = 5 * 1000;
|
|
8604
8606
|
this.unhealthyTimeoutInMs = 15 * 1000;
|
|
8607
|
+
this.subscriptionsConcurrencyTag = Symbol('subscriptionsConcurrencyTag');
|
|
8605
8608
|
/**
|
|
8606
8609
|
* Promise that resolves when the JoinResponse is received.
|
|
8607
8610
|
* Rejects after a certain threshold if the response is not received.
|
|
@@ -8709,8 +8712,10 @@ class StreamSfuClient {
|
|
|
8709
8712
|
this.close(StreamSfuClient.NORMAL_CLOSURE, reason.substring(0, 115));
|
|
8710
8713
|
};
|
|
8711
8714
|
this.updateSubscriptions = async (tracks) => {
|
|
8712
|
-
|
|
8713
|
-
|
|
8715
|
+
return withoutConcurrency(this.subscriptionsConcurrencyTag, async () => {
|
|
8716
|
+
await this.joinTask;
|
|
8717
|
+
return retryable((invocationMeta) => this.rpc.updateSubscriptions({ sessionId: this.sessionId, tracks }, { invocationMeta }), this.abortController.signal);
|
|
8718
|
+
});
|
|
8714
8719
|
};
|
|
8715
8720
|
this.setPublisher = async (data) => {
|
|
8716
8721
|
await this.joinTask;
|
|
@@ -10313,6 +10318,9 @@ class BrowserPermission {
|
|
|
10313
10318
|
}
|
|
10314
10319
|
setState(state) {
|
|
10315
10320
|
if (this.state !== state) {
|
|
10321
|
+
const { tracer, queryName } = this.permission;
|
|
10322
|
+
const traceKey = `navigator.mediaDevices.${queryName}.permission`;
|
|
10323
|
+
tracer?.trace(traceKey, { previous: this.state, state });
|
|
10316
10324
|
this.state = state;
|
|
10317
10325
|
this.listeners.forEach((listener) => listener(state));
|
|
10318
10326
|
}
|
|
@@ -10383,17 +10391,19 @@ const videoDeviceConstraints = {
|
|
|
10383
10391
|
* Keeps track of the browser permission to use microphone. This permission also
|
|
10384
10392
|
* affects an ability to enumerate audio devices.
|
|
10385
10393
|
*/
|
|
10386
|
-
const getAudioBrowserPermission = lazy(() => new BrowserPermission({
|
|
10394
|
+
const getAudioBrowserPermission = lazy((tracer) => new BrowserPermission({
|
|
10387
10395
|
constraints: audioDeviceConstraints,
|
|
10388
10396
|
queryName: 'microphone',
|
|
10397
|
+
tracer,
|
|
10389
10398
|
}));
|
|
10390
10399
|
/**
|
|
10391
10400
|
* Keeps track of the browser permission to use camera. This permission also
|
|
10392
10401
|
* affects an ability to enumerate video devices.
|
|
10393
10402
|
*/
|
|
10394
|
-
const getVideoBrowserPermission = lazy(() => new BrowserPermission({
|
|
10403
|
+
const getVideoBrowserPermission = lazy((tracer) => new BrowserPermission({
|
|
10395
10404
|
constraints: videoDeviceConstraints,
|
|
10396
10405
|
queryName: 'camera',
|
|
10406
|
+
tracer,
|
|
10397
10407
|
}));
|
|
10398
10408
|
const getDeviceChangeObserver = lazy((tracer) => {
|
|
10399
10409
|
// 'addEventListener' is not available in React Native, returning
|
|
@@ -10409,7 +10419,7 @@ const getDeviceChangeObserver = lazy((tracer) => {
|
|
|
10409
10419
|
* the observable errors.
|
|
10410
10420
|
*/
|
|
10411
10421
|
const getAudioDevices = lazy((tracer) => {
|
|
10412
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(), 'audioinput', tracer)), rxjs.shareReplay(1));
|
|
10422
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audioinput', tracer)), rxjs.shareReplay(1));
|
|
10413
10423
|
});
|
|
10414
10424
|
/**
|
|
10415
10425
|
* Prompts the user for a permission to use video devices (if not already granted
|
|
@@ -10418,7 +10428,7 @@ const getAudioDevices = lazy((tracer) => {
|
|
|
10418
10428
|
* the observable errors.
|
|
10419
10429
|
*/
|
|
10420
10430
|
const getVideoDevices = lazy((tracer) => {
|
|
10421
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getVideoBrowserPermission(), 'videoinput', tracer)), rxjs.shareReplay(1));
|
|
10431
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getVideoBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getVideoBrowserPermission(tracer), 'videoinput', tracer)), rxjs.shareReplay(1));
|
|
10422
10432
|
});
|
|
10423
10433
|
/**
|
|
10424
10434
|
* Prompts the user for a permission to use video devices (if not already granted
|
|
@@ -10427,7 +10437,7 @@ const getVideoDevices = lazy((tracer) => {
|
|
|
10427
10437
|
* the observable errors.
|
|
10428
10438
|
*/
|
|
10429
10439
|
const getAudioOutputDevices = lazy((tracer) => {
|
|
10430
|
-
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission().asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(), 'audiooutput', tracer)), rxjs.shareReplay(1));
|
|
10440
|
+
return rxjs.merge(getDeviceChangeObserver(tracer), getAudioBrowserPermission(tracer).asObservable()).pipe(rxjs.startWith([]), rxjs.concatMap(() => getDevices(getAudioBrowserPermission(tracer), 'audiooutput', tracer)), rxjs.shareReplay(1));
|
|
10431
10441
|
});
|
|
10432
10442
|
let getUserMediaExecId = 0;
|
|
10433
10443
|
const getStream = async (constraints, tracer) => {
|
|
@@ -10493,25 +10503,21 @@ const getAudioStream = async (trackConstraints, tracer) => {
|
|
|
10493
10503
|
},
|
|
10494
10504
|
};
|
|
10495
10505
|
try {
|
|
10496
|
-
await getAudioBrowserPermission().prompt({
|
|
10506
|
+
await getAudioBrowserPermission(tracer).prompt({
|
|
10497
10507
|
throwOnNotAllowed: true,
|
|
10498
10508
|
forcePrompt: true,
|
|
10499
10509
|
});
|
|
10500
10510
|
return await getStream(constraints, tracer);
|
|
10501
10511
|
}
|
|
10502
10512
|
catch (error) {
|
|
10513
|
+
const logger = videoLoggerSystem.getLogger('devices');
|
|
10503
10514
|
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
10504
10515
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10505
10516
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
10506
|
-
|
|
10507
|
-
.getLogger('devices')
|
|
10508
|
-
.warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10517
|
+
logger.warn('Failed to get audio stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10509
10518
|
return getAudioStream(relaxedConstraints, tracer);
|
|
10510
10519
|
}
|
|
10511
|
-
|
|
10512
|
-
error,
|
|
10513
|
-
constraints,
|
|
10514
|
-
});
|
|
10520
|
+
logger.error('Failed to get audio stream', { error, constraints });
|
|
10515
10521
|
throw error;
|
|
10516
10522
|
}
|
|
10517
10523
|
};
|
|
@@ -10531,25 +10537,21 @@ const getVideoStream = async (trackConstraints, tracer) => {
|
|
|
10531
10537
|
},
|
|
10532
10538
|
};
|
|
10533
10539
|
try {
|
|
10534
|
-
await getVideoBrowserPermission().prompt({
|
|
10540
|
+
await getVideoBrowserPermission(tracer).prompt({
|
|
10535
10541
|
throwOnNotAllowed: true,
|
|
10536
10542
|
forcePrompt: true,
|
|
10537
10543
|
});
|
|
10538
10544
|
return await getStream(constraints, tracer);
|
|
10539
10545
|
}
|
|
10540
10546
|
catch (error) {
|
|
10547
|
+
const logger = videoLoggerSystem.getLogger('devices');
|
|
10541
10548
|
if (isNotFoundOrOverconstrainedError(error) && trackConstraints?.deviceId) {
|
|
10542
10549
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
10543
10550
|
const { deviceId, ...relaxedConstraints } = trackConstraints;
|
|
10544
|
-
|
|
10545
|
-
|
|
10546
|
-
.warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10547
|
-
return getVideoStream(relaxedConstraints);
|
|
10551
|
+
logger.warn('Failed to get video stream, will try again with relaxed constraints', { error, constraints, relaxedConstraints });
|
|
10552
|
+
return getVideoStream(relaxedConstraints, tracer);
|
|
10548
10553
|
}
|
|
10549
|
-
|
|
10550
|
-
error,
|
|
10551
|
-
constraints,
|
|
10552
|
-
});
|
|
10554
|
+
logger.error('Failed to get video stream', { error, constraints });
|
|
10553
10555
|
throw error;
|
|
10554
10556
|
}
|
|
10555
10557
|
};
|
|
@@ -11320,8 +11322,8 @@ class DeviceManagerState {
|
|
|
11320
11322
|
}
|
|
11321
11323
|
|
|
11322
11324
|
class CameraManagerState extends DeviceManagerState {
|
|
11323
|
-
constructor() {
|
|
11324
|
-
super('stop-tracks', getVideoBrowserPermission());
|
|
11325
|
+
constructor(tracer) {
|
|
11326
|
+
super('stop-tracks', getVideoBrowserPermission(tracer));
|
|
11325
11327
|
this.directionSubject = new rxjs.BehaviorSubject(undefined);
|
|
11326
11328
|
/**
|
|
11327
11329
|
* Observable that emits the preferred camera direction
|
|
@@ -11375,7 +11377,7 @@ class CameraManager extends DeviceManager {
|
|
|
11375
11377
|
* @param devicePersistence the device persistence preferences to use.
|
|
11376
11378
|
*/
|
|
11377
11379
|
constructor(call, devicePersistence) {
|
|
11378
|
-
super(call, new CameraManagerState(), TrackType.VIDEO, devicePersistence);
|
|
11380
|
+
super(call, new CameraManagerState(call.tracer), TrackType.VIDEO, devicePersistence);
|
|
11379
11381
|
this.targetResolution = {
|
|
11380
11382
|
width: 1280,
|
|
11381
11383
|
height: 720,
|
|
@@ -11586,8 +11588,8 @@ class AudioDeviceManagerState extends DeviceManagerState {
|
|
|
11586
11588
|
}
|
|
11587
11589
|
|
|
11588
11590
|
class MicrophoneManagerState extends AudioDeviceManagerState {
|
|
11589
|
-
constructor(disableMode) {
|
|
11590
|
-
super(disableMode, getAudioBrowserPermission(), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
|
|
11591
|
+
constructor(disableMode, tracer) {
|
|
11592
|
+
super(disableMode, getAudioBrowserPermission(tracer), AudioBitrateProfile.VOICE_STANDARD_UNSPECIFIED);
|
|
11591
11593
|
this.speakingWhileMutedSubject = new rxjs.BehaviorSubject(false);
|
|
11592
11594
|
/**
|
|
11593
11595
|
* An Observable that emits `true` if the user's microphone is muted, but they're speaking.
|
|
@@ -11927,7 +11929,7 @@ class RNSpeechDetector {
|
|
|
11927
11929
|
|
|
11928
11930
|
class MicrophoneManager extends AudioDeviceManager {
|
|
11929
11931
|
constructor(call, devicePersistence, disableMode = 'stop-tracks') {
|
|
11930
|
-
super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO, devicePersistence);
|
|
11932
|
+
super(call, new MicrophoneManagerState(disableMode, call.tracer), TrackType.AUDIO, devicePersistence);
|
|
11931
11933
|
this.speakingWhileMutedNotificationEnabled = true;
|
|
11932
11934
|
this.soundDetectorConcurrencyTag = Symbol('soundDetectorConcurrencyTag');
|
|
11933
11935
|
this.silenceThresholdMs = 5000;
|
|
@@ -12029,7 +12031,6 @@ class MicrophoneManager extends AudioDeviceManager {
|
|
|
12029
12031
|
deviceId,
|
|
12030
12032
|
label,
|
|
12031
12033
|
};
|
|
12032
|
-
console.log(event);
|
|
12033
12034
|
this.call.tracer.trace('mic.capture_report', event);
|
|
12034
12035
|
this.call.streamClient.dispatchEvent(event);
|
|
12035
12036
|
},
|
|
@@ -15903,7 +15904,7 @@ class StreamClient {
|
|
|
15903
15904
|
this.getUserAgent = () => {
|
|
15904
15905
|
if (!this.cachedUserAgent) {
|
|
15905
15906
|
const { clientAppIdentifier = {} } = this.options;
|
|
15906
|
-
const { sdkName = 'js', sdkVersion = "1.44.
|
|
15907
|
+
const { sdkName = 'js', sdkVersion = "1.44.4", ...extras } = clientAppIdentifier;
|
|
15907
15908
|
this.cachedUserAgent = [
|
|
15908
15909
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
15909
15910
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|