@stream-io/video-client 1.46.0 → 1.46.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 +8 -0
- package/dist/index.browser.es.js +43 -16
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +43 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +43 -16
- package/dist/index.es.js.map +1 -1
- package/dist/src/helpers/RNSpeechDetector.d.ts +4 -2
- package/package.json +1 -1
- package/src/helpers/RNSpeechDetector.ts +52 -16
- package/src/helpers/__tests__/RNSpeechDetector.test.ts +52 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.46.1](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.46.0...@stream-io/video-client-1.46.1) (2026-04-09)
|
|
6
|
+
|
|
7
|
+
- remove listeners and stop even on permission error - rn speech detector ([f4fdd9e](https://github.com/GetStream/stream-video-js/commit/f4fdd9e1a008b52011ef18562152aad60a1f7936))
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
- ignore late ICE candidates after cleanup for RN speech detector ([#2193](https://github.com/GetStream/stream-video-js/issues/2193)) ([f8735d6](https://github.com/GetStream/stream-video-js/commit/f8735d604d86fc476b9b7e01eed0af03176625be))
|
|
12
|
+
|
|
5
13
|
## [1.46.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.45.0...@stream-io/video-client-1.46.0) (2026-04-09)
|
|
6
14
|
|
|
7
15
|
### Features
|
package/dist/index.browser.es.js
CHANGED
|
@@ -6284,7 +6284,7 @@ const getSdkVersion = (sdk) => {
|
|
|
6284
6284
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
6285
6285
|
};
|
|
6286
6286
|
|
|
6287
|
-
const version = "1.46.
|
|
6287
|
+
const version = "1.46.1";
|
|
6288
6288
|
const [major, minor, patch] = version.split('.');
|
|
6289
6289
|
let sdkInfo = {
|
|
6290
6290
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -11927,35 +11927,43 @@ class RNSpeechDetector {
|
|
|
11927
11927
|
constructor(externalAudioStream) {
|
|
11928
11928
|
this.pc1 = new RTCPeerConnection({});
|
|
11929
11929
|
this.pc2 = new RTCPeerConnection({});
|
|
11930
|
+
this.isStopped = false;
|
|
11930
11931
|
this.externalAudioStream = externalAudioStream;
|
|
11931
11932
|
}
|
|
11932
11933
|
/**
|
|
11933
11934
|
* Starts the speech detection.
|
|
11934
11935
|
*/
|
|
11935
11936
|
async start(onSoundDetectedStateChanged) {
|
|
11937
|
+
let detachListeners;
|
|
11938
|
+
let unsubscribe;
|
|
11936
11939
|
try {
|
|
11940
|
+
this.isStopped = false;
|
|
11937
11941
|
const audioStream = this.externalAudioStream != null
|
|
11938
11942
|
? this.externalAudioStream
|
|
11939
11943
|
: await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
11940
11944
|
this.audioStream = audioStream;
|
|
11941
|
-
|
|
11942
|
-
this.pc2
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
|
|
11947
|
-
|
|
11948
|
-
// do nothing
|
|
11949
|
-
});
|
|
11950
|
-
});
|
|
11951
|
-
this.pc2.addEventListener('track', (e) => {
|
|
11945
|
+
const onPc1IceCandidate = (e) => {
|
|
11946
|
+
this.forwardIceCandidate(this.pc2, e.candidate);
|
|
11947
|
+
};
|
|
11948
|
+
const onPc2IceCandidate = (e) => {
|
|
11949
|
+
this.forwardIceCandidate(this.pc1, e.candidate);
|
|
11950
|
+
};
|
|
11951
|
+
const onTrackPc2 = (e) => {
|
|
11952
11952
|
e.streams[0].getTracks().forEach((track) => {
|
|
11953
11953
|
// In RN, the remote track is automatically added to the audio output device
|
|
11954
11954
|
// so we need to mute it to avoid hearing the audio back
|
|
11955
11955
|
// @ts-expect-error _setVolume is a private method in react-native-webrtc
|
|
11956
11956
|
track._setVolume(0);
|
|
11957
11957
|
});
|
|
11958
|
-
}
|
|
11958
|
+
};
|
|
11959
|
+
this.pc1.addEventListener('icecandidate', onPc1IceCandidate);
|
|
11960
|
+
this.pc2.addEventListener('icecandidate', onPc2IceCandidate);
|
|
11961
|
+
this.pc2.addEventListener('track', onTrackPc2);
|
|
11962
|
+
detachListeners = () => {
|
|
11963
|
+
this.pc1.removeEventListener('icecandidate', onPc1IceCandidate);
|
|
11964
|
+
this.pc2.removeEventListener('icecandidate', onPc2IceCandidate);
|
|
11965
|
+
this.pc2.removeEventListener('track', onTrackPc2);
|
|
11966
|
+
};
|
|
11959
11967
|
audioStream
|
|
11960
11968
|
.getTracks()
|
|
11961
11969
|
.forEach((track) => this.pc1.addTrack(track, audioStream));
|
|
@@ -11965,13 +11973,17 @@ class RNSpeechDetector {
|
|
|
11965
11973
|
const answer = await this.pc2.createAnswer();
|
|
11966
11974
|
await this.pc1.setRemoteDescription(answer);
|
|
11967
11975
|
await this.pc2.setLocalDescription(answer);
|
|
11968
|
-
|
|
11976
|
+
unsubscribe = this.onSpeakingDetectedStateChange(onSoundDetectedStateChanged);
|
|
11969
11977
|
return () => {
|
|
11970
|
-
|
|
11978
|
+
detachListeners?.();
|
|
11979
|
+
unsubscribe?.();
|
|
11971
11980
|
this.stop();
|
|
11972
11981
|
};
|
|
11973
11982
|
}
|
|
11974
11983
|
catch (error) {
|
|
11984
|
+
detachListeners?.();
|
|
11985
|
+
unsubscribe?.();
|
|
11986
|
+
this.stop();
|
|
11975
11987
|
const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
|
|
11976
11988
|
logger.error('error handling permissions: ', error);
|
|
11977
11989
|
return () => { };
|
|
@@ -11981,6 +11993,9 @@ class RNSpeechDetector {
|
|
|
11981
11993
|
* Stops the speech detection and releases all allocated resources.
|
|
11982
11994
|
*/
|
|
11983
11995
|
stop() {
|
|
11996
|
+
if (this.isStopped)
|
|
11997
|
+
return;
|
|
11998
|
+
this.isStopped = true;
|
|
11984
11999
|
this.pc1.close();
|
|
11985
12000
|
this.pc2.close();
|
|
11986
12001
|
if (this.externalAudioStream != null) {
|
|
@@ -12080,6 +12095,18 @@ class RNSpeechDetector {
|
|
|
12080
12095
|
this.audioStream.release();
|
|
12081
12096
|
}
|
|
12082
12097
|
}
|
|
12098
|
+
forwardIceCandidate(destination, candidate) {
|
|
12099
|
+
if (this.isStopped ||
|
|
12100
|
+
!candidate ||
|
|
12101
|
+
destination.signalingState === 'closed') {
|
|
12102
|
+
return;
|
|
12103
|
+
}
|
|
12104
|
+
destination.addIceCandidate(candidate).catch(() => {
|
|
12105
|
+
// silently ignore the error
|
|
12106
|
+
const logger = videoLoggerSystem.getLogger('RNSpeechDetector');
|
|
12107
|
+
logger.info('cannot add ice candidate - ignoring');
|
|
12108
|
+
});
|
|
12109
|
+
}
|
|
12083
12110
|
}
|
|
12084
12111
|
|
|
12085
12112
|
class MicrophoneManager extends AudioDeviceManager {
|
|
@@ -16107,7 +16134,7 @@ class StreamClient {
|
|
|
16107
16134
|
this.getUserAgent = () => {
|
|
16108
16135
|
if (!this.cachedUserAgent) {
|
|
16109
16136
|
const { clientAppIdentifier = {} } = this.options;
|
|
16110
|
-
const { sdkName = 'js', sdkVersion = "1.46.
|
|
16137
|
+
const { sdkName = 'js', sdkVersion = "1.46.1", ...extras } = clientAppIdentifier;
|
|
16111
16138
|
this.cachedUserAgent = [
|
|
16112
16139
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
16113
16140
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|