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