实现音视频通话
更新时间: 2024/09/18 16:26:13
网易云信音视频通话产品的基本功能包括高质量的实时音频通话。当您成功初始化 SDK 之后,您可以简单体验本产品的基本业务流程。本文档为您展示音频通话提供的基本业务流程。
- NERtc Unity SDK 目前支持音视频通话、房间管理、多房间、互动直播、空间音效、屏幕共享(Windows)等功能。
- 暂不支持 macOS 平台;水印、跨房间推流、网络探测、自定义辅流、屏幕共享(移动端)等功能敬请期待后续版本。
前提条件
请确认您已完成以下操作:
- 创建应用并获取 App Key。
- 开通音视频通话 2.0 服务。
- 集成 SDK(音视频),其中需要添加必要的设备权限和导出工程的权限。
实现音视频通话
本节主要介绍如何使用 NERTC Unity SDK 实现音视频通话。
步骤一 初始化 SDK
在调用其他 API 前,您需要先初始化 SDK,具体步骤如下。
若您开发的是 Android 端的应用,则需要将 SDK 包的 AndroidManifest.xml
文件内所含的权限合并至 Assets/Plugins/Android/AndroidManifest.xml
中。
- 调用
RtcEngine.GetInstance
方法获取IRtcEngine
实例。 - 调用
IRtcEngine.Initialize
方法初始化 SDK,并在 UI 线程初始化Dispatcher
对象。
示例代码如下:
using nertc;
class MyDemo {
// 声明类成员
IRtcEngine rtcEngine = IRtcEngine.GetInstance();
// 创建 SDK 的示例函数,
private void InitSDK() {
//初始化Dispatcher,视屏回调纹理对象时需要用到,需要在UI线程调用
_ = Dispatcher.Current;
//初始化SDK引擎
var param = new RtcEngineContext();
param.appKey = "YOUR APPKEY";
param.logPath = Application.persistentDataPath;
param.logFileMaxSize = 200;
param.logLevel = RtcLogLevel.kNERtcLogLevelInfo;
#if UNITY_ANDROID && !UNITY_EDITOR
AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject activity = playerClass.GetStatic<AndroidJavaObject>("currentActivity");
param.context = activity;
#endif
int result = rtcEngine.Initialize(param);
if(result != RtcErrorCode.kNERtcNoError) {
//sdk 初始化失败
}
}
}
步骤二 添加监听事件
您可以注册 IRtcEngine
类中声明的事件来监听 SDK 可能触发的所有异步回调。
以监听OnJoinChannel
事件和OnLeaveChannel
事件为例,示例代码如下:
// 当加入房间成功后的回调
private void onJoinChannel(ulong cid, ulong uid, RtcErrorCode result, ulong elapsed) {
//进入房间事件回调结果
}
private void onLeaveChannel(RtcErrorCode result) {
// 离开房间事件回调结果
}
//事件绑定
private void BindEvents() {
//监听事件,其他事件类同此用法。
rtcEngine.OnJoinChannel = onJoinChannel;
rtcEngine.OnLeaveChannel = onLeaveChannel;
}
//事件解绑
private void UnbindEvents() {
//取消事件监听
rtcEngine.OnJoinChannel = null;
rtcEngine.OnLeaveChannel = null;
}
步骤三 设置本地视图
初始化成功后,您可以设置本地视图,来预览本地图像。您可以在加入房间之前预览,或在加入房间后预览,具体步骤如下。
-
加入房间前预览。
- 调用
IRtcEngine.SetupLocalVideoCanvas
与IRtcEngine.StartVideoPreview
方法,在加入房间前设置本地视图,预览本地图像。
示例代码如下:
- 调用
//定义回调接收类
public class VideoFrameCallback : IVideoFrameTextureCallback
{
private Action<ulong, Texture2D, RtcVideoRotation> _callback;
public VideoFrameCallback(Action<ulong, Texture2D, RtcVideoRotation> callback)
{
_callback = callback;
}
public void OnVideoFrameCallback(ulong uid, Texture2D texture, RtcVideoRotation rotation)
_callback?.Invoke(uid, texture, rotation);
}
}
//纹理对象回调处理
public void OnTexture2DVideoFrame(ulong uid, Texture2D texture, RtcVideoRotation rotation)
{
//uid为0时代表是本人的视频数据回调
}
//加入房间前预览
private void StartVideoPreview() {
var userCanvas = new RtcVideoCanvas();
userCanvas.callback = new VideoFrameCallback(OnTexture2DVideoFrame);
int result = rtcEngine.SetupLocalVideoCanvas(userCanvas);
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
return;
}
result = rtcEngine.StartVideoPreview();
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
}
}
- 若要结束预览,或者准备加入房间时,调用
IRtcEngine.StopVideoPreview
方法停止预览。
-
加入房间后预览。
在成功加入房间后,调用
IRtcEngine.EnableLocalVideo
方法进行视频的采集发送与预览。示例代码如下:
//开启视频采集和发送
private void EnableLocalVideo() {
var userCanvas = new RtcVideoCanvas();
userCanvas.callback = new VideoFrameCallback(OnTexture2DVideoFrame);
int result = rtcEngine.SetupLocalVideoCanvas(userCanvas);
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
return;
}
result = rtcEngine.EnableLocalVideo(true);
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
}
}
步骤四 加入房间
调用 IRtcEngine.JoinChannel
方法加入房间,相关参数说明如下表所示。
加入房间前,请确保已完成初始化相关事项。若您的业务中涉及呼叫邀请等机制,建议通过信令实现。
参数 | 说明 |
---|---|
token | 安全认证签名(NERTC Token)。
|
channel_name | 房间名称,长度为 1 ~ 64 字节。目前支持以下 89 个字符:a-z, A-Z, 0-9, space, !#$%&()+-:;≤.,>? @[]^_{|}~"。 设置相同房间名称的用户会进入同一个通话房间。 |
uid | 用户的唯一标识 id,房间内每个用户的 uid 必须是唯一的。 |
示例代码如下:
//加入房间
private void JoinChannel() {
// 初始化成功之后,加入房间 JoinChannel 需要填写参数:
int result = rtcEngine.JoinChannel(
"YOUR TOKEN",
"YOUR CHANNEL NAME",
12345678 //YOUR UID
);
if(result != (int)RtcErrorCode.kNERtcNoError) {
//加入房间失败
}
}
SDK 发起加入房间请求后,服务器会进行响应,您可以通过初始化时设置的 OnJoinChannel
回调监听本地用户加入房间的结果。
此外,您也可以调用 IRtcEngine.OnUserJoined
回调监听其它用户加入房间的通知。
步骤五 发布本地音频流(可选)
在 NERTC SDK 中,本地音频的采集发布和远端音频的订阅播放默认启动,正常情况下无需您主动干预。
此外,您也可以调用 IRtcEngine.EnableLocalAudio
方法开启或关闭音频设备,以控制本地音频流的发布。
示例代码如下:
private void EnableLocalAudio() {
int result = rtcEngine.EnableLocalAudio(true); // true启用音频设备,false则关闭音频设备
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
}
}
步骤六 发布本地视频流
调用 IRtcEngine.EnableLocalVideo
方法开启或关闭视频设备,以控制本地视频流的发布。
示例代码如下:
private void EnableLocalVideo() {
int result = rtcEngine.EnableLocalVideo(true); // 启用视频设备,false则关闭设备
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
}
}
步骤七 设置远端视图
音视频通话过程中,除了要显示本地的视频画面,通常也要显示参与互动的其他连麦者/主播的远端视频画面,具体步骤如下。
-
监听远端用户进出频道。
IRtcEngine
通过以下回调获取相关信息:-
OnUserJoined
:监听远端用户加入通话房间的事件,并抛出对方的 uid。当本端加入房间后,也会通过此回调抛出通话房间内已有的其他用户。 -
OnUserVideoStart
:监听远端用户发布视频流的事件,回调中携带对方的 uid 与发布的视频分辨率。
-
-
设置远端视频画布。
在监听到远端用户加入房间或发布视频流后,本端调用
IRtcEngine.SetupRemoteVideoCanvas
方法设置远端用户视频画布,用于显示其视频画面。示例代码如下:
//设置远端画布 private void SetupRemoteVideoCanvas(long uid) { var userCanvas = new RtcVideoCanvas(); userCanvas.callback = new VideoFrameCallback(OnTexture2DVideoFrame); int result = rtcEngine.SetupRemoteVideoCanvas(uid, userCanvas); if(result != (int)RtcErrorCode.kNERtcNoError) { //失败 } }
-
监听远端视频流发布。
当房间中的其他用户发布视频流时,本端会触发
OnUserVideoStart
回调。 -
订阅远端视频流。
在监听到远端用户发布视频流后,本端可以调用
IRtcEngine.SubscribeRemoteVideoStream
方法对其发起视频流的订阅,来将对方的视频流渲染到视频画布上。示例代码如下:
private void OnUserVideoStart(long uid) { // 订阅视频 SetupRemoteVideoCanvas(true); int result = rtcEngine.SubscribeRemoteVideoStream(uid,true); if(result != (int)RtcErrorCode.kNERtcNoError) { //失败 } } private void OnUserVideoStop(long uid) { // 取消订阅视频 int result = rtcEngine.SubscribeRemoteVideoStream(uid,false); if(result != (int)RtcErrorCode.kNERtcNoError) { //失败 } } private void OnUserLeft(long uid) { //移除远端画布 RemoveRemoteVideoCanvas(uid); }
-
监听远端用户离开房间或停止发布视频。
-
OnUserLeft
:用户离开房间回调。 -
OnUserVideoStop
:远端用户关闭视频功能回调。
-
-
销毁远端视频画布。
当房间中的其他用户离开房间时,本端会触发
OnUserLeft
回调,此时可以调用IRtcEngine.SetupRemoteVideoCanvas
方法,设置参数为 null 删除远端视频画布。LeaveChannel
时会自动清空远端用户画布,但会保留本地画布。Release
时会清空所有画布。示例代码如下:
//删除画布 private void RemoveRemoteVideoCanvas(long uid) { //删除本地画布 rtcEngine.SetupLocalVideoCanvas(null); //删除远端画布 rtcEngine.SetupRemoteVideoCanvas(uid, null); }
步骤八 退出通话房间
调用 IRtcEngine.LeaveChannel
方法退出通话房间。
示例代码如下:
// 离开房间
private void LeaveChannel() {
// 离开房间
int result = rtcEngine.LeaveChannel();
if(result != (int)RtcErrorCode.kNERtcNoError) {
//失败
}
}
- 通过
IRtcEngine.OnLeaveChannel
回调可以监听本地用户退出房间的结果。 - 通过
IRtcEngine.OnUserLeft
回调可以监听远端用户离开房间的通知。
步骤九 销毁实例
当确定 App 短期内不再使用音视频通话实例时,可以调用 IRtcEngine.Release
方法释放对应的对象资源。
当此接口调用成功之后,若您想再次使用 SDK,需要重新调用初始化的相关接口。
示例代码如下:
// 销毁 SDK 的示例函数
private void OnApplicationQuit() {
// 释放引擎
int result = rtcEngine.Release(true);
if(result != RtcErrorCode.kNERtcNoError) {
//失败
}
}