实时语音通话能够拉近人与人之间的距离,为用户提供沉浸式的交流体验,帮助你的 app 提高用户黏性。
本文介绍如何通过少量代码集成声网 SDK 并调用 API,在你的 app 中实现高质量、低延迟的语音通话功能。
技术原理
下图展示在 app 中实现声网语音通话的基本工作流程:
实现语音通话的步骤如下:
1. 设置角色
将用户角色均设置为主播。
2. 加入频道
调用 JoinChannel
创建并加入频道。在 App ID 一致的前提下,传入相同频道名的用户会进入同一个频道。
3、4. 在频道内发布和订阅音频
加入频道后,两位主播可以发布音频并互相订阅。
参考以下操作,在你的 app 中实现音频通话功能:
使用 Visual Studio 中的 NuGet 包管理器,将 SDK 集成到项目中。详见快速入门:在 Visual Studio 中安装和使用包。
本节介绍如何使用 SDK 在你的项目中实现音频通话功能。
为直观地体验音频通话,你需要根据应用场景创建用户界面 (UI)。若你的项目中已有用户界面,可略过此步骤。
如果你想实现音频通话,推荐在 UI 上添加以下控件:
参考以下步骤创建 UI。
创建 Join 和 Leave 按钮
a. 在你的项目中,打开 Solution Explore 窗口,双击 Form1.cs,打开 Toolbox 窗口,选择 Button 控件,依次添加两个按钮,并将两个按钮拖放至合适位置。
b. 将鼠标移至其中一个按钮上,点击鼠标右键,选中 Properties,在打开的 Properties 窗口中修改 Text 属性为 Join,修改 Name 属性为 btnJoin。
c. 重复上一个步骤来修改另一个按钮的属性:修改 Text 为 Leave;修改 Name 为 btnLeave。
创建频道名输入框
a. 打开 Toolbox 窗口,选中 TextBox 控件,然后将其拖拽至合适位置。
b. 将鼠标移至添加好的输入框控件上,点击鼠标右键,选中 Properties ,修改其属性 Name 为 txChannelName。
保存上述步骤的更改。
分别双击 Join 和 Leave 按钮,IDE 会自动关联点击事件处理函数。
参考以下步骤来实现音频通话逻辑:
在项目中,鼠标右键点击 Solution Explorer 中的 Form1.cs,单击 View Code。
在弹出的 Form1.cs
界面中,将下列代码添加至 using System.Windows.Forms;
之后:
using Agora.Rtc;
创建加入频道相关变量
在 Form1.cs
中,将下列代码添加至 public Form1()
之前:
// 填写项目的 App ID,可在声网控制台中生成。
private readonly string APP_ID = "";
// 填写声网控制台中生成的临时 Token。
private readonly string APP_TOKEN = "";
// 声明 IRtcEngine 实例
private IRtcEngine engine_ = null;
// 声明 RtcEventHandler
private RtcEventHandler handler_ = null;
声明一个 RtcEventHandler
类,用以处理事件
在 Form1.cs
中,将以下代码添加至类 Form1
的定义之后:
internal class RtcEventHandler : IRtcEngineEventHandler
{
// 声明一个代理,用于处理 OnUserJoined 事件。
public delegate void OnUserJoinedHandler(RtcConnection connection, uint remoteUid, int elapsed);
// 声明 OnUserJoined 回调。
public event OnUserJoinedHandler EventOnUserJoined;
public RtcEventHandler()
{
}
public override void OnError(int error, string msg)
{
Console.WriteLine("=====>OnError {0} {1}", error, msg);
}
public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
{
Console.WriteLine("----->OnJoinChannelSuccess channel={0} uid={1}", connection.channelId, connection.localUid);
}
public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
{
Console.WriteLine("----->OnLeaveChannel duration={0}", stats.duration);
}
public override void OnUserJoined(RtcConnection connection, uint remoteUid, int elapsed)
{
Console.WriteLine("----->OnUserJoined uid={0}", remoteUid);
if (EventOnUserJoined != null)
EventOnUserJoined.Invoke(connection, remoteUid, elapsed);
}
public override void OnUserOffline(RtcConnection connection, uint remoteUid, USER_OFFLINE_REASON_TYPE reason)
{
Console.WriteLine("----->OnUserOffline, channel={0}, remoteUid={1}, reason={2}", connection.channelId, remoteUid, reason);
}
public override void OnRemoteVideoStateChanged(RtcConnection connection, uint remoteUid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason, int elapsed)
{
Console.WriteLine("----->OnRemoteVideoStateChanged, channel={0}, remoteUid={1}, state={2}, reason={3}", connection.channelId, remoteUid, state, reason);
}
}
创建并初始化 IRtcEngine
a. 调用 CreateAgoraRtcEngine
来创建 IRtcEngine
实例。将以下代码添加到 InitializeComponent();
的后面:
// 创建 IRtcEngine。
engine_ = RtcEngine.CreateAgoraRtcEngine();
RtcEngineContext ctx = new RtcEngineContext()
{
appId = APP_ID,
areaCode = AREA_CODE.AREA_CODE_GLOB,
logConfig =
{
filePath = "rtc.log"
}
};
// 初始化 IRtcEngine。
var ret = engine_.Initialize(ctx);
if(ret != 0)
{
Console.WriteLine("=====>Initialize failed {0}", ret);
return;
}
b. 创建并注册事件监听器。将以下代码添加至上一段代码之后:
// 注册事件监听器。
handler_ = new RtcEventHandler();
handler_.EventOnUserJoined += OnUserJoined;
engine_.InitEventHandler(handler_);
实现加入频道逻辑。用以下代码替换 btnJoin_Click
函数:
private void btnJoin_Click(object sender, EventArgs e)
{
if (null != engine_)
{
ChannelMediaOptions options = new ChannelMediaOptions();
// 将频道场景设置为直播。
options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
// 将用户角色设置为主播。
options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
// 使用临时 Token 加入频道。
var ret = engine_.JoinChannel(APP_TOKEN, txChannelName.Text, 0, options);
Console.WriteLine("=====>JoinChannel result {0}", ret);
}
}
实现离开频道逻辑。用以下代码替换 btnLeave_Click
函数:
private void btnLeave_Click(object sender, EventArgs e)
{
if (null != engine_)
{
var ret = engine_.LeaveChannel();
Console.WriteLine("=====>LeaveChannel result {0}", ret);
}
}
按照以下步骤来测试你的音频通话项目:
Form1.cs
文件的 APP_ID
和 APP_TOKEN
中。声网在 GitHub 上提供了一个开源的示例项目 Agora-C_Sharp-RTC-SDK-API_Example 供你参考,可实现更多的应用场景。