声网互动直播让你在 app 里轻松实现音视频直播功能,用户可以实时进行深入交流,创造更多商业机会。
本文介绍如何通过最简单的代码来集成声网视频 SDK,在你的 App 里实现高质量、低延时的音视频直播功能。
下图展示在 app 中实现声网互动直播的基本工作流程:
参考以下步骤,在你的 app 中实现声动语聊功能:
设置用户角色
在互动直播中,用户角色可分为主播和观众。主播可在频道中发流,观众可接收频道中的音视频流。
加入频道
调用 joinChannel
方法来创建并加入频道。在 App ID 一致的前提下,传入相同频道名的用户会进入同一个频道。
在频道中发布并接收音视频流
加入频道后,主播可在频道中发流,并接收其他主播在频道中发布的音视频流。
在频道中接收音视频流
观众只能接收主播在频道中发布的音视频流,你可以调用 setClientRole
将用户角色从观众切换为主播。
如果你的目标平台为 iOS,你的开发环境需要满足以下需求:
如果你的目标平台为 Android,你的开发环境需要满足以下需求:
关于搭建开发环境的更多注意事项,详见搭建开发环境。
Invariant Violation: Calling synchronous methods on native modules is not supported in Chrome
。可以访问互联网的计算机。确保你的网络环境没有部署防火墙,否则无法正常使用声网服务。
有效的声网账户和声网项目。请参考开始使用声网平台,从声网控制台获取以下信息:
确保你已根据你使用的操作系统、针对的目标平台,完成了开发环境的搭建。
运行以下命令,在 ProjectName
处填入你的项目名称,创建并初始化一个新项目。
npx react-native init ProjectName --template react-native-template-typescript
运行完成后,会在执行该命令的路径下自动生成一个简单的示例项目。
启动你的 Andoird 或 iOS 模拟器,执行以下命令运行你的项目:
a. 在项目根目录下执行 npx react-native start
启动 Metro。
b. 在项目目录下再打开一个终端,执行 npx react-native run-android
运行 Android 应用或执行 npx react-native run-ios
运行 iOS 应用。
如果配置没有问题,你可以看到应用自动安装到模拟器上并开始运行。你也可以在 Android 或 iOS 真机上运行应用,详见在设备上运行 。
现在你已经成功运行了项目,可以开始尝试集成声网 SDK 并修改项目。
本节介绍如何在 React Native 0.60 或以上版本集成声网 React Native SDK。
在项目根目录下,使用以下任意一种方法下载最新版的声网 React Native SDK:
方法一:使用 npm 下载
npm i --save react-native-agora
方法二:使用 yarn 下载
// 安装 yarn
npm install -g yarn
// 使用 yarn 下载声网 React Native SDK
yarn add react-native-agora
React Native 0.60.0 或以上版本支持自动链接原生模块,请勿手动链接。详见
如果你的目标平台是 iOS, 还需要执行 npx pod-install
安装 SDK。
请确保你已安装 CocoaPods。你可以参考 Getting Started with CocoaPods。
本节展示如何使用声网 React Native SDK 为你的 App 添加互动直播功能。
打开 App.tsx
文件,删除所有代码并粘贴以下代码:
// 导入 React Native 的类
import React, {useRef, useState, useEffect} from 'react';
import {
SafeAreaView,
ScrollView,
StyleSheet,
Text,
View,
Switch,
} from 'react-native';
import {PermissionsAndroid, Platform} from 'react-native';
// 导入声网 SDK 的类
import {
ClientRoleType,
createAgoraRtcEngine,
IRtcEngine,
RtcSurfaceView,
ChannelProfileType,
AudienceLatencyLevelType,
} from 'react-native-agora';
React Native App 主进程包括以下部分:
定义基本信息。包括 App ID,Token 和频道名,用于初始化 RtcEngine
和加入频道。
appId
:你的声网项目的 App ID。详见获取 App ID。
channelName
:传入能标识频道的频道 ID。App ID 相同、频道 ID 相同的用户会进入同一个频道。
token
:传入能标识用户角色和权限的 Token。该 Token 必须是使用上述 App ID 和频道名生成的 Token。可设为如下一个值:
临时 Token。临时 Token 服务有效期为 24 小时。你可以在控制台里生成一个临时 Token,详见获取临时 Token。
在你的服务器端生成的 Token。在安全要求高的场景下,我们推荐你使用此种方式生成的 Token,详见生成 Token。
渲染用户界面。根据场景需要,为项目创建互动直播的用户界面,在互动直播中,声网推荐你添加如下用户界面元素:
加入/离开频道按钮
本地/远端视频窗口
定义样式。定义用户界面中各种元素的样式。
展示信息。调用 showMessage
方法展示用户提示信息。
为搭建 App 框架,打开 App.tsx
文件,在最下方粘贴以下代码:
// 定义基本信息
const appId = '<--在此粘贴 App ID -->';
const token = '<--在此粘贴音视频 token -->';
const channelName = '<--在此粘贴创建音视频 token 时对应的频道名-->';
const uid = 0; // 本地用户 Uid,无需修改
const App = () => {
const agoraEngineRef = useRef<IRtcEngine>(); // IRtcEngine 实例
const [isJoined, setIsJoined] = useState(false); // 本地用户是否已加入频道
const [isHost, setIsHost] = useState(true); // 用户角色
const [remoteUid, setRemoteUid] = useState(0); // 远端用户的 Uid
const [message, setMessage] = useState(''); // 用户提示信息
// 在此粘贴 “4.实现互动直播逻辑” 示例代码
// 渲染用户界面
return (
<SafeAreaView style={styles.main}>
<Text style={styles.head}>声网互动直播快速开始</Text>
<View style={styles.btnContainer}>
<Text onPress={join} style={styles.button}>
加入频道
</Text>
<Text onPress={leave} style={styles.button}>
离开频道
</Text>
</View>
<View style={styles.btnContainer}>
<Text>Audience</Text>
<Switch
onValueChange={switchValue => {
setIsHost(switchValue);
if (isJoined) {
leave();
}
}}
value={isHost}
/>
<Text>Host</Text>
</View>
<ScrollView
style={styles.scroll}
contentContainerStyle={styles.scrollContainer}>
{isJoined ? (
<React.Fragment key={0}>
<RtcSurfaceView canvas={{uid: 0}} style={styles.videoView} />
<Text>本地用户 uid: {uid}</Text>
</React.Fragment>
) : (
<Text>加入一个频道</Text>
)}
{isJoined && !isHost && remoteUid !== 0 ? (
<React.Fragment key={remoteUid}>
<RtcSurfaceView
canvas={{uid: remoteUid}}
style={styles.videoView}
/>
<Text>远端用户 uid: {remoteUid}</Text>
</React.Fragment>
) : (
<Text>{isJoined && !isHost ? '等待远端用户加入' : ''}</Text>
)}
<Text style={styles.info}>{message}</Text>
</ScrollView>
</SafeAreaView>
);
// 展示信息
function showMessage(msg: string) {
setMessage(msg);
}
};
// 定义用户界面样式
const styles = StyleSheet.create({
button: {
paddingHorizontal: 25,
paddingVertical: 4,
fontWeight: 'bold',
color: '#ffffff',
backgroundColor: '#0055cc',
margin: 5,
},
main: {flex: 1, alignItems: 'center'},
scroll: {flex: 1, backgroundColor: '#ddeeff', width: '100%'},
scrollContainer: {alignItems: 'center'},
videoView: {width: '90%', height: 200},
btnContainer: {flexDirection: 'row', justifyContent: 'center'},
head: {fontSize: 20},
info: {backgroundColor: '#ffffe0', paddingHorizontal: 8, color: '#0000ff'}
});
// 在此粘贴 “3.获取设备权限” 示例代码(目标平台为 Android)
export default App;
Android
在 Android 设备上,要获得麦克风和摄像头的使用权限,需要弹出提示框供用户选择。
在 App.tsx
文件的 export default App
代码块上方添加如下代码,设置获取设备麦克风和摄像头使用权限的提示框。
const getPermission = async () => {
if (Platform.OS === 'android') {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
PermissionsAndroid.PERMISSIONS.CAMERA,
]);
}
};
iOS
在 Xcode 中,打开 info.plist
文件。在右侧列表中添加如下内容,获取相应的设备权限:
Key | Type | Value |
---|---|---|
Privacy - Microphone Usage Description | String | 使用麦克风的目的,例如:for a call or live interactive streaming。 |
Privacy - Camera Usage Description | String | 使用摄像头的目的,例如:for a call or live interactive streaming。 |
互动直播的 API 调用时序见下图:
打开 App.tsx
文件,将以下代码复制到 const App
代码块中的 return
代码块上方 ,实现上述 API 的调用逻辑:
// 启动 App 时初始化引擎
useEffect(() => {
setupVideoSDKEngine();
});
const setupVideoSDKEngine = async () => {
try {
// 获取设备权限后创建 RtcEngine
if (Platform.OS === 'android') {
await getPermission()};
agoraEngineRef.current = createAgoraRtcEngine();
const agoraEngine = agoraEngineRef.current;
// 注册回调事件
agoraEngine.registerEventHandler({
onJoinChannelSuccess: () => {
showMessage('成功加入频道:' + channelName);
setIsJoined(true);
},
onUserJoined: (_connection, Uid) => {
showMessage('远端用户 ' + Uid + ' 已加入');
setRemoteUid(Uid);
},
onUserOffline: (_connection, Uid) => {
showMessage('远端用户 ' + Uid + '已离开频道');
setRemoteUid(0);
},
});
// 初始化引擎
agoraEngine.initialize({
appId: appId,
});
// 开启本地视频
agoraEngine.enableVideo();
} catch (e) {
console.log(e);
}
};
// 定义点击加入频道按钮后调用的 join 方法
const join = async () => {
if (isJoined) {
return;
}
try {
// 加入频道后设置频道场景类型为直播
agoraEngineRef.current?.setChannelProfile(
ChannelProfileType.ChannelProfileLiveBroadcasting,
);
if (isHost) {
// 开启预览
agoraEngineRef.current?.startPreview();
// 以主播角色加入频道
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
clientRoleType: ClientRoleType.ClientRoleBroadcaster});
} else {
// 以观众角色加入频道
agoraEngineRef.current?.joinChannel(token, channelName, uid, {
clientRoleType: ClientRoleType.ClientRoleAudience,
audienceLatencyLevelType: AudienceLatencyLevelType.AudienceLatencyLevelUltraLowLatency});
}
} catch (e) {
console.log(e);
}
};
// 定义点击离开频道按钮后调用的 leave 方法
const leave = () => {
try {
// 调用 leaveChannel 方法离开频道
agoraEngineRef.current?.leaveChannel();
setRemoteUid(0);
setIsJoined(false);
showMessage('已离开频道');
} catch (e) {
console.log(e);
}
};
确保已经在快速开始代码中传入了有效的 appId
,channelName
和 token
。详见设计主进程。
运行 App。部分模拟机可能无法支持本项目的全部功能,建议你在真机中运行该项目。
在 Android 设备上运行:
a. 开启 Android 设备的开发者选项,通过 USB 连接线将 Android 设备接入电脑。
b. 在项目根目录下执行 npx react-native run-android
。
在 iOS 设备上运行:
a. 使用 Xcode 打开 ProjectName/ios/ProjectName.xcworkspace
文件夹。
b. 通过 USB 线将 iOS 设备接入你的电脑。
c. 在 Xcode 中,点击 Build and run 按钮。
启动 App,选择角色并加入频道:
选择主播:发布本地视频流至远端,在 App 中会播放自己的画面。
选择观众:订阅远端直播流,在 App 中只会看到主播的画面。
邀请一位朋友克隆 https://github.com/AgoraIO/API-Examples-Web 到本地,在浏览器中打开 Demo/index.html 文件,并输入相同的 App ID、频道名称和临时 Token。 如果你的朋友作为主播加入,你们可以听见、看见对方;如果作为观众加入,你只能看到自己,你的朋友可以看到你并听到你的声音。