用 React Native UIKit 可以在几分钟内搭建一个视频通话应用(点击这里查看更多信息)。本文教给大家的是如何扩展 UIKit 以及如何为视频通话应用添加自定义功能(以 AI 降噪为例)。
前期准备
-
一个声网Agora 开发者账户——(点击这里免费注册)
-
Node.js LTS
-
一个可供测试用的 IOS 或安卓设备
-
了解 React Native 开发的高阶知识
设置
大家可以在 GitHub 上获得本示例的代码,或自行创建 React Native 项目。打开一个终端并执行:
npx react-native init demo --template react-native-template-typescript
cd demo
安装声网Agora React Native SDK 和 UIKit:
npm i react-native-agora agora-rn-uikit
注意:截止 2022 年 3 月 15 日, agora-rn-uikit
的最新版本是 v3.3.0, react-native-agora
的最新版本是 v3.5.1。
如果使用 iOS 设备,要运行 cd ios && pod install
来安装 CocoaPods,还需要配置应用签名和权限。大家可以打开 Xcode 里的 /ios/<projectname>.xcworkspace
文件进行配置。
设置完成后,执行 npm run android
或 npm run ios
,开启服务器,会得到一个基础的 React Native 应用。
搭建视频通话
我们可以通过 UIKit 访问高级组件 <AgoraUIKit>
,用 <AgoraUIKit>
渲染一个完整的视频通话。UIKit blog 对如何使用少量代码定制 UI 和功能进行了深度讲解。<AgoraUIKit>
组件是用更小的组件搭建而成的,我们可以不考虑视频通话逻辑,用这些小组件搭建一个完全自定义的组件。
首先,清除 App.tsx
文件,重新开始:
import React, {useState} from 'react';
import {View} from 'react-native';
const App = () => {
const [inCall, setCall] = useState(true);
return inCall ? (
/* Render Video Call here */
) : (
<View />
);
};
export default App;
创建状态变量 inCall
。当状态变量为 true 时,渲染视频通话,当状态变量为 false 时,暂时渲染空的 <View>
:
import React, {useState} from 'react';
import {View} from 'react-native';
import {RtcConfigure, GridVideo} from 'agora-rn-uikit/Components';
import {PropsContext} from 'agora-rn-uikit/Contexts';
import Controls from './src/Controls';
const App = () => {
const [inCall, setCall] = useState(true);
return inCall ? (
<PropsContext.Provider
value={{
rtcProps: {appId: '<Agora App ID>', channel: 'test'},
callbacks: {EndCall: () => setCall(false)},
}}>
<RtcConfigure>
<GridVideo />
<Controls />
</RtcConfigure>
</PropsContext.Provider>
) : (
<View />
);
};
export default App;
要搭建视频通话,需要从 UIKit 中输入 PropsContext
、RtcConfigure
、和 GridVideo
组件。RtcConfigure
组件处理视频通话逻辑。我们用 PropsContext
封装 RtcConfigure
组件,把用户道具传递到 UIKit 中。
然后,渲染 <GridVideo>
组件,该组件会把所有用户的视频呈网格状排列,大家也可以用 <PinnedVideo>
组件。因为我们想创建一个开启/关闭 AI 降噪的按钮,所以我们创建一个自定义组件 <Controls>
,在网格下方渲染。
import React from 'react';
import {StyleProp, View, ViewStyle} from 'react-native';
import {LocalAudioMute, LocalVideoMute, SwitchCamera, Endcall} from 'agora-rn-uikit/Components';
import {LocalUserContext} from 'agora-rn-uikit/Contexts';
import CustomButton from './CustomButton';
function Controls() {
return (
<LocalUserContext>
<View style={styles.Controls as StyleProp<ViewStyle>}>
<LocalAudioMute />
<LocalVideoMute />
<SwitchCamera />
<CustomButton />
<Endcall />
</View>
</LocalUserContext>
);
}
const styles = {
Controls: {
position: 'absolute',
bottom: 25,
left: 0,
width: '100%',
height: 70,
zIndex: 10,
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
},
};
export default Controls;
我们可以从 UIKit 中输入 LocalAudioMute
、LocalVideoMute
、SwitchCamera
和 Endcall
按钮,在 <View>
中渲染。
另外,我们会创建一个新组件 CustomButton
,该组件包含开启/关闭降噪功能的代码。
import React, {useContext, useState} from 'react';
import {Image, StyleSheet, TouchableOpacity} from 'react-native';
import {RtcContext} from 'agora-rn-uikit/Contexts';
function Button() {
const {RtcEngine} = useContext(RtcContext);
const [enabled, setEnabled] = useState(false);
return (
<TouchableOpacity
style={styles.localButton}
onPress={async () => {
if (!enabled) {
await RtcEngine.enableDeepLearningDenoise(true);
setEnabled(true);
} else {
await RtcEngine.enableDeepLearningDenoise(false);
setEnabled(false);
}
}}>
<Image
style={[styles.icon, {tintColor: enabled ? '#00ff00' : '#fff'}]}
source={{
uri: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABmJLR0QA/wD/AP+gvaeTAAABRklEQVRIieXUyy4EQRTG8R/WTNyaldiR8B6CJ2FPxiU8iHgMl40NNsSKBWHDziURT2As6ky0TmZ0m5FInKRSVadO/U/116eKP2hjqOMCr9FOsYH+TuELeEajRVvqFP4eoD3MYQq34bvCyE/h43gJ0BZ6kAW0Cc8idhjLKspVD9B+wGst4PmkG1USXMSmuZivfwNv4AR6SyaYiP4s+kZhPcMRZnEXvpnSx8dbQAdiXpQoP56O8WOVBKexab5w6rwkTbkWYn5eFp7hJjbVC2s1rIW/JhXAYcSuloXnP79dnfdgO2KfpBtfCd6sllFsSnKNYEiS5SBi332VshK8qHuxPXULfoNj6aF7kcp3JRfb0kZxGZBr6Ylo569kgyVOnvdXtt3fhPP5Wk7+BhweArYYSboKJ93IYtl1DQ59keRekmtH+vH/3D4A73qGGEQiRsYAAAAASUVORK5CYII=',
}}
/>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
icon: {
width: 24,
height: 24,
tintColor: '#fff',
},
localButton: {
width: 46,
height: 46,
backgroundColor: '#007bff',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 23,
},
});
export default Button;
可以用 RtcContext
访问 RtcEngine
示例,访问声网Agora SDK 里的供 UIKit 使用的引擎示例。我们会定义一个变量,开启该变量时,可以触发降噪效果。
另外,用<TouchableOpacity>
创建一个按钮,该按钮会根据状态在引擎示例上调用 enableDeepLearningDenoise
方法。记得要添加一个图形图标来显示状态。
以上是所有添加自定义功能所需的设置,大家也可以用同样的方式添加事件监听器,用来访问引擎事件,执行自定义操作。
总结
如果大家发现了可以添加在声网 Agora UIKit 上的好用的 React Native 功能,欢迎随时复刻资源库并添加拉取请求。
也欢迎大家在资源库里开启功能请求哦,谢谢大家~
原文作者:Ekaansh Arora
原文链接:Add AI Denoising to your Video Calls using the Agora React Native UIKit