@stream-io/video-react-sdk 0.6.10 → 0.6.12
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 +19 -0
- package/dist/index.cjs.js +74 -8
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +74 -10
- package/dist/index.es.js.map +1 -1
- package/dist/src/components/NoiseCancellation/NoiseCancellationProvider.d.ts +34 -0
- package/dist/src/components/NoiseCancellation/index.d.ts +1 -0
- package/dist/src/components/index.d.ts +1 -0
- package/package.json +4 -3
- package/src/components/BackgroundFilters/BackgroundFilters.tsx +10 -7
- package/src/components/NoiseCancellation/NoiseCancellationProvider.tsx +124 -0
- package/src/components/NoiseCancellation/index.ts +1 -0
- package/src/components/index.ts +1 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
import type { INoiseCancellation } from '@stream-io/audio-filters-web';
|
|
3
|
+
export type NoiseCancellationProviderProps = {
|
|
4
|
+
/**
|
|
5
|
+
* The noise cancellation instance to use.
|
|
6
|
+
*/
|
|
7
|
+
noiseCancellation: INoiseCancellation;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* The Noise Cancellation API.
|
|
11
|
+
*/
|
|
12
|
+
export type NoiseCancellationAPI = {
|
|
13
|
+
/**
|
|
14
|
+
* A boolean providing information whether Noise Cancelling functionalities
|
|
15
|
+
* are supported on this platform and for the current user.
|
|
16
|
+
*/
|
|
17
|
+
isSupported: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Provides information whether Noise Cancellation is active or not.
|
|
20
|
+
*/
|
|
21
|
+
isEnabled: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Allows you to temporary enable or disable the Noise Cancellation filters.
|
|
24
|
+
*
|
|
25
|
+
* @param enabled a boolean or a setter.
|
|
26
|
+
*/
|
|
27
|
+
setEnabled: (enabled: boolean | ((value: boolean) => boolean)) => void;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Exposes the NoiseCancellation API.
|
|
31
|
+
* Throws an error if used outside <NoiseCancellationProvider />.
|
|
32
|
+
*/
|
|
33
|
+
export declare const useNoiseCancellation: () => NoiseCancellationAPI;
|
|
34
|
+
export declare const NoiseCancellationProvider: (props: PropsWithChildren<NoiseCancellationProviderProps>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NoiseCancellationProvider';
|
|
@@ -12,6 +12,7 @@ export * from './DropdownSelect';
|
|
|
12
12
|
export * from './Icon';
|
|
13
13
|
export * from './LoadingIndicator';
|
|
14
14
|
export * from './Menu';
|
|
15
|
+
export * from './NoiseCancellation';
|
|
15
16
|
export * from './Notification';
|
|
16
17
|
export * from './RingingCall';
|
|
17
18
|
export * from './Permissions';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-io/video-react-sdk",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.12",
|
|
4
4
|
"packageManager": "yarn@3.2.4",
|
|
5
5
|
"main": "./dist/index.cjs.js",
|
|
6
6
|
"module": "./dist/index.es.js",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@floating-ui/react": "^0.26.5",
|
|
32
|
-
"@stream-io/video-client": "0.7.
|
|
32
|
+
"@stream-io/video-client": "0.7.8",
|
|
33
33
|
"@stream-io/video-filters-web": "0.1.0",
|
|
34
|
-
"@stream-io/video-react-bindings": "0.4.
|
|
34
|
+
"@stream-io/video-react-bindings": "0.4.19",
|
|
35
35
|
"chart.js": "^4.4.1",
|
|
36
36
|
"clsx": "^2.0.0",
|
|
37
37
|
"react-chartjs-2": "^5.2.0"
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@rollup/plugin-json": "^6.1.0",
|
|
45
45
|
"@rollup/plugin-replace": "^5.0.5",
|
|
46
46
|
"@rollup/plugin-typescript": "^11.1.6",
|
|
47
|
+
"@stream-io/audio-filters-web": "^0.0.1",
|
|
47
48
|
"@stream-io/video-styling": "^1.0.2",
|
|
48
49
|
"react": "^18.2.0",
|
|
49
50
|
"react-dom": "^18.2.0",
|
|
@@ -219,25 +219,28 @@ const BackgroundFilters = (props: { tfLite: TFLite }) => {
|
|
|
219
219
|
const [width, setWidth] = useState(1920);
|
|
220
220
|
const [height, setHeight] = useState(1080);
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
// Holds a ref to the `resolve` function of the returned Promise as part
|
|
223
|
+
// of the `camera.registerFilter()` API. Once the filter is initialized,
|
|
224
|
+
// it should be called with the filtered MediaStream as an argument.
|
|
225
|
+
const signalFilterReadyRef =
|
|
223
226
|
useRef<(value: MediaStream | PromiseLike<MediaStream>) => void>();
|
|
224
227
|
|
|
225
228
|
const [mediaStream, setMediaStream] = useState<MediaStream>();
|
|
226
|
-
const
|
|
229
|
+
const unregister = useRef<Promise<void>>();
|
|
227
230
|
useEffect(() => {
|
|
228
231
|
if (!call || !backgroundFilter) return;
|
|
229
|
-
|
|
232
|
+
const register = (unregister.current || Promise.resolve()).then(() =>
|
|
230
233
|
call.camera.registerFilter(async (ms) => {
|
|
231
234
|
return new Promise<MediaStream>((resolve) => {
|
|
232
235
|
setMediaStream(ms);
|
|
233
|
-
|
|
236
|
+
signalFilterReadyRef.current = resolve;
|
|
234
237
|
});
|
|
235
238
|
}),
|
|
236
239
|
);
|
|
237
240
|
|
|
238
241
|
return () => {
|
|
239
|
-
|
|
240
|
-
.then((
|
|
242
|
+
unregister.current = register
|
|
243
|
+
.then((unregisterFilter) => unregisterFilter())
|
|
241
244
|
.then(() => setMediaStream(undefined))
|
|
242
245
|
.catch((err) => console.error('Failed to unregister filter', err));
|
|
243
246
|
};
|
|
@@ -254,7 +257,7 @@ const BackgroundFilters = (props: { tfLite: TFLite }) => {
|
|
|
254
257
|
setHeight(h);
|
|
255
258
|
}
|
|
256
259
|
|
|
257
|
-
const resolveFilter =
|
|
260
|
+
const resolveFilter = signalFilterReadyRef.current;
|
|
258
261
|
if (!resolveFilter) return;
|
|
259
262
|
const filter = canvasRef.captureStream();
|
|
260
263
|
resolveFilter(filter);
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
PropsWithChildren,
|
|
4
|
+
useContext,
|
|
5
|
+
useEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import {
|
|
10
|
+
NoiseCancellationSettingsModeEnum,
|
|
11
|
+
OwnCapability,
|
|
12
|
+
} from '@stream-io/video-client';
|
|
13
|
+
import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
|
|
14
|
+
import type { INoiseCancellation } from '@stream-io/audio-filters-web';
|
|
15
|
+
|
|
16
|
+
export type NoiseCancellationProviderProps = {
|
|
17
|
+
/**
|
|
18
|
+
* The noise cancellation instance to use.
|
|
19
|
+
*/
|
|
20
|
+
noiseCancellation: INoiseCancellation;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The Noise Cancellation API.
|
|
25
|
+
*/
|
|
26
|
+
export type NoiseCancellationAPI = {
|
|
27
|
+
/**
|
|
28
|
+
* A boolean providing information whether Noise Cancelling functionalities
|
|
29
|
+
* are supported on this platform and for the current user.
|
|
30
|
+
*/
|
|
31
|
+
isSupported: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Provides information whether Noise Cancellation is active or not.
|
|
34
|
+
*/
|
|
35
|
+
isEnabled: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Allows you to temporary enable or disable the Noise Cancellation filters.
|
|
38
|
+
*
|
|
39
|
+
* @param enabled a boolean or a setter.
|
|
40
|
+
*/
|
|
41
|
+
setEnabled: (enabled: boolean | ((value: boolean) => boolean)) => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const NoiseCancellationContext = createContext<NoiseCancellationAPI | null>(
|
|
45
|
+
null,
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Exposes the NoiseCancellation API.
|
|
50
|
+
* Throws an error if used outside <NoiseCancellationProvider />.
|
|
51
|
+
*/
|
|
52
|
+
export const useNoiseCancellation = (): NoiseCancellationAPI => {
|
|
53
|
+
const context = useContext(NoiseCancellationContext);
|
|
54
|
+
if (!context) {
|
|
55
|
+
throw new Error(
|
|
56
|
+
'useNoiseCancellation must be used within a NoiseCancellationProvider',
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
return context;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const NoiseCancellationProvider = (
|
|
63
|
+
props: PropsWithChildren<NoiseCancellationProviderProps>,
|
|
64
|
+
) => {
|
|
65
|
+
const { children, noiseCancellation } = props;
|
|
66
|
+
const call = useCall();
|
|
67
|
+
const { useCallSettings, useHasPermissions } = useCallStateHooks();
|
|
68
|
+
const settings = useCallSettings();
|
|
69
|
+
const noiseCancellationAllowed = !!(
|
|
70
|
+
settings &&
|
|
71
|
+
settings.audio.noise_cancellation &&
|
|
72
|
+
settings.audio.noise_cancellation.mode !==
|
|
73
|
+
NoiseCancellationSettingsModeEnum.DISABLED
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const hasCapability = useHasPermissions(
|
|
77
|
+
OwnCapability.ENABLE_NOISE_CANCELLATION,
|
|
78
|
+
);
|
|
79
|
+
const isSupported =
|
|
80
|
+
hasCapability &&
|
|
81
|
+
noiseCancellationAllowed &&
|
|
82
|
+
noiseCancellation.isSupported();
|
|
83
|
+
|
|
84
|
+
const [isEnabled, setIsEnabled] = useState(false);
|
|
85
|
+
const deinit = useRef<Promise<void>>();
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!call || !isSupported) return;
|
|
88
|
+
const unsubscribe = noiseCancellation.on('change', (v) => setIsEnabled(v));
|
|
89
|
+
const init = (deinit.current || Promise.resolve())
|
|
90
|
+
.then(() => noiseCancellation.init())
|
|
91
|
+
.then(() => call.microphone.enableNoiseCancellation(noiseCancellation))
|
|
92
|
+
.catch((err) => console.error(`Can't initialize noise suppression`, err));
|
|
93
|
+
|
|
94
|
+
return () => {
|
|
95
|
+
deinit.current = init
|
|
96
|
+
.then(() => call.microphone.disableNoiseCancellation())
|
|
97
|
+
.then(() => noiseCancellation.dispose())
|
|
98
|
+
.then(() => unsubscribe());
|
|
99
|
+
};
|
|
100
|
+
}, [call, isSupported, noiseCancellation]);
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<NoiseCancellationContext.Provider
|
|
104
|
+
value={{
|
|
105
|
+
isSupported,
|
|
106
|
+
isEnabled,
|
|
107
|
+
setEnabled: (enabledOrSetter) => {
|
|
108
|
+
if (!noiseCancellation) return;
|
|
109
|
+
const enable =
|
|
110
|
+
typeof enabledOrSetter === 'function'
|
|
111
|
+
? enabledOrSetter(isEnabled)
|
|
112
|
+
: enabledOrSetter;
|
|
113
|
+
if (enable) {
|
|
114
|
+
noiseCancellation.enable();
|
|
115
|
+
} else {
|
|
116
|
+
noiseCancellation.disable();
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
}}
|
|
120
|
+
>
|
|
121
|
+
{children}
|
|
122
|
+
</NoiseCancellationContext.Provider>
|
|
123
|
+
);
|
|
124
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './NoiseCancellationProvider';
|
package/src/components/index.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './DropdownSelect';
|
|
|
12
12
|
export * from './Icon';
|
|
13
13
|
export * from './LoadingIndicator';
|
|
14
14
|
export * from './Menu';
|
|
15
|
+
export * from './NoiseCancellation';
|
|
15
16
|
export * from './Notification';
|
|
16
17
|
export * from './RingingCall';
|
|
17
18
|
export * from './Permissions';
|