@stream-io/video-client 1.16.0 → 1.16.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 +17 -0
- package/dist/index.browser.es.js +54 -9
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +54 -9
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +54 -9
- package/dist/index.es.js.map +1 -1
- package/dist/src/rtc/BasePeerConnection.d.ts +2 -1
- package/package.json +1 -1
- package/src/devices/CameraManager.ts +25 -4
- package/src/devices/__tests__/CameraManager.test.ts +14 -4
- package/src/devices/__tests__/mocks.ts +4 -1
- package/src/rtc/BasePeerConnection.ts +14 -4
- package/src/rtc/Publisher.ts +7 -4
- package/src/store/stateStore.ts +2 -0
package/dist/index.es.js
CHANGED
|
@@ -3897,6 +3897,8 @@ class StreamVideoWriteableStateStore {
|
|
|
3897
3897
|
* @param call the call to remove
|
|
3898
3898
|
*/
|
|
3899
3899
|
this.unregisterCall = (call) => {
|
|
3900
|
+
const logger = getLogger(['client-state']);
|
|
3901
|
+
logger('trace', `Unregistering call: ${call.cid}`);
|
|
3900
3902
|
return this.setCalls((calls) => calls.filter((c) => c !== call));
|
|
3901
3903
|
};
|
|
3902
3904
|
/**
|
|
@@ -5182,11 +5184,14 @@ class BasePeerConnection {
|
|
|
5182
5184
|
*/
|
|
5183
5185
|
constructor(peerType, { sfuClient, connectionConfig, state, dispatcher, onUnrecoverableError, logTag, }) {
|
|
5184
5186
|
this.isIceRestarting = false;
|
|
5187
|
+
this.isDisposed = false;
|
|
5185
5188
|
this.subscriptions = [];
|
|
5186
5189
|
/**
|
|
5187
5190
|
* Disposes the `RTCPeerConnection` instance.
|
|
5188
5191
|
*/
|
|
5189
5192
|
this.dispose = () => {
|
|
5193
|
+
this.onUnrecoverableError = undefined;
|
|
5194
|
+
this.isDisposed = true;
|
|
5190
5195
|
this.detachEventHandlers();
|
|
5191
5196
|
this.pc.close();
|
|
5192
5197
|
};
|
|
@@ -5197,6 +5202,8 @@ class BasePeerConnection {
|
|
|
5197
5202
|
this.on = (event, fn) => {
|
|
5198
5203
|
this.subscriptions.push(this.dispatcher.on(event, (e) => {
|
|
5199
5204
|
withoutConcurrency(`pc.${event}`, async () => fn(e)).catch((err) => {
|
|
5205
|
+
if (this.isDisposed)
|
|
5206
|
+
return;
|
|
5200
5207
|
this.logger('warn', `Error handling ${event}`, err);
|
|
5201
5208
|
});
|
|
5202
5209
|
}));
|
|
@@ -5212,6 +5219,8 @@ class BasePeerConnection {
|
|
|
5212
5219
|
this.unsubscribeIceTrickle?.();
|
|
5213
5220
|
this.unsubscribeIceTrickle = createSafeAsyncSubscription(observable, async (candidate) => {
|
|
5214
5221
|
return this.pc.addIceCandidate(candidate).catch((e) => {
|
|
5222
|
+
if (this.isDisposed)
|
|
5223
|
+
return;
|
|
5215
5224
|
this.logger('warn', `ICE candidate error`, e, candidate);
|
|
5216
5225
|
});
|
|
5217
5226
|
});
|
|
@@ -5244,7 +5253,11 @@ class BasePeerConnection {
|
|
|
5244
5253
|
const iceCandidate = this.toJSON(candidate);
|
|
5245
5254
|
this.sfuClient
|
|
5246
5255
|
.iceTrickle({ peerType: this.peerType, iceCandidate })
|
|
5247
|
-
.catch((err) =>
|
|
5256
|
+
.catch((err) => {
|
|
5257
|
+
if (this.isDisposed)
|
|
5258
|
+
return;
|
|
5259
|
+
this.logger('warn', `ICETrickle failed`, err);
|
|
5260
|
+
});
|
|
5248
5261
|
};
|
|
5249
5262
|
/**
|
|
5250
5263
|
* Converts the ICE candidate to a JSON string.
|
|
@@ -5273,6 +5286,8 @@ class BasePeerConnection {
|
|
|
5273
5286
|
if (state === 'failed' || state === 'disconnected') {
|
|
5274
5287
|
this.logger('debug', `Attempting to restart ICE`);
|
|
5275
5288
|
this.restartIce().catch((e) => {
|
|
5289
|
+
if (this.isDisposed)
|
|
5290
|
+
return;
|
|
5276
5291
|
this.logger('error', `ICE restart failed`, e);
|
|
5277
5292
|
this.onUnrecoverableError?.();
|
|
5278
5293
|
});
|
|
@@ -5324,6 +5339,8 @@ class BasePeerConnection {
|
|
|
5324
5339
|
this.pc.removeEventListener('icecandidateerror', this.onIceCandidateError);
|
|
5325
5340
|
this.pc.removeEventListener('signalingstatechange', this.onSignalingChange);
|
|
5326
5341
|
this.pc.removeEventListener('iceconnectionstatechange', this.onIceConnectionStateChange);
|
|
5342
|
+
// cancel any ongoing ICE restart process
|
|
5343
|
+
withCancellation('onIceConnectionStateChange', () => Promise.resolve());
|
|
5327
5344
|
this.pc.removeEventListener('icegatheringstatechange', this.onIceGatherChange);
|
|
5328
5345
|
this.unsubscribeIceTrickle?.();
|
|
5329
5346
|
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
@@ -5839,10 +5856,12 @@ class Publisher extends BasePeerConnection {
|
|
|
5839
5856
|
await this.negotiate({ iceRestart: true });
|
|
5840
5857
|
};
|
|
5841
5858
|
this.onNegotiationNeeded = () => {
|
|
5842
|
-
|
|
5859
|
+
withCancellation('publisher.negotiate', (signal) => this.negotiate().catch((err) => {
|
|
5860
|
+
if (signal.aborted)
|
|
5861
|
+
return;
|
|
5843
5862
|
this.logger('error', `Negotiation failed.`, err);
|
|
5844
5863
|
this.onUnrecoverableError?.();
|
|
5845
|
-
});
|
|
5864
|
+
}));
|
|
5846
5865
|
};
|
|
5847
5866
|
/**
|
|
5848
5867
|
* Initiates a new offer/answer exchange with the currently connected SFU.
|
|
@@ -5969,6 +5988,8 @@ class Publisher extends BasePeerConnection {
|
|
|
5969
5988
|
detachEventHandlers() {
|
|
5970
5989
|
super.detachEventHandlers();
|
|
5971
5990
|
this.pc.removeEventListener('negotiationneeded', this.onNegotiationNeeded);
|
|
5991
|
+
// abort any ongoing negotiation
|
|
5992
|
+
withCancellation('publisher.negotiate', () => Promise.resolve());
|
|
5972
5993
|
}
|
|
5973
5994
|
}
|
|
5974
5995
|
|
|
@@ -7393,7 +7414,7 @@ const aggregate = (stats) => {
|
|
|
7393
7414
|
return report;
|
|
7394
7415
|
};
|
|
7395
7416
|
|
|
7396
|
-
const version = "1.16.
|
|
7417
|
+
const version = "1.16.2";
|
|
7397
7418
|
const [major, minor, patch] = version.split('.');
|
|
7398
7419
|
let sdkInfo = {
|
|
7399
7420
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -9250,10 +9271,34 @@ class CameraManager extends InputMediaDeviceManager {
|
|
|
9250
9271
|
*/
|
|
9251
9272
|
async selectDirection(direction) {
|
|
9252
9273
|
if (this.isDirectionSupportedByDevice()) {
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9274
|
+
if (isReactNative()) {
|
|
9275
|
+
const videoTrack = this.getTracks()[0];
|
|
9276
|
+
if (!videoTrack)
|
|
9277
|
+
return;
|
|
9278
|
+
// @ts-expect-error _switchCamera() is only present in react-native-webrtc 124 and below
|
|
9279
|
+
if (typeof videoTrack._switchCamera === 'function') {
|
|
9280
|
+
// @ts-expect-error for older versions of react-native-webrtc support
|
|
9281
|
+
videoTrack._switchCamera();
|
|
9282
|
+
}
|
|
9283
|
+
else {
|
|
9284
|
+
const constraints = {
|
|
9285
|
+
facingMode: direction === 'front' ? 'user' : 'environment',
|
|
9286
|
+
};
|
|
9287
|
+
await videoTrack.applyConstraints(constraints);
|
|
9288
|
+
}
|
|
9289
|
+
this.state.setDirection(direction);
|
|
9290
|
+
this.state.setDevice(undefined);
|
|
9291
|
+
}
|
|
9292
|
+
else {
|
|
9293
|
+
// web mobile
|
|
9294
|
+
this.state.setDirection(direction);
|
|
9295
|
+
// Providing both device id and direction doesn't work, so we deselect the device
|
|
9296
|
+
this.state.setDevice(undefined);
|
|
9297
|
+
this.getTracks().forEach((track) => {
|
|
9298
|
+
track.stop();
|
|
9299
|
+
});
|
|
9300
|
+
await this.unmuteStream();
|
|
9301
|
+
}
|
|
9257
9302
|
}
|
|
9258
9303
|
else {
|
|
9259
9304
|
this.logger('warn', 'Camera direction ignored for desktop devices');
|
|
@@ -12974,7 +13019,7 @@ class StreamClient {
|
|
|
12974
13019
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
12975
13020
|
};
|
|
12976
13021
|
this.getUserAgent = () => {
|
|
12977
|
-
const version = "1.16.
|
|
13022
|
+
const version = "1.16.2";
|
|
12978
13023
|
return (this.userAgent ||
|
|
12979
13024
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
12980
13025
|
};
|