@stream-io/video-client 1.3.1 → 1.4.1
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 +37 -12
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +37 -12
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +37 -12
- package/dist/index.es.js.map +1 -1
- package/dist/src/gen/coordinator/index.d.ts +6 -0
- package/dist/src/rtc/Publisher.d.ts +4 -1
- package/dist/src/rtc/Subscriber.d.ts +4 -1
- package/package.json +1 -1
- package/src/Call.ts +10 -0
- package/src/gen/coordinator/index.ts +7 -0
- package/src/rtc/Publisher.ts +10 -2
- package/src/rtc/Subscriber.ts +23 -16
- package/src/rtc/__tests__/Subscriber.test.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
### [1.4.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.4.0...@stream-io/video-client-1.4.1) (2024-06-19)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* perform full reconnect if ice restart fails ([#1408](https://github.com/GetStream/stream-video-js/issues/1408)) ([641df7e](https://github.com/GetStream/stream-video-js/commit/641df7e50522452171498a9cf3de893472fe7b7b))
|
|
11
|
+
|
|
12
|
+
## [1.4.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.3.1...@stream-io/video-client-1.4.0) (2024-06-19)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **client:** support join_ahead_time_seconds field in the BackstageSettingsRequest struct ([#1397](https://github.com/GetStream/stream-video-js/issues/1397)) ([ded7a23](https://github.com/GetStream/stream-video-js/commit/ded7a23b1d112b496821bee95fe073f57bd51783))
|
|
18
|
+
|
|
5
19
|
### [1.3.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.3.0...@stream-io/video-client-1.3.1) (2024-06-12)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -8255,8 +8255,9 @@ class Publisher {
|
|
|
8255
8255
|
* @param isDtxEnabled whether DTX is enabled.
|
|
8256
8256
|
* @param isRedEnabled whether RED is enabled.
|
|
8257
8257
|
* @param iceRestartDelay the delay in milliseconds to wait before restarting ICE once connection goes to `disconnected` state.
|
|
8258
|
+
* @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
|
|
8258
8259
|
*/
|
|
8259
|
-
constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, }) {
|
|
8260
|
+
constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, onUnrecoverableError, }) {
|
|
8260
8261
|
this.transceiverRegistry = {
|
|
8261
8262
|
[TrackType.AUDIO]: undefined,
|
|
8262
8263
|
[TrackType.VIDEO]: undefined,
|
|
@@ -8777,15 +8778,16 @@ class Publisher {
|
|
|
8777
8778
|
logger$3('debug', `ICE Connection state changed to`, state);
|
|
8778
8779
|
const hasNetworkConnection = this.state.callingState !== CallingState.OFFLINE;
|
|
8779
8780
|
if (state === 'failed') {
|
|
8780
|
-
logger$3('
|
|
8781
|
+
logger$3('debug', `Attempting to restart ICE`);
|
|
8781
8782
|
this.restartIce().catch((e) => {
|
|
8782
8783
|
logger$3('error', `ICE restart error`, e);
|
|
8784
|
+
this.onUnrecoverableError?.();
|
|
8783
8785
|
});
|
|
8784
8786
|
}
|
|
8785
8787
|
else if (state === 'disconnected' && hasNetworkConnection) {
|
|
8786
8788
|
// when in `disconnected` state, the browser may recover automatically,
|
|
8787
8789
|
// hence, we delay the ICE restart
|
|
8788
|
-
logger$3('
|
|
8790
|
+
logger$3('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
|
|
8789
8791
|
this.iceRestartTimeout = setTimeout(() => {
|
|
8790
8792
|
// check if the state is still `disconnected` or `failed`
|
|
8791
8793
|
// as the connection may have recovered (or failed) in the meantime
|
|
@@ -8793,6 +8795,7 @@ class Publisher {
|
|
|
8793
8795
|
this.pc.iceConnectionState === 'failed') {
|
|
8794
8796
|
this.restartIce().catch((e) => {
|
|
8795
8797
|
logger$3('error', `ICE restart error`, e);
|
|
8798
|
+
this.onUnrecoverableError?.();
|
|
8796
8799
|
});
|
|
8797
8800
|
}
|
|
8798
8801
|
else {
|
|
@@ -8820,11 +8823,13 @@ class Publisher {
|
|
|
8820
8823
|
this.isDtxEnabled = isDtxEnabled;
|
|
8821
8824
|
this.isRedEnabled = isRedEnabled;
|
|
8822
8825
|
this.iceRestartDelay = iceRestartDelay;
|
|
8826
|
+
this.onUnrecoverableError = onUnrecoverableError;
|
|
8823
8827
|
this.unsubscribeOnIceRestart = dispatcher.on('iceRestart', (iceRestart) => {
|
|
8824
8828
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
|
|
8825
8829
|
return;
|
|
8826
8830
|
this.restartIce().catch((err) => {
|
|
8827
8831
|
logger$3('warn', `ICERestart failed`, err);
|
|
8832
|
+
this.onUnrecoverableError?.();
|
|
8828
8833
|
});
|
|
8829
8834
|
});
|
|
8830
8835
|
}
|
|
@@ -8854,8 +8859,9 @@ class Subscriber {
|
|
|
8854
8859
|
* @param state the state of the call.
|
|
8855
8860
|
* @param connectionConfig the connection configuration to use.
|
|
8856
8861
|
* @param iceRestartDelay the delay in milliseconds to wait before restarting ICE when connection goes to `disconnected` state.
|
|
8862
|
+
* @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
|
|
8857
8863
|
*/
|
|
8858
|
-
constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, }) {
|
|
8864
|
+
constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, onUnrecoverableError, }) {
|
|
8859
8865
|
this.isIceRestarting = false;
|
|
8860
8866
|
/**
|
|
8861
8867
|
* Creates a new `RTCPeerConnection` instance with the given configuration.
|
|
@@ -8965,6 +8971,10 @@ class Subscriber {
|
|
|
8965
8971
|
logger$2('debug', 'ICE restart is already in progress');
|
|
8966
8972
|
return;
|
|
8967
8973
|
}
|
|
8974
|
+
if (this.pc.connectionState === 'new') {
|
|
8975
|
+
logger$2('debug', `ICE connection is not yet established, skipping restart.`);
|
|
8976
|
+
return;
|
|
8977
|
+
}
|
|
8968
8978
|
const previousIsIceRestarting = this.isIceRestarting;
|
|
8969
8979
|
try {
|
|
8970
8980
|
this.isIceRestarting = true;
|
|
@@ -8985,17 +8995,18 @@ class Subscriber {
|
|
|
8985
8995
|
const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
|
|
8986
8996
|
logger$2('debug', `[onTrack]: Got remote ${trackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
|
|
8987
8997
|
if (!participantToUpdate) {
|
|
8988
|
-
logger$2('
|
|
8998
|
+
logger$2('warn', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
|
|
8989
8999
|
return;
|
|
8990
9000
|
}
|
|
9001
|
+
const trackDebugInfo = `${participantToUpdate.userId} ${trackType}:${trackId}`;
|
|
8991
9002
|
e.track.addEventListener('mute', () => {
|
|
8992
|
-
logger$2('info', `[onTrack]: Track muted: ${
|
|
9003
|
+
logger$2('info', `[onTrack]: Track muted: ${trackDebugInfo}`);
|
|
8993
9004
|
});
|
|
8994
9005
|
e.track.addEventListener('unmute', () => {
|
|
8995
|
-
logger$2('info', `[onTrack]: Track unmuted: ${
|
|
9006
|
+
logger$2('info', `[onTrack]: Track unmuted: ${trackDebugInfo}`);
|
|
8996
9007
|
});
|
|
8997
9008
|
e.track.addEventListener('ended', () => {
|
|
8998
|
-
logger$2('info', `[onTrack]: Track ended: ${
|
|
9009
|
+
logger$2('info', `[onTrack]: Track ended: ${trackDebugInfo}`);
|
|
8999
9010
|
});
|
|
9000
9011
|
const streamKindProp = {
|
|
9001
9012
|
TRACK_TYPE_AUDIO: 'audioStream',
|
|
@@ -9065,15 +9076,16 @@ class Subscriber {
|
|
|
9065
9076
|
return;
|
|
9066
9077
|
const hasNetworkConnection = this.state.callingState !== CallingState.OFFLINE;
|
|
9067
9078
|
if (state === 'failed') {
|
|
9068
|
-
logger$2('
|
|
9079
|
+
logger$2('debug', `Attempting to restart ICE`);
|
|
9069
9080
|
this.restartIce().catch((e) => {
|
|
9070
9081
|
logger$2('error', `ICE restart failed`, e);
|
|
9082
|
+
this.onUnrecoverableError?.();
|
|
9071
9083
|
});
|
|
9072
9084
|
}
|
|
9073
9085
|
else if (state === 'disconnected' && hasNetworkConnection) {
|
|
9074
9086
|
// when in `disconnected` state, the browser may recover automatically,
|
|
9075
9087
|
// hence, we delay the ICE restart
|
|
9076
|
-
logger$2('
|
|
9088
|
+
logger$2('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
|
|
9077
9089
|
this.iceRestartTimeout = setTimeout(() => {
|
|
9078
9090
|
// check if the state is still `disconnected` or `failed`
|
|
9079
9091
|
// as the connection may have recovered (or failed) in the meantime
|
|
@@ -9081,12 +9093,13 @@ class Subscriber {
|
|
|
9081
9093
|
this.pc.iceConnectionState === 'failed') {
|
|
9082
9094
|
this.restartIce().catch((e) => {
|
|
9083
9095
|
logger$2('error', `ICE restart failed`, e);
|
|
9096
|
+
this.onUnrecoverableError?.();
|
|
9084
9097
|
});
|
|
9085
9098
|
}
|
|
9086
9099
|
else {
|
|
9087
9100
|
logger$2('debug', `Scheduled ICE restart: connection recovered, canceled.`);
|
|
9088
9101
|
}
|
|
9089
|
-
},
|
|
9102
|
+
}, this.iceRestartDelay);
|
|
9090
9103
|
}
|
|
9091
9104
|
};
|
|
9092
9105
|
this.onIceGatheringStateChange = () => {
|
|
@@ -9102,6 +9115,7 @@ class Subscriber {
|
|
|
9102
9115
|
this.sfuClient = sfuClient;
|
|
9103
9116
|
this.state = state;
|
|
9104
9117
|
this.iceRestartDelay = iceRestartDelay;
|
|
9118
|
+
this.onUnrecoverableError = onUnrecoverableError;
|
|
9105
9119
|
this.pc = this.createPeerConnection(connectionConfig);
|
|
9106
9120
|
this.unregisterOnSubscriberOffer = dispatcher.on('subscriberOffer', (subscriberOffer) => {
|
|
9107
9121
|
this.negotiate(subscriberOffer).catch((err) => {
|
|
@@ -9113,6 +9127,7 @@ class Subscriber {
|
|
|
9113
9127
|
return;
|
|
9114
9128
|
this.restartIce().catch((err) => {
|
|
9115
9129
|
logger$2('warn', `ICERestart failed`, err);
|
|
9130
|
+
this.onUnrecoverableError?.();
|
|
9116
9131
|
});
|
|
9117
9132
|
});
|
|
9118
9133
|
}
|
|
@@ -12795,6 +12810,11 @@ class Call {
|
|
|
12795
12810
|
dispatcher: this.dispatcher,
|
|
12796
12811
|
state: this.state,
|
|
12797
12812
|
connectionConfig,
|
|
12813
|
+
onUnrecoverableError: () => {
|
|
12814
|
+
reconnect('full', 'unrecoverable subscriber error').catch((err) => {
|
|
12815
|
+
this.logger('debug', '[Rejoin]: Rejoin failed', err);
|
|
12816
|
+
});
|
|
12817
|
+
},
|
|
12798
12818
|
});
|
|
12799
12819
|
}
|
|
12800
12820
|
// anonymous users can't publish anything hence, there is no need
|
|
@@ -12811,6 +12831,11 @@ class Call {
|
|
|
12811
12831
|
connectionConfig,
|
|
12812
12832
|
isDtxEnabled,
|
|
12813
12833
|
isRedEnabled,
|
|
12834
|
+
onUnrecoverableError: () => {
|
|
12835
|
+
reconnect('full', 'unrecoverable publisher error').catch((err) => {
|
|
12836
|
+
this.logger('debug', '[Rejoin]: Rejoin failed', err);
|
|
12837
|
+
});
|
|
12838
|
+
},
|
|
12814
12839
|
});
|
|
12815
12840
|
}
|
|
12816
12841
|
if (!this.statsReporter) {
|
|
@@ -15384,7 +15409,7 @@ class StreamClient {
|
|
|
15384
15409
|
});
|
|
15385
15410
|
};
|
|
15386
15411
|
this.getUserAgent = () => {
|
|
15387
|
-
const version = "1.
|
|
15412
|
+
const version = "1.4.1" ;
|
|
15388
15413
|
return (this.userAgent ||
|
|
15389
15414
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
15390
15415
|
};
|