@stream-io/video-client 1.15.6 → 1.16.0
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 +249 -137
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +253 -141
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.es.js +249 -137
- package/dist/index.es.js.map +1 -1
- package/dist/src/Call.d.ts +18 -2
- package/dist/src/coordinator/connection/types.d.ts +4 -4
- package/dist/src/gen/coordinator/index.d.ts +1876 -2591
- package/dist/src/helpers/RNSpeechDetector.d.ts +3 -4
- package/dist/src/store/CallState.d.ts +2 -3
- package/index.ts +0 -1
- package/package.json +1 -1
- package/src/Call.ts +53 -2
- package/src/coordinator/connection/types.ts +4 -4
- package/src/devices/MicrophoneManager.ts +4 -12
- package/src/devices/__tests__/MicrophoneManagerRN.test.ts +6 -4
- package/src/gen/coordinator/index.ts +2762 -3476
- package/src/helpers/RNSpeechDetector.ts +104 -40
- package/src/store/CallState.ts +18 -26
- package/src/store/__tests__/CallState.test.ts +13 -1
- package/dist/src/gen/shims.d.ts +0 -41
- package/src/gen/shims.ts +0 -44
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.16.0](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.15.7...@stream-io/video-client-1.16.0) (2025-01-31)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* OpenAPI upgrades and HLS status reporting ([#1668](https://github.com/GetStream/stream-video-js/issues/1668)) ([2f377b8](https://github.com/GetStream/stream-video-js/commit/2f377b8772f7b9fc8fcb8b8e9b3eecb1920bc7d0))
|
|
11
|
+
|
|
12
|
+
## [1.15.7](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.15.6...@stream-io/video-client-1.15.7) (2025-01-29)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* speech detection and align mic disable with web ([#1658](https://github.com/GetStream/stream-video-js/issues/1658)) ([fd908fb](https://github.com/GetStream/stream-video-js/commit/fd908fb2b70e6bade595f44107ca2f85aa4d5631))
|
|
18
|
+
|
|
5
19
|
## [1.15.6](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.15.5...@stream-io/video-client-1.15.6) (2025-01-29)
|
|
6
20
|
|
|
7
21
|
|
package/dist/index.browser.es.js
CHANGED
|
@@ -8,8 +8,6 @@ import { ReplaySubject, combineLatest, BehaviorSubject, map, shareReplay, distin
|
|
|
8
8
|
import { parse } from 'sdp-transform';
|
|
9
9
|
import { UAParser } from 'ua-parser-js';
|
|
10
10
|
|
|
11
|
-
/* tslint:disable */
|
|
12
|
-
/* eslint-disable */
|
|
13
11
|
/**
|
|
14
12
|
* @export
|
|
15
13
|
*/
|
|
@@ -24,80 +22,6 @@ const AudioSettingsResponseDefaultDeviceEnum = {
|
|
|
24
22
|
SPEAKER: 'speaker',
|
|
25
23
|
EARPIECE: 'earpiece',
|
|
26
24
|
};
|
|
27
|
-
/**
|
|
28
|
-
* @export
|
|
29
|
-
*/
|
|
30
|
-
const BlockListOptionsBehaviorEnum = {
|
|
31
|
-
FLAG: 'flag',
|
|
32
|
-
BLOCK: 'block',
|
|
33
|
-
SHADOW_BLOCK: 'shadow_block',
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* @export
|
|
37
|
-
*/
|
|
38
|
-
const ChannelConfigWithInfoAutomodEnum = {
|
|
39
|
-
DISABLED: 'disabled',
|
|
40
|
-
SIMPLE: 'simple',
|
|
41
|
-
AI: 'AI',
|
|
42
|
-
};
|
|
43
|
-
/**
|
|
44
|
-
* @export
|
|
45
|
-
*/
|
|
46
|
-
const ChannelConfigWithInfoAutomodBehaviorEnum = {
|
|
47
|
-
FLAG: 'flag',
|
|
48
|
-
BLOCK: 'block',
|
|
49
|
-
SHADOW_BLOCK: 'shadow_block',
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* @export
|
|
53
|
-
*/
|
|
54
|
-
const ChannelConfigWithInfoBlocklistBehaviorEnum = {
|
|
55
|
-
FLAG: 'flag',
|
|
56
|
-
BLOCK: 'block',
|
|
57
|
-
SHADOW_BLOCK: 'shadow_block',
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* All possibility of string to use
|
|
61
|
-
* @export
|
|
62
|
-
*/
|
|
63
|
-
const ChannelOwnCapability = {
|
|
64
|
-
BAN_CHANNEL_MEMBERS: 'ban-channel-members',
|
|
65
|
-
CAST_POLL_VOTE: 'cast-poll-vote',
|
|
66
|
-
CONNECT_EVENTS: 'connect-events',
|
|
67
|
-
CREATE_ATTACHMENT: 'create-attachment',
|
|
68
|
-
CREATE_CALL: 'create-call',
|
|
69
|
-
DELETE_ANY_MESSAGE: 'delete-any-message',
|
|
70
|
-
DELETE_CHANNEL: 'delete-channel',
|
|
71
|
-
DELETE_OWN_MESSAGE: 'delete-own-message',
|
|
72
|
-
FLAG_MESSAGE: 'flag-message',
|
|
73
|
-
FREEZE_CHANNEL: 'freeze-channel',
|
|
74
|
-
JOIN_CALL: 'join-call',
|
|
75
|
-
JOIN_CHANNEL: 'join-channel',
|
|
76
|
-
LEAVE_CHANNEL: 'leave-channel',
|
|
77
|
-
MUTE_CHANNEL: 'mute-channel',
|
|
78
|
-
PIN_MESSAGE: 'pin-message',
|
|
79
|
-
QUERY_POLL_VOTES: 'query-poll-votes',
|
|
80
|
-
QUOTE_MESSAGE: 'quote-message',
|
|
81
|
-
READ_EVENTS: 'read-events',
|
|
82
|
-
SEARCH_MESSAGES: 'search-messages',
|
|
83
|
-
SEND_CUSTOM_EVENTS: 'send-custom-events',
|
|
84
|
-
SEND_LINKS: 'send-links',
|
|
85
|
-
SEND_MESSAGE: 'send-message',
|
|
86
|
-
SEND_POLL: 'send-poll',
|
|
87
|
-
SEND_REACTION: 'send-reaction',
|
|
88
|
-
SEND_REPLY: 'send-reply',
|
|
89
|
-
SEND_TYPING_EVENTS: 'send-typing-events',
|
|
90
|
-
SET_CHANNEL_COOLDOWN: 'set-channel-cooldown',
|
|
91
|
-
SKIP_SLOW_MODE: 'skip-slow-mode',
|
|
92
|
-
SLOW_MODE: 'slow-mode',
|
|
93
|
-
TYPING_EVENTS: 'typing-events',
|
|
94
|
-
UPDATE_ANY_MESSAGE: 'update-any-message',
|
|
95
|
-
UPDATE_CHANNEL: 'update-channel',
|
|
96
|
-
UPDATE_CHANNEL_MEMBERS: 'update-channel-members',
|
|
97
|
-
UPDATE_OWN_MESSAGE: 'update-own-message',
|
|
98
|
-
UPDATE_THREAD: 'update-thread',
|
|
99
|
-
UPLOAD_FILE: 'upload-file',
|
|
100
|
-
};
|
|
101
25
|
/**
|
|
102
26
|
* @export
|
|
103
27
|
*/
|
|
@@ -107,6 +31,16 @@ const CreateDeviceRequestPushProviderEnum = {
|
|
|
107
31
|
HUAWEI: 'huawei',
|
|
108
32
|
XIAOMI: 'xiaomi',
|
|
109
33
|
};
|
|
34
|
+
/**
|
|
35
|
+
* @export
|
|
36
|
+
*/
|
|
37
|
+
const LayoutSettingsRequestNameEnum = {
|
|
38
|
+
SPOTLIGHT: 'spotlight',
|
|
39
|
+
GRID: 'grid',
|
|
40
|
+
SINGLE_PARTICIPANT: 'single-participant',
|
|
41
|
+
MOBILE: 'mobile',
|
|
42
|
+
CUSTOM: 'custom',
|
|
43
|
+
};
|
|
110
44
|
/**
|
|
111
45
|
* @export
|
|
112
46
|
*/
|
|
@@ -149,6 +83,36 @@ const OwnCapability = {
|
|
|
149
83
|
UPDATE_CALL_PERMISSIONS: 'update-call-permissions',
|
|
150
84
|
UPDATE_CALL_SETTINGS: 'update-call-settings',
|
|
151
85
|
};
|
|
86
|
+
/**
|
|
87
|
+
* @export
|
|
88
|
+
*/
|
|
89
|
+
const RTMPBroadcastRequestQualityEnum = {
|
|
90
|
+
_360P: '360p',
|
|
91
|
+
_480P: '480p',
|
|
92
|
+
_720P: '720p',
|
|
93
|
+
_1080P: '1080p',
|
|
94
|
+
_1440P: '1440p',
|
|
95
|
+
PORTRAIT_360X640: 'portrait-360x640',
|
|
96
|
+
PORTRAIT_480X854: 'portrait-480x854',
|
|
97
|
+
PORTRAIT_720X1280: 'portrait-720x1280',
|
|
98
|
+
PORTRAIT_1080X1920: 'portrait-1080x1920',
|
|
99
|
+
PORTRAIT_1440X2560: 'portrait-1440x2560',
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* @export
|
|
103
|
+
*/
|
|
104
|
+
const RTMPSettingsRequestQualityEnum = {
|
|
105
|
+
_360P: '360p',
|
|
106
|
+
_480P: '480p',
|
|
107
|
+
_720P: '720p',
|
|
108
|
+
_1080P: '1080p',
|
|
109
|
+
_1440P: '1440p',
|
|
110
|
+
PORTRAIT_360X640: 'portrait-360x640',
|
|
111
|
+
PORTRAIT_480X854: 'portrait-480x854',
|
|
112
|
+
PORTRAIT_720X1280: 'portrait-720x1280',
|
|
113
|
+
PORTRAIT_1080X1920: 'portrait-1080x1920',
|
|
114
|
+
PORTRAIT_1440X2560: 'portrait-1440x2560',
|
|
115
|
+
};
|
|
152
116
|
/**
|
|
153
117
|
* @export
|
|
154
118
|
*/
|
|
@@ -180,6 +144,44 @@ const TranscriptionSettingsRequestClosedCaptionModeEnum = {
|
|
|
180
144
|
DISABLED: 'disabled',
|
|
181
145
|
AUTO_ON: 'auto-on',
|
|
182
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* @export
|
|
149
|
+
*/
|
|
150
|
+
const TranscriptionSettingsRequestLanguageEnum = {
|
|
151
|
+
AUTO: 'auto',
|
|
152
|
+
EN: 'en',
|
|
153
|
+
FR: 'fr',
|
|
154
|
+
ES: 'es',
|
|
155
|
+
DE: 'de',
|
|
156
|
+
IT: 'it',
|
|
157
|
+
NL: 'nl',
|
|
158
|
+
PT: 'pt',
|
|
159
|
+
PL: 'pl',
|
|
160
|
+
CA: 'ca',
|
|
161
|
+
CS: 'cs',
|
|
162
|
+
DA: 'da',
|
|
163
|
+
EL: 'el',
|
|
164
|
+
FI: 'fi',
|
|
165
|
+
ID: 'id',
|
|
166
|
+
JA: 'ja',
|
|
167
|
+
RU: 'ru',
|
|
168
|
+
SV: 'sv',
|
|
169
|
+
TA: 'ta',
|
|
170
|
+
TH: 'th',
|
|
171
|
+
TR: 'tr',
|
|
172
|
+
HU: 'hu',
|
|
173
|
+
RO: 'ro',
|
|
174
|
+
ZH: 'zh',
|
|
175
|
+
AR: 'ar',
|
|
176
|
+
TL: 'tl',
|
|
177
|
+
HE: 'he',
|
|
178
|
+
HI: 'hi',
|
|
179
|
+
HR: 'hr',
|
|
180
|
+
KO: 'ko',
|
|
181
|
+
MS: 'ms',
|
|
182
|
+
NO: 'no',
|
|
183
|
+
UK: 'uk',
|
|
184
|
+
};
|
|
183
185
|
/**
|
|
184
186
|
* @export
|
|
185
187
|
*/
|
|
@@ -196,6 +198,44 @@ const TranscriptionSettingsResponseClosedCaptionModeEnum = {
|
|
|
196
198
|
DISABLED: 'disabled',
|
|
197
199
|
AUTO_ON: 'auto-on',
|
|
198
200
|
};
|
|
201
|
+
/**
|
|
202
|
+
* @export
|
|
203
|
+
*/
|
|
204
|
+
const TranscriptionSettingsResponseLanguageEnum = {
|
|
205
|
+
AUTO: 'auto',
|
|
206
|
+
EN: 'en',
|
|
207
|
+
FR: 'fr',
|
|
208
|
+
ES: 'es',
|
|
209
|
+
DE: 'de',
|
|
210
|
+
IT: 'it',
|
|
211
|
+
NL: 'nl',
|
|
212
|
+
PT: 'pt',
|
|
213
|
+
PL: 'pl',
|
|
214
|
+
CA: 'ca',
|
|
215
|
+
CS: 'cs',
|
|
216
|
+
DA: 'da',
|
|
217
|
+
EL: 'el',
|
|
218
|
+
FI: 'fi',
|
|
219
|
+
ID: 'id',
|
|
220
|
+
JA: 'ja',
|
|
221
|
+
RU: 'ru',
|
|
222
|
+
SV: 'sv',
|
|
223
|
+
TA: 'ta',
|
|
224
|
+
TH: 'th',
|
|
225
|
+
TR: 'tr',
|
|
226
|
+
HU: 'hu',
|
|
227
|
+
RO: 'ro',
|
|
228
|
+
ZH: 'zh',
|
|
229
|
+
AR: 'ar',
|
|
230
|
+
TL: 'tl',
|
|
231
|
+
HE: 'he',
|
|
232
|
+
HI: 'hi',
|
|
233
|
+
HR: 'hr',
|
|
234
|
+
KO: 'ko',
|
|
235
|
+
MS: 'ms',
|
|
236
|
+
NO: 'no',
|
|
237
|
+
UK: 'uk',
|
|
238
|
+
};
|
|
199
239
|
/**
|
|
200
240
|
* @export
|
|
201
241
|
*/
|
|
@@ -4183,7 +4223,7 @@ const livestreamOrAudioRoomSortPreset = combineComparators(ifInvisibleBy(combine
|
|
|
4183
4223
|
*/
|
|
4184
4224
|
const defaultEgress = {
|
|
4185
4225
|
broadcasting: false,
|
|
4186
|
-
hls: { playlist_url: '' },
|
|
4226
|
+
hls: { playlist_url: '', status: '' },
|
|
4187
4227
|
rtmps: [],
|
|
4188
4228
|
};
|
|
4189
4229
|
/**
|
|
@@ -4646,21 +4686,19 @@ class CallState {
|
|
|
4646
4686
|
this.setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
|
|
4647
4687
|
...egress,
|
|
4648
4688
|
broadcasting: false,
|
|
4689
|
+
hls: {
|
|
4690
|
+
...egress.hls,
|
|
4691
|
+
status: '',
|
|
4692
|
+
},
|
|
4649
4693
|
}));
|
|
4650
4694
|
};
|
|
4651
4695
|
this.updateFromHLSBroadcastingFailed = () => {
|
|
4652
4696
|
this.setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
|
|
4653
4697
|
...egress,
|
|
4654
4698
|
broadcasting: false,
|
|
4655
|
-
}));
|
|
4656
|
-
};
|
|
4657
|
-
this.updateFromHLSBroadcastStarted = (event) => {
|
|
4658
|
-
this.setCurrentValue(this.egressSubject, (egress = defaultEgress) => ({
|
|
4659
|
-
...egress,
|
|
4660
|
-
broadcasting: true,
|
|
4661
4699
|
hls: {
|
|
4662
4700
|
...egress.hls,
|
|
4663
|
-
|
|
4701
|
+
status: '',
|
|
4664
4702
|
},
|
|
4665
4703
|
}));
|
|
4666
4704
|
};
|
|
@@ -4871,21 +4909,16 @@ class CallState {
|
|
|
4871
4909
|
this.captioning$ = duc(this.captioningSubject);
|
|
4872
4910
|
this.eventHandlers = {
|
|
4873
4911
|
// these events are not updating the call state:
|
|
4874
|
-
'call.deleted': undefined,
|
|
4875
4912
|
'call.permission_request': undefined,
|
|
4876
4913
|
'call.recording_ready': undefined,
|
|
4914
|
+
'call.rtmp_broadcast_failed': undefined,
|
|
4915
|
+
'call.rtmp_broadcast_started': undefined,
|
|
4916
|
+
'call.rtmp_broadcast_stopped': undefined,
|
|
4877
4917
|
'call.transcription_ready': undefined,
|
|
4878
4918
|
'call.user_muted': undefined,
|
|
4879
4919
|
'connection.error': undefined,
|
|
4880
4920
|
'connection.ok': undefined,
|
|
4881
4921
|
'health.check': undefined,
|
|
4882
|
-
'user.banned': undefined,
|
|
4883
|
-
'user.deactivated': undefined,
|
|
4884
|
-
'user.deleted': undefined,
|
|
4885
|
-
'user.muted': undefined,
|
|
4886
|
-
'user.presence.changed': undefined,
|
|
4887
|
-
'user.reactivated': undefined,
|
|
4888
|
-
'user.unbanned': undefined,
|
|
4889
4922
|
'user.updated': undefined,
|
|
4890
4923
|
custom: undefined,
|
|
4891
4924
|
// events that update call state:
|
|
@@ -4902,12 +4935,15 @@ class CallState {
|
|
|
4902
4935
|
this.setCurrentValue(this.captioningSubject, false);
|
|
4903
4936
|
},
|
|
4904
4937
|
'call.created': (e) => this.updateFromCallResponse(e.call),
|
|
4938
|
+
'call.deleted': (e) => this.updateFromCallResponse(e.call),
|
|
4905
4939
|
'call.ended': (e) => {
|
|
4906
4940
|
this.updateFromCallResponse(e.call);
|
|
4907
4941
|
this.setCurrentValue(this.endedBySubject, e.user);
|
|
4908
4942
|
},
|
|
4909
4943
|
'call.hls_broadcasting_failed': this.updateFromHLSBroadcastingFailed,
|
|
4910
|
-
'call.hls_broadcasting_started':
|
|
4944
|
+
'call.hls_broadcasting_started': (e) => {
|
|
4945
|
+
this.updateFromCallResponse(e.call);
|
|
4946
|
+
},
|
|
4911
4947
|
'call.hls_broadcasting_stopped': this.updateFromHLSBroadcastStopped,
|
|
4912
4948
|
'call.live_started': (e) => this.updateFromCallResponse(e.call),
|
|
4913
4949
|
'call.member_added': this.updateFromMemberAdded,
|
|
@@ -7356,7 +7392,7 @@ const aggregate = (stats) => {
|
|
|
7356
7392
|
return report;
|
|
7357
7393
|
};
|
|
7358
7394
|
|
|
7359
|
-
const version = "1.
|
|
7395
|
+
const version = "1.16.0";
|
|
7360
7396
|
const [major, minor, patch] = version.split('.');
|
|
7361
7397
|
let sdkInfo = {
|
|
7362
7398
|
type: SdkType.PLAIN_JAVASCRIPT,
|
|
@@ -9337,7 +9373,7 @@ class MicrophoneManagerState extends InputMediaDeviceManagerState {
|
|
|
9337
9373
|
}
|
|
9338
9374
|
|
|
9339
9375
|
const DETECTION_FREQUENCY_IN_MS = 500;
|
|
9340
|
-
const AUDIO_LEVEL_THRESHOLD
|
|
9376
|
+
const AUDIO_LEVEL_THRESHOLD = 150;
|
|
9341
9377
|
const FFT_SIZE = 128;
|
|
9342
9378
|
/**
|
|
9343
9379
|
* Creates a new sound detector.
|
|
@@ -9348,7 +9384,7 @@ const FFT_SIZE = 128;
|
|
|
9348
9384
|
* @returns a clean-up function which once invoked stops the sound detector.
|
|
9349
9385
|
*/
|
|
9350
9386
|
const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options = {}) => {
|
|
9351
|
-
const { detectionFrequencyInMs = DETECTION_FREQUENCY_IN_MS, audioLevelThreshold = AUDIO_LEVEL_THRESHOLD
|
|
9387
|
+
const { detectionFrequencyInMs = DETECTION_FREQUENCY_IN_MS, audioLevelThreshold = AUDIO_LEVEL_THRESHOLD, fftSize = FFT_SIZE, destroyStreamOnStop = true, } = options;
|
|
9352
9388
|
const audioContext = new AudioContext();
|
|
9353
9389
|
const analyser = audioContext.createAnalyser();
|
|
9354
9390
|
analyser.fftSize = fftSize;
|
|
@@ -9389,7 +9425,6 @@ const createSoundDetector = (audioStream, onSoundDetectedStateChanged, options =
|
|
|
9389
9425
|
};
|
|
9390
9426
|
};
|
|
9391
9427
|
|
|
9392
|
-
const AUDIO_LEVEL_THRESHOLD = 0.2;
|
|
9393
9428
|
class RNSpeechDetector {
|
|
9394
9429
|
constructor() {
|
|
9395
9430
|
this.pc1 = new RTCPeerConnection({});
|
|
@@ -9398,7 +9433,7 @@ class RNSpeechDetector {
|
|
|
9398
9433
|
/**
|
|
9399
9434
|
* Starts the speech detection.
|
|
9400
9435
|
*/
|
|
9401
|
-
async start() {
|
|
9436
|
+
async start(onSoundDetectedStateChanged) {
|
|
9402
9437
|
try {
|
|
9403
9438
|
this.cleanupAudioStream();
|
|
9404
9439
|
const audioStream = await navigator.mediaDevices.getUserMedia({
|
|
@@ -9411,6 +9446,14 @@ class RNSpeechDetector {
|
|
|
9411
9446
|
this.pc2.addEventListener('icecandidate', async (e) => {
|
|
9412
9447
|
await this.pc1.addIceCandidate(e.candidate);
|
|
9413
9448
|
});
|
|
9449
|
+
this.pc2.addEventListener('track', (e) => {
|
|
9450
|
+
e.streams[0].getTracks().forEach((track) => {
|
|
9451
|
+
// In RN, the remote track is automatically added to the audio output device
|
|
9452
|
+
// so we need to mute it to avoid hearing the audio back
|
|
9453
|
+
// @ts-ignore _setVolume is a private method in react-native-webrtc
|
|
9454
|
+
track._setVolume(0);
|
|
9455
|
+
});
|
|
9456
|
+
});
|
|
9414
9457
|
audioStream
|
|
9415
9458
|
.getTracks()
|
|
9416
9459
|
.forEach((track) => this.pc1.addTrack(track, audioStream));
|
|
@@ -9420,12 +9463,16 @@ class RNSpeechDetector {
|
|
|
9420
9463
|
const answer = await this.pc2.createAnswer();
|
|
9421
9464
|
await this.pc1.setRemoteDescription(answer);
|
|
9422
9465
|
await this.pc2.setLocalDescription(answer);
|
|
9423
|
-
const
|
|
9424
|
-
|
|
9425
|
-
|
|
9466
|
+
const unsub = this.onSpeakingDetectedStateChange(onSoundDetectedStateChanged);
|
|
9467
|
+
return () => {
|
|
9468
|
+
unsub();
|
|
9469
|
+
this.stop();
|
|
9470
|
+
};
|
|
9426
9471
|
}
|
|
9427
9472
|
catch (error) {
|
|
9428
|
-
|
|
9473
|
+
const logger = getLogger(['RNSpeechDetector']);
|
|
9474
|
+
logger('error', 'error handling permissions: ', error);
|
|
9475
|
+
return () => { };
|
|
9429
9476
|
}
|
|
9430
9477
|
}
|
|
9431
9478
|
/**
|
|
@@ -9435,40 +9482,85 @@ class RNSpeechDetector {
|
|
|
9435
9482
|
this.pc1.close();
|
|
9436
9483
|
this.pc2.close();
|
|
9437
9484
|
this.cleanupAudioStream();
|
|
9438
|
-
if (this.intervalId) {
|
|
9439
|
-
clearInterval(this.intervalId);
|
|
9440
|
-
}
|
|
9441
9485
|
}
|
|
9442
9486
|
/**
|
|
9443
9487
|
* Public method that detects the audio levels and returns the status.
|
|
9444
9488
|
*/
|
|
9445
9489
|
onSpeakingDetectedStateChange(onSoundDetectedStateChanged) {
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9490
|
+
const initialBaselineNoiseLevel = 0.13;
|
|
9491
|
+
let baselineNoiseLevel = initialBaselineNoiseLevel;
|
|
9492
|
+
let speechDetected = false;
|
|
9493
|
+
let intervalId;
|
|
9494
|
+
let speechTimer;
|
|
9495
|
+
let silenceTimer;
|
|
9496
|
+
let audioLevelHistory = []; // Store recent audio levels for smoother detection
|
|
9497
|
+
const historyLength = 10;
|
|
9498
|
+
const silenceThreshold = 1.1;
|
|
9499
|
+
const resetThreshold = 0.9;
|
|
9500
|
+
const speechTimeout = 500; // Speech is set to true after 500ms of audio detection
|
|
9501
|
+
const silenceTimeout = 5000; // Reset baseline after 5 seconds of silence
|
|
9502
|
+
const checkAudioLevel = async () => {
|
|
9503
|
+
try {
|
|
9504
|
+
const stats = (await this.pc1.getStats());
|
|
9505
|
+
const report = flatten(stats);
|
|
9506
|
+
// Audio levels are present inside stats of type `media-source` and of kind `audio`
|
|
9507
|
+
const audioMediaSourceStats = report.find((stat) => stat.type === 'media-source' &&
|
|
9508
|
+
stat.kind === 'audio');
|
|
9509
|
+
if (audioMediaSourceStats) {
|
|
9510
|
+
const { audioLevel } = audioMediaSourceStats;
|
|
9511
|
+
if (audioLevel) {
|
|
9512
|
+
// Update audio level history (with max historyLength sized array)
|
|
9513
|
+
audioLevelHistory.push(audioLevel);
|
|
9514
|
+
if (audioLevelHistory.length > historyLength) {
|
|
9515
|
+
audioLevelHistory.shift();
|
|
9516
|
+
}
|
|
9517
|
+
// Calculate average audio level
|
|
9518
|
+
const avgAudioLevel = audioLevelHistory.reduce((a, b) => a + b, 0) /
|
|
9519
|
+
audioLevelHistory.length;
|
|
9520
|
+
// Update baseline (if necessary) based on silence detection
|
|
9521
|
+
if (avgAudioLevel < baselineNoiseLevel * silenceThreshold) {
|
|
9522
|
+
if (!silenceTimer) {
|
|
9523
|
+
silenceTimer = setTimeout(() => {
|
|
9524
|
+
baselineNoiseLevel = Math.min(avgAudioLevel * resetThreshold, initialBaselineNoiseLevel);
|
|
9525
|
+
}, silenceTimeout);
|
|
9526
|
+
}
|
|
9527
|
+
}
|
|
9528
|
+
else {
|
|
9529
|
+
clearTimeout(silenceTimer);
|
|
9530
|
+
silenceTimer = undefined;
|
|
9531
|
+
}
|
|
9532
|
+
// Speech detection with hysteresis
|
|
9533
|
+
if (avgAudioLevel > baselineNoiseLevel * 1.5) {
|
|
9534
|
+
if (!speechDetected) {
|
|
9535
|
+
speechDetected = true;
|
|
9536
|
+
onSoundDetectedStateChanged({
|
|
9537
|
+
isSoundDetected: true,
|
|
9538
|
+
audioLevel,
|
|
9539
|
+
});
|
|
9540
|
+
}
|
|
9541
|
+
clearTimeout(speechTimer);
|
|
9542
|
+
speechTimer = setTimeout(() => {
|
|
9543
|
+
speechDetected = false;
|
|
9544
|
+
onSoundDetectedStateChanged({
|
|
9545
|
+
isSoundDetected: false,
|
|
9546
|
+
audioLevel: 0,
|
|
9547
|
+
});
|
|
9548
|
+
}, speechTimeout);
|
|
9549
|
+
}
|
|
9466
9550
|
}
|
|
9467
9551
|
}
|
|
9468
9552
|
}
|
|
9469
|
-
|
|
9553
|
+
catch (error) {
|
|
9554
|
+
const logger = getLogger(['RNSpeechDetector']);
|
|
9555
|
+
logger('error', 'error checking audio level from stats', error);
|
|
9556
|
+
}
|
|
9557
|
+
};
|
|
9558
|
+
// Call checkAudioLevel periodically (every 100ms)
|
|
9559
|
+
intervalId = setInterval(checkAudioLevel, 100);
|
|
9470
9560
|
return () => {
|
|
9471
|
-
clearInterval(
|
|
9561
|
+
clearInterval(intervalId);
|
|
9562
|
+
clearTimeout(speechTimer);
|
|
9563
|
+
clearTimeout(silenceTimer);
|
|
9472
9564
|
};
|
|
9473
9565
|
}
|
|
9474
9566
|
cleanupAudioStream() {
|
|
@@ -9486,9 +9578,7 @@ class RNSpeechDetector {
|
|
|
9486
9578
|
}
|
|
9487
9579
|
|
|
9488
9580
|
class MicrophoneManager extends InputMediaDeviceManager {
|
|
9489
|
-
constructor(call, disableMode =
|
|
9490
|
-
? 'disable-tracks'
|
|
9491
|
-
: 'stop-tracks') {
|
|
9581
|
+
constructor(call, disableMode = 'stop-tracks') {
|
|
9492
9582
|
super(call, new MicrophoneManagerState(disableMode), TrackType.AUDIO);
|
|
9493
9583
|
this.speakingWhileMutedNotificationEnabled = true;
|
|
9494
9584
|
this.soundDetectorConcurrencyTag = Symbol('soundDetectorConcurrencyTag');
|
|
@@ -9669,13 +9759,11 @@ class MicrophoneManager extends InputMediaDeviceManager {
|
|
|
9669
9759
|
await this.stopSpeakingWhileMutedDetection();
|
|
9670
9760
|
if (isReactNative()) {
|
|
9671
9761
|
this.rnSpeechDetector = new RNSpeechDetector();
|
|
9672
|
-
await this.rnSpeechDetector.start()
|
|
9673
|
-
const unsubscribe = this.rnSpeechDetector?.onSpeakingDetectedStateChange((event) => {
|
|
9762
|
+
const unsubscribe = await this.rnSpeechDetector.start((event) => {
|
|
9674
9763
|
this.state.setSpeakingWhileMuted(event.isSoundDetected);
|
|
9675
9764
|
});
|
|
9676
9765
|
this.soundDetectorCleanup = () => {
|
|
9677
9766
|
unsubscribe();
|
|
9678
|
-
this.rnSpeechDetector?.stop();
|
|
9679
9767
|
this.rnSpeechDetector = undefined;
|
|
9680
9768
|
};
|
|
9681
9769
|
}
|
|
@@ -10358,6 +10446,12 @@ class Call {
|
|
|
10358
10446
|
this.create = async (data) => {
|
|
10359
10447
|
return this.getOrCreate(data);
|
|
10360
10448
|
};
|
|
10449
|
+
/**
|
|
10450
|
+
* Deletes the call.
|
|
10451
|
+
*/
|
|
10452
|
+
this.delete = async (data = {}) => {
|
|
10453
|
+
return this.streamClient.post(`${this.streamClientBasePath}/delete`, data);
|
|
10454
|
+
};
|
|
10361
10455
|
/**
|
|
10362
10456
|
* A shortcut for {@link Call.get} with `ring` parameter set to `true`.
|
|
10363
10457
|
* Will send a `call.ring` event to the call members.
|
|
@@ -11368,8 +11462,8 @@ class Call {
|
|
|
11368
11462
|
/**
|
|
11369
11463
|
* Stops the livestreaming of the call.
|
|
11370
11464
|
*/
|
|
11371
|
-
this.stopLive = async () => {
|
|
11372
|
-
return this.streamClient.post(`${this.streamClientBasePath}/stop_live`,
|
|
11465
|
+
this.stopLive = async (data = {}) => {
|
|
11466
|
+
return this.streamClient.post(`${this.streamClientBasePath}/stop_live`, data);
|
|
11373
11467
|
};
|
|
11374
11468
|
/**
|
|
11375
11469
|
* Starts the broadcasting of the call.
|
|
@@ -11383,6 +11477,24 @@ class Call {
|
|
|
11383
11477
|
this.stopHLS = async () => {
|
|
11384
11478
|
return this.streamClient.post(`${this.streamClientBasePath}/stop_broadcasting`, {});
|
|
11385
11479
|
};
|
|
11480
|
+
/**
|
|
11481
|
+
* Starts the RTMP-out broadcasting of the call.
|
|
11482
|
+
*/
|
|
11483
|
+
this.startRTMPBroadcasts = async (data) => {
|
|
11484
|
+
return this.streamClient.post(`${this.streamClientBasePath}/rtmp_broadcasts`, data);
|
|
11485
|
+
};
|
|
11486
|
+
/**
|
|
11487
|
+
* Stops all RTMP-out broadcasting of the call.
|
|
11488
|
+
*/
|
|
11489
|
+
this.stopAllRTMPBroadcasts = async () => {
|
|
11490
|
+
return this.streamClient.post(`${this.streamClientBasePath}/rtmp_broadcasts/stop`);
|
|
11491
|
+
};
|
|
11492
|
+
/**
|
|
11493
|
+
* Stops the RTMP-out broadcasting of the call specified by it's name.
|
|
11494
|
+
*/
|
|
11495
|
+
this.stopRTMPBroadcast = async (name) => {
|
|
11496
|
+
return this.streamClient.post(`${this.streamClientBasePath}/rtmp_broadcasts/${name}/stop`);
|
|
11497
|
+
};
|
|
11386
11498
|
/**
|
|
11387
11499
|
* Updates the call settings or custom data.
|
|
11388
11500
|
*
|
|
@@ -12863,7 +12975,7 @@ class StreamClient {
|
|
|
12863
12975
|
return await this.wsConnection.connect(this.defaultWSTimeout);
|
|
12864
12976
|
};
|
|
12865
12977
|
this.getUserAgent = () => {
|
|
12866
|
-
const version = "1.
|
|
12978
|
+
const version = "1.16.0";
|
|
12867
12979
|
return (this.userAgent ||
|
|
12868
12980
|
`stream-video-javascript-client-${this.node ? 'node' : 'browser'}-${version}`);
|
|
12869
12981
|
};
|
|
@@ -13372,5 +13484,5 @@ class StreamVideoClient {
|
|
|
13372
13484
|
}
|
|
13373
13485
|
StreamVideoClient._instanceMap = new Map();
|
|
13374
13486
|
|
|
13375
|
-
export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum,
|
|
13487
|
+
export { AudioSettingsRequestDefaultDeviceEnum, AudioSettingsResponseDefaultDeviceEnum, browsers as Browsers, Call, CallState, CallType, CallTypes, CallingState, CameraManager, CameraManagerState, CreateDeviceRequestPushProviderEnum, DebounceType, DynascaleManager, ErrorFromResponse, InputMediaDeviceManager, InputMediaDeviceManagerState, LayoutSettingsRequestNameEnum, MicrophoneManager, MicrophoneManagerState, NoiseCancellationSettingsModeEnum, OwnCapability, RTMPBroadcastRequestQualityEnum, RTMPSettingsRequestQualityEnum, RecordSettingsRequestModeEnum, RecordSettingsRequestQualityEnum, rxUtils as RxUtils, ScreenShareManager, ScreenShareState, events as SfuEvents, models as SfuModels, SpeakerManager, SpeakerState, StreamSfuClient, StreamVideoClient, StreamVideoReadOnlyStateStore, StreamVideoWriteableStateStore, TranscriptionSettingsRequestClosedCaptionModeEnum, TranscriptionSettingsRequestLanguageEnum, TranscriptionSettingsRequestModeEnum, TranscriptionSettingsResponseClosedCaptionModeEnum, TranscriptionSettingsResponseLanguageEnum, TranscriptionSettingsResponseModeEnum, VideoSettingsRequestCameraFacingEnum, VideoSettingsResponseCameraFacingEnum, ViewportTracker, VisibilityState, checkIfAudioOutputChangeSupported, combineComparators, conditional, createSoundDetector, defaultSortPreset, descending, deviceIds$, disposeOfMediaStream, dominantSpeaker, getAudioBrowserPermission, getAudioDevices, getAudioOutputDevices, getAudioStream, getClientDetails, getDeviceInfo, getDeviceState, getLogLevel, getLogger, getOSInfo, getScreenShareStream, getSdkInfo, getVideoBrowserPermission, getVideoDevices, getVideoStream, getWebRTCInfo, hasAudio, hasScreenShare, hasScreenShareAudio, hasVideo, isPinned, livestreamOrAudioRoomSortPreset, logLevels, logToConsole, name, noopComparator, paginatedLayoutSortPreset, pinned, publishingAudio, publishingVideo, reactionType, role, screenSharing, setDeviceInfo, setLogLevel, setLogger, setOSInfo, setPowerState, setSdkInfo, setThermalState, setWebRTCInfo, speakerLayoutSortPreset, speaking };
|
|
13376
13488
|
//# sourceMappingURL=index.browser.es.js.map
|