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