@stream-io/video-react-native-sdk 1.32.4 → 1.34.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 +34 -0
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js +10 -1
- package/dist/commonjs/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
- package/dist/commonjs/contexts/BackgroundFilters.js +50 -9
- package/dist/commonjs/contexts/BackgroundFilters.js.map +1 -1
- package/dist/commonjs/hooks/index.js +0 -11
- package/dist/commonjs/hooks/index.js.map +1 -1
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js +1 -1
- package/dist/commonjs/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js +2 -3
- package/dist/commonjs/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/commonjs/utils/internal/registerSDKGlobals.js +13 -0
- package/dist/commonjs/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/commonjs/utils/push/android.js +5 -5
- package/dist/commonjs/utils/push/android.js.map +1 -1
- package/dist/commonjs/utils/push/internal/ios.js +3 -3
- package/dist/commonjs/utils/push/internal/ios.js.map +1 -1
- package/dist/commonjs/utils/push/ios.js +2 -2
- package/dist/commonjs/utils/push/ios.js.map +1 -1
- package/dist/commonjs/utils/push/libs/callingx.js +6 -3
- package/dist/commonjs/utils/push/libs/callingx.js.map +1 -1
- package/dist/commonjs/utils/push/setupCallingExpEvents.js +2 -1
- package/dist/commonjs/utils/push/setupCallingExpEvents.js.map +1 -1
- package/dist/commonjs/version.js +1 -1
- package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js +12 -3
- package/dist/module/components/Participant/ParticipantView/ParticipantLabel.js.map +1 -1
- package/dist/module/contexts/BackgroundFilters.js +51 -10
- package/dist/module/contexts/BackgroundFilters.js.map +1 -1
- package/dist/module/hooks/index.js +0 -1
- package/dist/module/hooks/index.js.map +1 -1
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js +1 -1
- package/dist/module/hooks/push/useIosVoipPushEventsSetupEffect.js.map +1 -1
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js +2 -3
- package/dist/module/hooks/useAndroidKeepCallAliveEffect.js.map +1 -1
- package/dist/module/utils/internal/registerSDKGlobals.js +13 -0
- package/dist/module/utils/internal/registerSDKGlobals.js.map +1 -1
- package/dist/module/utils/push/android.js +5 -5
- package/dist/module/utils/push/android.js.map +1 -1
- package/dist/module/utils/push/internal/ios.js +3 -3
- package/dist/module/utils/push/internal/ios.js.map +1 -1
- package/dist/module/utils/push/ios.js +2 -2
- package/dist/module/utils/push/ios.js.map +1 -1
- package/dist/module/utils/push/libs/callingx.js +6 -3
- package/dist/module/utils/push/libs/callingx.js.map +1 -1
- package/dist/module/utils/push/setupCallingExpEvents.js +2 -1
- package/dist/module/utils/push/setupCallingExpEvents.js.map +1 -1
- package/dist/module/version.js +1 -1
- package/dist/typescript/components/Participant/ParticipantView/ParticipantLabel.d.ts.map +1 -1
- package/dist/typescript/contexts/BackgroundFilters.d.ts.map +1 -1
- package/dist/typescript/hooks/index.d.ts +0 -1
- package/dist/typescript/hooks/index.d.ts.map +1 -1
- package/dist/typescript/hooks/useAndroidKeepCallAliveEffect.d.ts.map +1 -1
- package/dist/typescript/utils/StreamVideoRN/types.d.ts +12 -7
- package/dist/typescript/utils/StreamVideoRN/types.d.ts.map +1 -1
- package/dist/typescript/utils/internal/registerSDKGlobals.d.ts.map +1 -1
- package/dist/typescript/utils/push/internal/ios.d.ts.map +1 -1
- package/dist/typescript/utils/push/libs/callingx.d.ts.map +1 -1
- package/dist/typescript/utils/push/setupCallingExpEvents.d.ts.map +1 -1
- package/dist/typescript/version.d.ts +1 -1
- package/expo-config-plugin/dist/index.js +2 -0
- package/expo-config-plugin/dist/withCallResources/index.js +31 -0
- package/expo-config-plugin/dist/withCallResources/withAndroidRingtone.js +92 -0
- package/expo-config-plugin/dist/withCallResources/withIosCallkitIcon.js +97 -0
- package/expo-config-plugin/dist/withCallResources/withIosRingtone.js +81 -0
- package/expo-config-plugin/dist/withiOSInfoPlist.js +3 -1
- package/package.json +7 -7
- package/src/components/Participant/ParticipantView/ParticipantLabel.tsx +24 -2
- package/src/contexts/BackgroundFilters.tsx +55 -9
- package/src/hooks/index.ts +0 -1
- package/src/hooks/push/useIosVoipPushEventsSetupEffect.ts +1 -1
- package/src/hooks/useAndroidKeepCallAliveEffect.ts +2 -4
- package/src/utils/StreamVideoRN/types.ts +12 -7
- package/src/utils/internal/registerSDKGlobals.ts +13 -0
- package/src/utils/push/android.ts +5 -5
- package/src/utils/push/internal/ios.ts +4 -4
- package/src/utils/push/ios.ts +2 -2
- package/src/utils/push/libs/callingx.ts +6 -4
- package/src/utils/push/setupCallingExpEvents.ts +4 -1
- package/src/version.ts +1 -1
- package/dist/commonjs/hooks/useSpeechDetection.js +0 -39
- package/dist/commonjs/hooks/useSpeechDetection.js.map +0 -1
- package/dist/module/hooks/useSpeechDetection.js +0 -34
- package/dist/module/hooks/useSpeechDetection.js.map +0 -1
- package/dist/typescript/hooks/useSpeechDetection.d.ts +0 -8
- package/dist/typescript/hooks/useSpeechDetection.d.ts.map +0 -1
- package/src/hooks/useSpeechDetection.ts +0 -35
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const config_plugins_1 = require("@expo/config-plugins");
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const SUPPORTED_EXTENSIONS = ['.caf', '.aiff', '.m4a', '.wav'];
|
|
40
|
+
const withIosRingtone = (config, props) => {
|
|
41
|
+
if (!props?.iosRingtone) {
|
|
42
|
+
return config;
|
|
43
|
+
}
|
|
44
|
+
return (0, config_plugins_1.withXcodeProject)(config, (xCodeConfig) => {
|
|
45
|
+
const projectRoot = xCodeConfig.modRequest.projectRoot;
|
|
46
|
+
const sourcePath = path.resolve(projectRoot, props.iosRingtone);
|
|
47
|
+
if (!fs.existsSync(sourcePath)) {
|
|
48
|
+
throw new Error(`[StreamVideo] iOS ringtone file not found: ${sourcePath}. ` +
|
|
49
|
+
`Check that the "iosRingtone" path in your plugin config is correct.`);
|
|
50
|
+
}
|
|
51
|
+
const ext = path.extname(sourcePath).toLowerCase();
|
|
52
|
+
if (!SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
53
|
+
throw new Error(`[StreamVideo] Invalid iOS ringtone format "${ext}". ` +
|
|
54
|
+
`Supported formats: ${SUPPORTED_EXTENSIONS.join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
const fileName = path.basename(sourcePath);
|
|
57
|
+
const appName = xCodeConfig.modRequest.projectName;
|
|
58
|
+
const destDir = path.join(xCodeConfig.modRequest.platformProjectRoot, appName);
|
|
59
|
+
const destPath = path.join(destDir, fileName);
|
|
60
|
+
// Path relative to the ios/ directory — Xcode needs this to locate the file
|
|
61
|
+
const projectFilePath = path.join(appName, fileName);
|
|
62
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
63
|
+
fs.copyFileSync(sourcePath, destPath);
|
|
64
|
+
const proj = xCodeConfig.modResults;
|
|
65
|
+
if (!proj.hasFile(fileName)) {
|
|
66
|
+
// Find the main app group by name (Expo projects don't have a "Resources" group,
|
|
67
|
+
// so we can't use addResourceFile which crashes on correctForResourcesPath)
|
|
68
|
+
const appGroupKey = proj.findPBXGroupKey({ name: appName });
|
|
69
|
+
const file = proj.addFile(projectFilePath, appGroupKey, {
|
|
70
|
+
target: proj.getFirstTarget().uuid,
|
|
71
|
+
});
|
|
72
|
+
if (file) {
|
|
73
|
+
file.uuid = proj.generateUuid();
|
|
74
|
+
proj.addToPbxBuildFileSection(file);
|
|
75
|
+
proj.addToPbxResourcesBuildPhase(file);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return xCodeConfig;
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
exports.default = withIosRingtone;
|
|
@@ -12,8 +12,10 @@ const withStreamVideoReactNativeSDKiOSInfoPList = (configuration, props) => {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
addBackgroundMode('audio');
|
|
15
|
-
if (props?.ringing) {
|
|
15
|
+
if (props?.ringing || props?.iosKeepCallAlive) {
|
|
16
16
|
addBackgroundMode('voip');
|
|
17
|
+
}
|
|
18
|
+
if (props?.ringing) {
|
|
17
19
|
addBackgroundMode('fetch');
|
|
18
20
|
addBackgroundMode('processing');
|
|
19
21
|
config.modResults['BGTaskSchedulerPermittedIdentifiers'] = [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-native-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
4
4
|
"description": "Stream Video SDK for React Native",
|
|
5
5
|
"author": "https://getstream.io",
|
|
6
6
|
"homepage": "https://getstream.io/video/docs/react-native/",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"!**/.*"
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@stream-io/video-client": "1.
|
|
54
|
-
"@stream-io/video-react-bindings": "1.
|
|
53
|
+
"@stream-io/video-client": "1.49.0",
|
|
54
|
+
"@stream-io/video-react-bindings": "1.15.1",
|
|
55
55
|
"intl-pluralrules": "2.0.1",
|
|
56
56
|
"react-native-url-polyfill": "^3.0.0",
|
|
57
57
|
"rxjs": "~7.8.2",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@react-native-firebase/messaging": ">=17.5.0",
|
|
66
66
|
"@stream-io/noise-cancellation-react-native": ">=0.1.0",
|
|
67
67
|
"@stream-io/react-native-callingx": ">=0.1.0",
|
|
68
|
-
"@stream-io/react-native-webrtc": ">=137.
|
|
68
|
+
"@stream-io/react-native-webrtc": ">=137.2.0",
|
|
69
69
|
"@stream-io/video-filters-react-native": ">=0.1.0",
|
|
70
70
|
"expo": ">=47.0.0",
|
|
71
71
|
"expo-build-properties": "*",
|
|
@@ -126,9 +126,9 @@
|
|
|
126
126
|
"@react-native-firebase/messaging": "^23.4.0",
|
|
127
127
|
"@react-native/babel-preset": "^0.81.5",
|
|
128
128
|
"@stream-io/noise-cancellation-react-native": "^0.7.0",
|
|
129
|
-
"@stream-io/react-native-callingx": "^0.
|
|
130
|
-
"@stream-io/react-native-webrtc": "137.
|
|
131
|
-
"@stream-io/video-filters-react-native": "^0.12.
|
|
129
|
+
"@stream-io/react-native-callingx": "^0.2.0",
|
|
130
|
+
"@stream-io/react-native-webrtc": "137.2.0",
|
|
131
|
+
"@stream-io/video-filters-react-native": "^0.12.2",
|
|
132
132
|
"@testing-library/jest-native": "^5.4.3",
|
|
133
133
|
"@testing-library/react-native": "13.3.3",
|
|
134
134
|
"@tsconfig/node18": "^18.2.4",
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Pressable,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
Text,
|
|
6
|
+
View,
|
|
7
|
+
ActivityIndicator,
|
|
8
|
+
} from 'react-native';
|
|
3
9
|
import {
|
|
4
10
|
BadNetwork,
|
|
5
11
|
MicOff,
|
|
@@ -7,7 +13,11 @@ import {
|
|
|
7
13
|
ScreenShareIndicator,
|
|
8
14
|
VideoSlash,
|
|
9
15
|
} from '../../../icons';
|
|
10
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
useCall,
|
|
18
|
+
useI18n,
|
|
19
|
+
useIsAudioConnecting,
|
|
20
|
+
} from '@stream-io/video-react-bindings';
|
|
11
21
|
import { ComponentTestIds } from '../../../constants/TestIds';
|
|
12
22
|
import { type ParticipantViewProps } from './ParticipantView';
|
|
13
23
|
import { Z_INDEX } from '../../../constants';
|
|
@@ -55,6 +65,7 @@ export const ParticipantLabel = ({
|
|
|
55
65
|
const isAudioMuted = !hasAudio(participant);
|
|
56
66
|
const isVideoMuted = !hasVideo(participant);
|
|
57
67
|
const isTrackPaused = trackType && hasPausedTrack(participant, trackType);
|
|
68
|
+
const isAudioConnecting = useIsAudioConnecting(participant);
|
|
58
69
|
|
|
59
70
|
if (trackType === 'screenShareTrack') {
|
|
60
71
|
const screenShareText = isLocalParticipant
|
|
@@ -104,6 +115,13 @@ export const ParticipantLabel = ({
|
|
|
104
115
|
]}
|
|
105
116
|
>
|
|
106
117
|
<View style={styles.wrapper}>
|
|
118
|
+
{isAudioConnecting && (
|
|
119
|
+
<ActivityIndicator
|
|
120
|
+
size="small"
|
|
121
|
+
color={colors.iconPrimary}
|
|
122
|
+
style={styles.audioConnectingIndicator}
|
|
123
|
+
/>
|
|
124
|
+
)}
|
|
107
125
|
<Text style={[styles.userNameLabel, userNameLabel]} numberOfLines={1}>
|
|
108
126
|
{participantLabel}
|
|
109
127
|
</Text>
|
|
@@ -174,6 +192,10 @@ const useStyles = () => {
|
|
|
174
192
|
fontWeight: '400',
|
|
175
193
|
color: theme.colors.textPrimary,
|
|
176
194
|
},
|
|
195
|
+
audioConnectingIndicator: {
|
|
196
|
+
marginRight: theme.variants.spacingSizes.sm,
|
|
197
|
+
justifyContent: 'center',
|
|
198
|
+
},
|
|
177
199
|
screenShareIconContainer: {
|
|
178
200
|
marginRight: theme.variants.spacingSizes.sm,
|
|
179
201
|
justifyContent: 'center',
|
|
@@ -2,6 +2,7 @@ import React, {
|
|
|
2
2
|
type PropsWithChildren,
|
|
3
3
|
useCallback,
|
|
4
4
|
useContext,
|
|
5
|
+
useEffect,
|
|
5
6
|
useMemo,
|
|
6
7
|
useRef,
|
|
7
8
|
useState,
|
|
@@ -76,6 +77,10 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
76
77
|
const isBackgroundBlurRegisteredRef = useRef(false);
|
|
77
78
|
const isVideoBlurRegisteredRef = useRef(false);
|
|
78
79
|
const registeredImageFiltersSetRef = useRef(new Set<string>());
|
|
80
|
+
// The currently applied native filter name. Used to reapply on track
|
|
81
|
+
// replacement, and as a staleness signal so a later apply/disable can
|
|
82
|
+
// invalidate an in-flight apply() call.
|
|
83
|
+
const lastAppliedFilterNameRef = useRef<string | null>(null);
|
|
79
84
|
|
|
80
85
|
const [currentBackgroundFilter, setCurrentBackgroundFilter] =
|
|
81
86
|
useState<CurrentBackgroundFilter>();
|
|
@@ -85,16 +90,19 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
85
90
|
if (!isSupported) {
|
|
86
91
|
return;
|
|
87
92
|
}
|
|
88
|
-
if (!isBackgroundBlurRegisteredRef.current) {
|
|
89
|
-
await videoFiltersModule?.registerBackgroundBlurVideoFilters();
|
|
90
|
-
isBackgroundBlurRegisteredRef.current = true;
|
|
91
|
-
}
|
|
92
93
|
let filterName = 'BackgroundBlurMedium';
|
|
93
94
|
if (blurIntensity === 'heavy') {
|
|
94
95
|
filterName = 'BackgroundBlurHeavy';
|
|
95
96
|
} else if (blurIntensity === 'light') {
|
|
96
97
|
filterName = 'BackgroundBlurLight';
|
|
97
98
|
}
|
|
99
|
+
// Set before awaiting so a later apply/disable can mark this call stale.
|
|
100
|
+
lastAppliedFilterNameRef.current = filterName;
|
|
101
|
+
if (!isBackgroundBlurRegisteredRef.current) {
|
|
102
|
+
await videoFiltersModule?.registerBackgroundBlurVideoFilters();
|
|
103
|
+
if (lastAppliedFilterNameRef.current !== filterName) return;
|
|
104
|
+
isBackgroundBlurRegisteredRef.current = true;
|
|
105
|
+
}
|
|
98
106
|
call?.tracer.trace('backgroundFilters.apply', filterName);
|
|
99
107
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
100
108
|
?.getVideoTracks()
|
|
@@ -111,16 +119,18 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
111
119
|
if (!isSupported) {
|
|
112
120
|
return;
|
|
113
121
|
}
|
|
114
|
-
if (!isVideoBlurRegisteredRef.current) {
|
|
115
|
-
await videoFiltersModule?.registerBlurVideoFilters();
|
|
116
|
-
isVideoBlurRegisteredRef.current = true;
|
|
117
|
-
}
|
|
118
122
|
let filterName = 'BlurMedium';
|
|
119
123
|
if (blurIntensity === 'heavy') {
|
|
120
124
|
filterName = 'BlurHeavy';
|
|
121
125
|
} else if (blurIntensity === 'light') {
|
|
122
126
|
filterName = 'BlurLight';
|
|
123
127
|
}
|
|
128
|
+
lastAppliedFilterNameRef.current = filterName;
|
|
129
|
+
if (!isVideoBlurRegisteredRef.current) {
|
|
130
|
+
await videoFiltersModule?.registerBlurVideoFilters();
|
|
131
|
+
if (lastAppliedFilterNameRef.current !== filterName) return;
|
|
132
|
+
isVideoBlurRegisteredRef.current = true;
|
|
133
|
+
}
|
|
124
134
|
call?.tracer.trace('videoFilters.apply', filterName);
|
|
125
135
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
126
136
|
?.getVideoTracks()
|
|
@@ -139,12 +149,14 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
139
149
|
}
|
|
140
150
|
const source = Image.resolveAssetSource(imageSource);
|
|
141
151
|
const imageUri = source.uri;
|
|
152
|
+
const filterName = `VirtualBackground-${imageUri}`;
|
|
153
|
+
lastAppliedFilterNameRef.current = filterName;
|
|
142
154
|
const registeredImageFiltersSet = registeredImageFiltersSetRef.current;
|
|
143
155
|
if (!registeredImageFiltersSet.has(imageUri)) {
|
|
144
156
|
await videoFiltersModule?.registerVirtualBackgroundFilter(imageSource);
|
|
157
|
+
if (lastAppliedFilterNameRef.current !== filterName) return;
|
|
145
158
|
registeredImageFiltersSetRef.current.add(imageUri);
|
|
146
159
|
}
|
|
147
|
-
const filterName = `VirtualBackground-${imageUri}`;
|
|
148
160
|
call?.tracer.trace('backgroundFilters.apply', filterName);
|
|
149
161
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
150
162
|
?.getVideoTracks()
|
|
@@ -161,6 +173,8 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
161
173
|
return;
|
|
162
174
|
}
|
|
163
175
|
call?.tracer.trace('backgroundFilters.disableAll', null);
|
|
176
|
+
// Clearing the ref invalidates any in-flight apply — its stale check will bail.
|
|
177
|
+
lastAppliedFilterNameRef.current = null;
|
|
164
178
|
(call?.camera.state.mediaStream as MediaStream | undefined)
|
|
165
179
|
?.getVideoTracks()
|
|
166
180
|
.forEach((track) => {
|
|
@@ -169,6 +183,38 @@ export const BackgroundFiltersProvider = ({ children }: PropsWithChildren) => {
|
|
|
169
183
|
setCurrentBackgroundFilter(undefined);
|
|
170
184
|
}, [call]);
|
|
171
185
|
|
|
186
|
+
// Reapplies the filter on track replacement (flip, enable-after-disable).
|
|
187
|
+
// Releases native filter state on unmount / call change.
|
|
188
|
+
useEffect(() => {
|
|
189
|
+
if (!call || !isSupported) return;
|
|
190
|
+
const registeredImageFiltersSet = registeredImageFiltersSetRef.current;
|
|
191
|
+
const subscription = call.camera.state.mediaStream$.subscribe(() => {
|
|
192
|
+
const name = lastAppliedFilterNameRef.current;
|
|
193
|
+
if (!name) return;
|
|
194
|
+
(call.camera.state.mediaStream as MediaStream | undefined)
|
|
195
|
+
?.getVideoTracks()
|
|
196
|
+
.forEach((track) => {
|
|
197
|
+
track._setVideoEffect(name);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
return () => {
|
|
201
|
+
subscription.unsubscribe();
|
|
202
|
+
(call.camera.state.mediaStream as MediaStream | undefined)
|
|
203
|
+
?.getVideoTracks()
|
|
204
|
+
.forEach((track) => {
|
|
205
|
+
track._setVideoEffect(null);
|
|
206
|
+
});
|
|
207
|
+
// Drop native processor refs so they can be deallocated. Otherwise the
|
|
208
|
+
// ProcessorProvider registry holds them for the app's lifetime.
|
|
209
|
+
videoFiltersModule?.unregisterAllFilters?.().catch(() => {});
|
|
210
|
+
lastAppliedFilterNameRef.current = null;
|
|
211
|
+
isBackgroundBlurRegisteredRef.current = false;
|
|
212
|
+
isVideoBlurRegisteredRef.current = false;
|
|
213
|
+
registeredImageFiltersSet.clear();
|
|
214
|
+
setCurrentBackgroundFilter(undefined);
|
|
215
|
+
};
|
|
216
|
+
}, [call]);
|
|
217
|
+
|
|
172
218
|
const value = useMemo(
|
|
173
219
|
() => ({
|
|
174
220
|
currentBackgroundFilter,
|
package/src/hooks/index.ts
CHANGED
|
@@ -88,7 +88,7 @@ export const useIosVoipPushEventsSetupEffect = () => {
|
|
|
88
88
|
|
|
89
89
|
useEffect(() => {
|
|
90
90
|
const pushConfig = StreamVideoRN.getConfig().push;
|
|
91
|
-
const pushProviderName = pushConfig?.ios
|
|
91
|
+
const pushProviderName = pushConfig?.ios?.pushProviderName;
|
|
92
92
|
const callingx = getCallingxLibIfAvailable();
|
|
93
93
|
|
|
94
94
|
if (Platform.OS !== 'ios' || !client || !pushProviderName || !callingx) {
|
|
@@ -53,7 +53,7 @@ async function startForegroundService(call_cid: string) {
|
|
|
53
53
|
const foregroundServiceConfig = videoConfig.foregroundService;
|
|
54
54
|
const notificationTexts = foregroundServiceConfig.android.notificationTexts;
|
|
55
55
|
const channel = foregroundServiceConfig.android.channel;
|
|
56
|
-
const smallIconName = videoConfig.push?.android
|
|
56
|
+
const smallIconName = videoConfig.push?.android?.smallIcon;
|
|
57
57
|
|
|
58
58
|
// NOTE: we use requestAnimationFrame to ensure that the foreground service is started after all the current UI operations are done
|
|
59
59
|
// this is a workaround for the crash - android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground()
|
|
@@ -89,13 +89,11 @@ export const useAndroidKeepCallAliveEffect = () => {
|
|
|
89
89
|
const { useCallCallingState } = useCallStateHooks();
|
|
90
90
|
const callingState = useCallCallingState();
|
|
91
91
|
|
|
92
|
-
const isOutgoingCall =
|
|
93
|
-
callingState === CallingState.RINGING && call?.isCreatedByMe;
|
|
94
92
|
const isCallJoined = callingState === CallingState.JOINED;
|
|
95
93
|
const isRingingCall = call?.ringing;
|
|
96
94
|
|
|
97
95
|
const shouldStartForegroundService =
|
|
98
|
-
!foregroundServiceStartedRef.current &&
|
|
96
|
+
!foregroundServiceStartedRef.current && isCallJoined;
|
|
99
97
|
|
|
100
98
|
useEffect((): (() => void) | undefined => {
|
|
101
99
|
if (Platform.OS === 'ios' || !activeCallCid) {
|
|
@@ -37,7 +37,7 @@ export type StreamVideoConfig = {
|
|
|
37
37
|
*/
|
|
38
38
|
publishOptions?: ClientPublishOptions;
|
|
39
39
|
|
|
40
|
-
ios
|
|
40
|
+
ios?: {
|
|
41
41
|
/**
|
|
42
42
|
* The name for the alias of push provider used for iOS
|
|
43
43
|
* Pass undefined if you will not be using stream's push notifications but still want to use the functionality of the SDK
|
|
@@ -65,8 +65,13 @@ export type StreamVideoConfig = {
|
|
|
65
65
|
* @default 60000 (1 minute)
|
|
66
66
|
*/
|
|
67
67
|
displayCallTimeout?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Whether to enable ongoing calls.
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
enableOngoingCalls?: boolean;
|
|
68
73
|
};
|
|
69
|
-
android
|
|
74
|
+
android?: {
|
|
70
75
|
/**
|
|
71
76
|
* The small icon to be used for push notifications for Android
|
|
72
77
|
* Reference the name created (Optional, defaults to 'ic_launcher')
|
|
@@ -145,12 +150,12 @@ export type StreamVideoConfig = {
|
|
|
145
150
|
) => string;
|
|
146
151
|
getBody: (type: NonRingingPushEvent, createdUserName: string) => string;
|
|
147
152
|
};
|
|
153
|
+
/**
|
|
154
|
+
* Whether to enable ongoing calls.
|
|
155
|
+
* @default false
|
|
156
|
+
*/
|
|
157
|
+
enableOngoingCalls?: boolean;
|
|
148
158
|
};
|
|
149
|
-
/**
|
|
150
|
-
* Whether to enable ongoing calls.
|
|
151
|
-
* @default false
|
|
152
|
-
*/
|
|
153
|
-
enableOngoingCalls?: boolean;
|
|
154
159
|
/**
|
|
155
160
|
* Whether to reject calls when the user is busy.
|
|
156
161
|
* @default false
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { StreamRNVideoSDKGlobals } from '@stream-io/video-client';
|
|
2
2
|
import { NativeModules, PermissionsAndroid, Platform } from 'react-native';
|
|
3
|
+
import { audioDeviceModuleEvents } from '@stream-io/react-native-webrtc';
|
|
3
4
|
import { getCallingxLibIfAvailable } from '../push/libs/callingx';
|
|
4
5
|
import {
|
|
5
6
|
endCallingxCall,
|
|
@@ -85,6 +86,18 @@ const streamRNVideoSDKGlobals: StreamRNVideoSDKGlobals = {
|
|
|
85
86
|
);
|
|
86
87
|
},
|
|
87
88
|
},
|
|
89
|
+
nativeEvents: {
|
|
90
|
+
speechActivity: {
|
|
91
|
+
subscribe(cb) {
|
|
92
|
+
const subscription = audioDeviceModuleEvents.addSpeechActivityListener(
|
|
93
|
+
(data) => {
|
|
94
|
+
cb({ isSoundDetected: data.event === 'started' });
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
return () => subscription.remove();
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
},
|
|
88
101
|
};
|
|
89
102
|
|
|
90
103
|
// Note: The global type declaration for `streamRNVideoSDK` is defined in
|
|
@@ -40,7 +40,7 @@ export async function initAndroidPushToken(
|
|
|
40
40
|
pushConfig: PushConfig,
|
|
41
41
|
setUnsubscribeListener: (unsubscribe: () => void) => void,
|
|
42
42
|
) {
|
|
43
|
-
if (Platform.OS !== 'android' || !pushConfig.android
|
|
43
|
+
if (Platform.OS !== 'android' || !pushConfig.android?.pushProviderName) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
|
46
46
|
const logger = videoLoggerSystem.getLogger('initAndroidPushToken');
|
|
@@ -69,7 +69,7 @@ export async function initAndroidPushToken(
|
|
|
69
69
|
logger.warn('Failed to remove firebase token from stream', err);
|
|
70
70
|
}
|
|
71
71
|
});
|
|
72
|
-
const push_provider_name = pushConfig.android
|
|
72
|
+
const push_provider_name = pushConfig.android?.pushProviderName;
|
|
73
73
|
logger.debug(`sending firebase token: ${token} for userId: ${userId}`);
|
|
74
74
|
await client.addDevice(token, 'firebase', push_provider_name);
|
|
75
75
|
};
|
|
@@ -336,9 +336,9 @@ export const firebaseDataHandler = async (
|
|
|
336
336
|
}
|
|
337
337
|
|
|
338
338
|
// the other types are call.live_started and call.notification
|
|
339
|
-
const callChannel = pushConfig.android
|
|
339
|
+
const callChannel = pushConfig.android?.callChannel;
|
|
340
340
|
const callNotificationTextGetters =
|
|
341
|
-
pushConfig.android
|
|
341
|
+
pushConfig.android?.callNotificationTextGetters;
|
|
342
342
|
if (!callChannel || !callNotificationTextGetters) {
|
|
343
343
|
logger.debug(
|
|
344
344
|
"Can't show call notification as either or both callChannel and callNotificationTextGetters is not provided",
|
|
@@ -364,7 +364,7 @@ export const firebaseDataHandler = async (
|
|
|
364
364
|
data,
|
|
365
365
|
android: {
|
|
366
366
|
sound: callChannel.sound,
|
|
367
|
-
smallIcon: pushConfig.android
|
|
367
|
+
smallIcon: pushConfig.android?.smallIcon,
|
|
368
368
|
vibrationPattern: callChannel.vibrationPattern,
|
|
369
369
|
channelId,
|
|
370
370
|
importance: 4, // high importance
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { videoLoggerSystem } from '@stream-io/video-client';
|
|
1
2
|
import { Platform } from 'react-native';
|
|
2
|
-
import { pushUnsubscriptionCallbacks } from './constants';
|
|
3
|
-
import { canListenToWS, shouldCallBeClosed } from './utils';
|
|
4
3
|
import { StreamVideoConfig } from '../../StreamVideoRN/types';
|
|
5
|
-
import { videoLoggerSystem } from '@stream-io/video-client';
|
|
6
4
|
import { getCallingxLib } from '../libs/callingx';
|
|
5
|
+
import { pushUnsubscriptionCallbacks } from './constants';
|
|
6
|
+
import { canListenToWS, shouldCallBeClosed } from './utils';
|
|
7
7
|
|
|
8
8
|
export const onVoipNotificationReceived = async (
|
|
9
9
|
notification: any,
|
|
@@ -43,7 +43,7 @@ export const onVoipNotificationReceived = async (
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const call_cid = notification?.stream?.call_cid;
|
|
46
|
-
if (!call_cid || Platform.OS !== 'ios' || !pushConfig.ios
|
|
46
|
+
if (!call_cid || Platform.OS !== 'ios' || !pushConfig.ios?.pushProviderName) {
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
49
|
|
package/src/utils/push/ios.ts
CHANGED
|
@@ -127,7 +127,7 @@ export async function initIosNonVoipToken(
|
|
|
127
127
|
) {
|
|
128
128
|
if (
|
|
129
129
|
Platform.OS !== 'ios' ||
|
|
130
|
-
!pushConfig.ios
|
|
130
|
+
!pushConfig.ios?.pushProviderName ||
|
|
131
131
|
!pushConfig.onTapNonRingingCallNotification
|
|
132
132
|
) {
|
|
133
133
|
return;
|
|
@@ -155,7 +155,7 @@ export async function initIosNonVoipToken(
|
|
|
155
155
|
);
|
|
156
156
|
}
|
|
157
157
|
});
|
|
158
|
-
const push_provider_name = pushConfig.ios
|
|
158
|
+
const push_provider_name = pushConfig.ios?.pushProviderName;
|
|
159
159
|
logger.debug('Add device token to stream', token);
|
|
160
160
|
await client
|
|
161
161
|
.addDevice(token, 'apn', push_provider_name)
|
|
@@ -49,6 +49,9 @@ export function extractCallingExpOptions(
|
|
|
49
49
|
if (pushConfig.ios.displayCallTimeout !== undefined) {
|
|
50
50
|
iosOptions.displayCallTimeout = pushConfig.ios.displayCallTimeout;
|
|
51
51
|
}
|
|
52
|
+
if (pushConfig.ios.enableOngoingCalls !== undefined) {
|
|
53
|
+
iosOptions.enableOngoingCalls = pushConfig.ios.enableOngoingCalls;
|
|
54
|
+
}
|
|
52
55
|
|
|
53
56
|
if (Object.keys(iosOptions).length > 0) {
|
|
54
57
|
callingExpOptions.ios = iosOptions;
|
|
@@ -66,6 +69,9 @@ export function extractCallingExpOptions(
|
|
|
66
69
|
if (pushConfig.android.notificationTexts) {
|
|
67
70
|
androidOptions.notificationTexts = pushConfig.android.notificationTexts;
|
|
68
71
|
}
|
|
72
|
+
if (pushConfig.android.enableOngoingCalls !== undefined) {
|
|
73
|
+
androidOptions.enableOngoingCalls = pushConfig.android.enableOngoingCalls;
|
|
74
|
+
}
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
if (foregroundServiceConfig.android.channel) {
|
|
@@ -81,9 +87,5 @@ export function extractCallingExpOptions(
|
|
|
81
87
|
pushConfig.shouldRejectCallWhenBusy;
|
|
82
88
|
}
|
|
83
89
|
|
|
84
|
-
if (pushConfig?.enableOngoingCalls !== undefined) {
|
|
85
|
-
callingExpOptions.enableOngoingCalls = pushConfig?.enableOngoingCalls;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
90
|
return callingExpOptions;
|
|
89
91
|
}
|
|
@@ -23,8 +23,11 @@ export function setupCallingExpEvents(pushConfig: NonNullable<PushConfig>) {
|
|
|
23
23
|
const hasPushProvider =
|
|
24
24
|
(Platform.OS === 'android' && pushConfig.android?.pushProviderName) ||
|
|
25
25
|
(Platform.OS === 'ios' && pushConfig.ios?.pushProviderName);
|
|
26
|
+
const hasOngoingCalls =
|
|
27
|
+
(Platform.OS === 'android' && pushConfig.android?.enableOngoingCalls) ||
|
|
28
|
+
(Platform.OS === 'ios' && pushConfig.ios?.enableOngoingCalls);
|
|
26
29
|
|
|
27
|
-
if (!hasPushProvider) {
|
|
30
|
+
if (!hasPushProvider && !hasOngoingCalls) {
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
30
33
|
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '1.34.0';
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useSpeechDetection = useSpeechDetection;
|
|
7
|
-
var _react = require("react");
|
|
8
|
-
var _videoClient = require("@stream-io/video-client");
|
|
9
|
-
var _videoReactBindings = require("@stream-io/video-react-bindings");
|
|
10
|
-
/**
|
|
11
|
-
* Hook that provides speech detection info using the RNSpeechDetector.
|
|
12
|
-
*
|
|
13
|
-
* @returns An object containing the current audio level (0 - 1) and whether sound is detected.
|
|
14
|
-
*/
|
|
15
|
-
function useSpeechDetection() {
|
|
16
|
-
const [audioState, setAudioState] = (0, _react.useState)({
|
|
17
|
-
isSoundDetected: false,
|
|
18
|
-
audioLevel: 0
|
|
19
|
-
});
|
|
20
|
-
const {
|
|
21
|
-
useMicrophoneState
|
|
22
|
-
} = (0, _videoReactBindings.useCallStateHooks)();
|
|
23
|
-
const {
|
|
24
|
-
isEnabled,
|
|
25
|
-
mediaStream
|
|
26
|
-
} = useMicrophoneState();
|
|
27
|
-
(0, _react.useEffect)(() => {
|
|
28
|
-
if (!isEnabled) return;
|
|
29
|
-
const detector = new _videoClient.RNSpeechDetector(mediaStream);
|
|
30
|
-
const start = detector.start(state => {
|
|
31
|
-
setAudioState(state);
|
|
32
|
-
});
|
|
33
|
-
return () => {
|
|
34
|
-
start.then(stop => stop());
|
|
35
|
-
};
|
|
36
|
-
}, [mediaStream, isEnabled]);
|
|
37
|
-
return audioState;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=useSpeechDetection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_videoClient","_videoReactBindings","useSpeechDetection","audioState","setAudioState","useState","isSoundDetected","audioLevel","useMicrophoneState","useCallStateHooks","isEnabled","mediaStream","useEffect","detector","RNSpeechDetector","start","state","then","stop"],"sourceRoot":"../../../src","sources":["hooks/useSpeechDetection.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAIA,IAAAE,mBAAA,GAAAF,OAAA;AAEA;AACA;AACA;AACA;AACA;AACO,SAASG,kBAAkBA,CAAA,EAAG;EACnC,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAG,IAAAC,eAAQ,EAAqB;IAC/DC,eAAe,EAAE,KAAK;IACtBC,UAAU,EAAE;EACd,CAAC,CAAC;EACF,MAAM;IAAEC;EAAmB,CAAC,GAAG,IAAAC,qCAAiB,EAAC,CAAC;EAClD,MAAM;IAAEC,SAAS;IAAEC;EAAY,CAAC,GAAGH,kBAAkB,CAAC,CAAC;EAEvD,IAAAI,gBAAS,EAAC,MAAM;IACd,IAAI,CAACF,SAAS,EAAE;IAEhB,MAAMG,QAAQ,GAAG,IAAIC,6BAAgB,CAACH,WAAW,CAAC;IAClD,MAAMI,KAAK,GAAGF,QAAQ,CAACE,KAAK,CAAEC,KAAyB,IAAK;MAC1DZ,aAAa,CAACY,KAAK,CAAC;IACtB,CAAC,CAAC;IAEF,OAAO,MAAM;MACXD,KAAK,CAACE,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAAC,CAAC,CAAC;IAC9B,CAAC;EACH,CAAC,EAAE,CAACP,WAAW,EAAED,SAAS,CAAC,CAAC;EAE5B,OAAOP,UAAU;AACnB","ignoreList":[]}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
import { RNSpeechDetector } from '@stream-io/video-client';
|
|
3
|
-
import { useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Hook that provides speech detection info using the RNSpeechDetector.
|
|
7
|
-
*
|
|
8
|
-
* @returns An object containing the current audio level (0 - 1) and whether sound is detected.
|
|
9
|
-
*/
|
|
10
|
-
export function useSpeechDetection() {
|
|
11
|
-
const [audioState, setAudioState] = useState({
|
|
12
|
-
isSoundDetected: false,
|
|
13
|
-
audioLevel: 0
|
|
14
|
-
});
|
|
15
|
-
const {
|
|
16
|
-
useMicrophoneState
|
|
17
|
-
} = useCallStateHooks();
|
|
18
|
-
const {
|
|
19
|
-
isEnabled,
|
|
20
|
-
mediaStream
|
|
21
|
-
} = useMicrophoneState();
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
if (!isEnabled) return;
|
|
24
|
-
const detector = new RNSpeechDetector(mediaStream);
|
|
25
|
-
const start = detector.start(state => {
|
|
26
|
-
setAudioState(state);
|
|
27
|
-
});
|
|
28
|
-
return () => {
|
|
29
|
-
start.then(stop => stop());
|
|
30
|
-
};
|
|
31
|
-
}, [mediaStream, isEnabled]);
|
|
32
|
-
return audioState;
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=useSpeechDetection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useEffect","useState","RNSpeechDetector","useCallStateHooks","useSpeechDetection","audioState","setAudioState","isSoundDetected","audioLevel","useMicrophoneState","isEnabled","mediaStream","detector","start","state","then","stop"],"sourceRoot":"../../../src","sources":["hooks/useSpeechDetection.ts"],"mappings":"AAAA,SAASA,SAAS,EAAEC,QAAQ,QAAQ,OAAO;AAC3C,SAEEC,gBAAgB,QACX,yBAAyB;AAChC,SAASC,iBAAiB,QAAQ,iCAAiC;;AAEnE;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,kBAAkBA,CAAA,EAAG;EACnC,MAAM,CAACC,UAAU,EAAEC,aAAa,CAAC,GAAGL,QAAQ,CAAqB;IAC/DM,eAAe,EAAE,KAAK;IACtBC,UAAU,EAAE;EACd,CAAC,CAAC;EACF,MAAM;IAAEC;EAAmB,CAAC,GAAGN,iBAAiB,CAAC,CAAC;EAClD,MAAM;IAAEO,SAAS;IAAEC;EAAY,CAAC,GAAGF,kBAAkB,CAAC,CAAC;EAEvDT,SAAS,CAAC,MAAM;IACd,IAAI,CAACU,SAAS,EAAE;IAEhB,MAAME,QAAQ,GAAG,IAAIV,gBAAgB,CAACS,WAAW,CAAC;IAClD,MAAME,KAAK,GAAGD,QAAQ,CAACC,KAAK,CAAEC,KAAyB,IAAK;MAC1DR,aAAa,CAACQ,KAAK,CAAC;IACtB,CAAC,CAAC;IAEF,OAAO,MAAM;MACXD,KAAK,CAACE,IAAI,CAAEC,IAAI,IAAKA,IAAI,CAAC,CAAC,CAAC;IAC9B,CAAC;EACH,CAAC,EAAE,CAACL,WAAW,EAAED,SAAS,CAAC,CAAC;EAE5B,OAAOL,UAAU;AACnB","ignoreList":[]}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type SoundDetectorState } from '@stream-io/video-client';
|
|
2
|
-
/**
|
|
3
|
-
* Hook that provides speech detection info using the RNSpeechDetector.
|
|
4
|
-
*
|
|
5
|
-
* @returns An object containing the current audio level (0 - 1) and whether sound is detected.
|
|
6
|
-
*/
|
|
7
|
-
export declare function useSpeechDetection(): SoundDetectorState;
|
|
8
|
-
//# sourceMappingURL=useSpeechDetection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useSpeechDetection.d.ts","sourceRoot":"","sources":["../../../src/hooks/useSpeechDetection.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,yBAAyB,CAAC;AAGjC;;;;GAIG;AACH,wBAAgB,kBAAkB,uBAsBjC"}
|