@stream-io/video-client 1.4.0 → 1.4.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 +14 -0
- package/dist/index.browser.es.js +42 -12
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +42 -12
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +42 -12
- package/dist/index.es.js.map +1 -1
- package/dist/src/gen/coordinator/index.d.ts +5 -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 +5 -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/dist/index.es.js
CHANGED
|
@@ -123,6 +123,11 @@ const RecordSettingsRequestQualityEnum = {
|
|
|
123
123
|
_720P: '720p',
|
|
124
124
|
_1080P: '1080p',
|
|
125
125
|
_1440P: '1440p',
|
|
126
|
+
PORTRAIT_360X640: 'portrait-360x640',
|
|
127
|
+
PORTRAIT_480X854: 'portrait-480x854',
|
|
128
|
+
PORTRAIT_720X1280: 'portrait-720x1280',
|
|
129
|
+
PORTRAIT_1080X1920: 'portrait-1080x1920',
|
|
130
|
+
PORTRAIT_1440X2560: 'portrait-1440x2560',
|
|
126
131
|
};
|
|
127
132
|
/**
|
|
128
133
|
* @export
|
|
@@ -8256,8 +8261,9 @@ class Publisher {
|
|
|
8256
8261
|
* @param isDtxEnabled whether DTX is enabled.
|
|
8257
8262
|
* @param isRedEnabled whether RED is enabled.
|
|
8258
8263
|
* @param iceRestartDelay the delay in milliseconds to wait before restarting ICE once connection goes to `disconnected` state.
|
|
8264
|
+
* @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
|
|
8259
8265
|
*/
|
|
8260
|
-
constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, }) {
|
|
8266
|
+
constructor({ connectionConfig, sfuClient, dispatcher, state, isDtxEnabled, isRedEnabled, iceRestartDelay = 2500, onUnrecoverableError, }) {
|
|
8261
8267
|
this.transceiverRegistry = {
|
|
8262
8268
|
[TrackType.AUDIO]: undefined,
|
|
8263
8269
|
[TrackType.VIDEO]: undefined,
|
|
@@ -8778,15 +8784,16 @@ class Publisher {
|
|
|
8778
8784
|
logger$3('debug', `ICE Connection state changed to`, state);
|
|
8779
8785
|
const hasNetworkConnection = this.state.callingState !== CallingState.OFFLINE;
|
|
8780
8786
|
if (state === 'failed') {
|
|
8781
|
-
logger$3('
|
|
8787
|
+
logger$3('debug', `Attempting to restart ICE`);
|
|
8782
8788
|
this.restartIce().catch((e) => {
|
|
8783
8789
|
logger$3('error', `ICE restart error`, e);
|
|
8790
|
+
this.onUnrecoverableError?.();
|
|
8784
8791
|
});
|
|
8785
8792
|
}
|
|
8786
8793
|
else if (state === 'disconnected' && hasNetworkConnection) {
|
|
8787
8794
|
// when in `disconnected` state, the browser may recover automatically,
|
|
8788
8795
|
// hence, we delay the ICE restart
|
|
8789
|
-
logger$3('
|
|
8796
|
+
logger$3('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
|
|
8790
8797
|
this.iceRestartTimeout = setTimeout(() => {
|
|
8791
8798
|
// check if the state is still `disconnected` or `failed`
|
|
8792
8799
|
// as the connection may have recovered (or failed) in the meantime
|
|
@@ -8794,6 +8801,7 @@ class Publisher {
|
|
|
8794
8801
|
this.pc.iceConnectionState === 'failed') {
|
|
8795
8802
|
this.restartIce().catch((e) => {
|
|
8796
8803
|
logger$3('error', `ICE restart error`, e);
|
|
8804
|
+
this.onUnrecoverableError?.();
|
|
8797
8805
|
});
|
|
8798
8806
|
}
|
|
8799
8807
|
else {
|
|
@@ -8821,11 +8829,13 @@ class Publisher {
|
|
|
8821
8829
|
this.isDtxEnabled = isDtxEnabled;
|
|
8822
8830
|
this.isRedEnabled = isRedEnabled;
|
|
8823
8831
|
this.iceRestartDelay = iceRestartDelay;
|
|
8832
|
+
this.onUnrecoverableError = onUnrecoverableError;
|
|
8824
8833
|
this.unsubscribeOnIceRestart = dispatcher.on('iceRestart', (iceRestart) => {
|
|
8825
8834
|
if (iceRestart.peerType !== PeerType.PUBLISHER_UNSPECIFIED)
|
|
8826
8835
|
return;
|
|
8827
8836
|
this.restartIce().catch((err) => {
|
|
8828
8837
|
logger$3('warn', `ICERestart failed`, err);
|
|
8838
|
+
this.onUnrecoverableError?.();
|
|
8829
8839
|
});
|
|
8830
8840
|
});
|
|
8831
8841
|
}
|
|
@@ -8855,8 +8865,9 @@ class Subscriber {
|
|
|
8855
8865
|
* @param state the state of the call.
|
|
8856
8866
|
* @param connectionConfig the connection configuration to use.
|
|
8857
8867
|
* @param iceRestartDelay the delay in milliseconds to wait before restarting ICE when connection goes to `disconnected` state.
|
|
8868
|
+
* @param onUnrecoverableError a callback to call when an unrecoverable error occurs.
|
|
8858
8869
|
*/
|
|
8859
|
-
constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, }) {
|
|
8870
|
+
constructor({ sfuClient, dispatcher, state, connectionConfig, iceRestartDelay = 2500, onUnrecoverableError, }) {
|
|
8860
8871
|
this.isIceRestarting = false;
|
|
8861
8872
|
/**
|
|
8862
8873
|
* Creates a new `RTCPeerConnection` instance with the given configuration.
|
|
@@ -8966,6 +8977,10 @@ class Subscriber {
|
|
|
8966
8977
|
logger$2('debug', 'ICE restart is already in progress');
|
|
8967
8978
|
return;
|
|
8968
8979
|
}
|
|
8980
|
+
if (this.pc.connectionState === 'new') {
|
|
8981
|
+
logger$2('debug', `ICE connection is not yet established, skipping restart.`);
|
|
8982
|
+
return;
|
|
8983
|
+
}
|
|
8969
8984
|
const previousIsIceRestarting = this.isIceRestarting;
|
|
8970
8985
|
try {
|
|
8971
8986
|
this.isIceRestarting = true;
|
|
@@ -8986,17 +9001,18 @@ class Subscriber {
|
|
|
8986
9001
|
const participantToUpdate = this.state.participants.find((p) => p.trackLookupPrefix === trackId);
|
|
8987
9002
|
logger$2('debug', `[onTrack]: Got remote ${trackType} track for userId: ${participantToUpdate?.userId}`, e.track.id, e.track);
|
|
8988
9003
|
if (!participantToUpdate) {
|
|
8989
|
-
logger$2('
|
|
9004
|
+
logger$2('warn', `[onTrack]: Received track for unknown participant: ${trackId}`, e);
|
|
8990
9005
|
return;
|
|
8991
9006
|
}
|
|
9007
|
+
const trackDebugInfo = `${participantToUpdate.userId} ${trackType}:${trackId}`;
|
|
8992
9008
|
e.track.addEventListener('mute', () => {
|
|
8993
|
-
logger$2('info', `[onTrack]: Track muted: ${
|
|
9009
|
+
logger$2('info', `[onTrack]: Track muted: ${trackDebugInfo}`);
|
|
8994
9010
|
});
|
|
8995
9011
|
e.track.addEventListener('unmute', () => {
|
|
8996
|
-
logger$2('info', `[onTrack]: Track unmuted: ${
|
|
9012
|
+
logger$2('info', `[onTrack]: Track unmuted: ${trackDebugInfo}`);
|
|
8997
9013
|
});
|
|
8998
9014
|
e.track.addEventListener('ended', () => {
|
|
8999
|
-
logger$2('info', `[onTrack]: Track ended: ${
|
|
9015
|
+
logger$2('info', `[onTrack]: Track ended: ${trackDebugInfo}`);
|
|
9000
9016
|
});
|
|
9001
9017
|
const streamKindProp = {
|
|
9002
9018
|
TRACK_TYPE_AUDIO: 'audioStream',
|
|
@@ -9066,15 +9082,16 @@ class Subscriber {
|
|
|
9066
9082
|
return;
|
|
9067
9083
|
const hasNetworkConnection = this.state.callingState !== CallingState.OFFLINE;
|
|
9068
9084
|
if (state === 'failed') {
|
|
9069
|
-
logger$2('
|
|
9085
|
+
logger$2('debug', `Attempting to restart ICE`);
|
|
9070
9086
|
this.restartIce().catch((e) => {
|
|
9071
9087
|
logger$2('error', `ICE restart failed`, e);
|
|
9088
|
+
this.onUnrecoverableError?.();
|
|
9072
9089
|
});
|
|
9073
9090
|
}
|
|
9074
9091
|
else if (state === 'disconnected' && hasNetworkConnection) {
|
|
9075
9092
|
// when in `disconnected` state, the browser may recover automatically,
|
|
9076
9093
|
// hence, we delay the ICE restart
|
|
9077
|
-
logger$2('
|
|
9094
|
+
logger$2('debug', `Scheduling ICE restart in ${this.iceRestartDelay} ms.`);
|
|
9078
9095
|
this.iceRestartTimeout = setTimeout(() => {
|
|
9079
9096
|
// check if the state is still `disconnected` or `failed`
|
|
9080
9097
|
// as the connection may have recovered (or failed) in the meantime
|
|
@@ -9082,12 +9099,13 @@ class Subscriber {
|
|
|
9082
9099
|
this.pc.iceConnectionState === 'failed') {
|
|
9083
9100
|
this.restartIce().catch((e) => {
|
|
9084
9101
|
logger$2('error', `ICE restart failed`, e);
|
|
9102
|
+
this.onUnrecoverableError?.();
|
|
9085
9103
|
});
|
|
9086
9104
|
}
|
|
9087
9105
|
else {
|
|
9088
9106
|
logger$2('debug', `Scheduled ICE restart: connection recovered, canceled.`);
|
|
9089
9107
|
}
|
|
9090
|
-
},
|
|
9108
|
+
}, this.iceRestartDelay);
|
|
9091
9109
|
}
|
|
9092
9110
|
};
|
|
9093
9111
|
this.onIceGatheringStateChange = () => {
|
|
@@ -9103,6 +9121,7 @@ class Subscriber {
|
|
|
9103
9121
|
this.sfuClient = sfuClient;
|
|
9104
9122
|
this.state = state;
|
|
9105
9123
|
this.iceRestartDelay = iceRestartDelay;
|
|
9124
|
+
this.onUnrecoverableError = onUnrecoverableError;
|
|
9106
9125
|
this.pc = this.createPeerConnection(connectionConfig);
|
|
9107
9126
|
this.unregisterOnSubscriberOffer = dispatcher.on('subscriberOffer', (subscriberOffer) => {
|
|
9108
9127
|
this.negotiate(subscriberOffer).catch((err) => {
|
|
@@ -9114,6 +9133,7 @@ class Subscriber {
|
|
|
9114
9133
|
return;
|
|
9115
9134
|
this.restartIce().catch((err) => {
|
|
9116
9135
|
logger$2('warn', `ICERestart failed`, err);
|
|
9136
|
+
this.onUnrecoverableError?.();
|
|
9117
9137
|
});
|
|
9118
9138
|
});
|
|
9119
9139
|
}
|
|
@@ -12796,6 +12816,11 @@ class Call {
|
|
|
12796
12816
|
dispatcher: this.dispatcher,
|
|
12797
12817
|
state: this.state,
|
|
12798
12818
|
connectionConfig,
|
|
12819
|
+
onUnrecoverableError: () => {
|
|
12820
|
+
reconnect('full', 'unrecoverable subscriber error').catch((err) => {
|
|
12821
|
+
this.logger('debug', '[Rejoin]: Rejoin failed', err);
|
|
12822
|
+
});
|
|
12823
|
+
},
|
|
12799
12824
|
});
|
|
12800
12825
|
}
|
|
12801
12826
|
// anonymous users can't publish anything hence, there is no need
|
|
@@ -12812,6 +12837,11 @@ class Call {
|
|
|
12812
12837
|
connectionConfig,
|
|
12813
12838
|
isDtxEnabled,
|
|
12814
12839
|
isRedEnabled,
|
|
12840
|
+
onUnrecoverableError: () => {
|
|
12841
|
+
reconnect('full', 'unrecoverable publisher error').catch((err) => {
|
|
12842
|
+
this.logger('debug', '[Rejoin]: Rejoin failed', err);
|
|
12843
|
+
});
|
|
12844
|
+
},
|
|
12815
12845
|
});
|
|
12816
12846
|
}
|
|
12817
12847
|
if (!this.statsReporter) {
|
|
@@ -15383,7 +15413,7 @@ class StreamClient {
|
|
|
15383
15413
|
});
|
|
15384
15414
|
};
|
|
15385
15415
|
this.getUserAgent = () => {
|
|
15386
|
-
const version = "1.4.
|
|
15416
|
+
const version = "1.4.2" ;
|
|
15387
15417
|
return (this.userAgent ||
|
|
15388
15418
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
15389
15419
|
};
|