Unity

Demo运行指引

1.环境准备
unity3d是一个跨平台的游戏引擎,所以我们的语音demo支持三个平台。
你需要在windows下或者iMac安装好Unity3D 软件,支持版本4.6以上。下面以windows的环境来演示运行demo的过程。
如果要编译Android平台,需要事先安装好android sdk和jdk。并在菜单栏Edit->Prefrences->External Tools配置好路径。
如果要编译iOS平台,需要安装好Xcode软件。

2.导入项目
新建一个2D工程,如图

创建成功后打开项目的根目录,把Assets文件夹复制进去。如图

unity工程界面会呈现如下图

点击左上角菜单栏的File->BuildAndSetting选项,选择场景,编译的平台和架构。如图

注意,如果是Android平台,需要点击player setting 里填写包名信息。如图

点击build按钮执行编译。

如果是iMac,会生成Xcode工程。打开工程,添加依赖的系统库,
CoreTelephoney.framework
libiconv.tbd
libc++.1.tbd
libz.tbd
执行编译即可。
3.运行demo
启动程序后如图

用户名任意输入,测试房间号为1-50,其中7,8,9房间是高音质房间。点击加入即可。如果登陆成功,则会看到如下图

主界面显示房间的与会方列表
下面几个按钮显示了当前语音状态,通话结束可以点击挂断按钮。

SDK的集成

1.SDK的概述
目录结构

其中x86 x86-64文件夹的库是windows系统用的。
SDK与原生平台的库相比多了两个脚本文件
ValleyRtcAPI_Native.cs
ValleyRtcAPI.cs

ValleyRtcAPI_Native.cs是对C语言接口的封装,不推荐上层直接调用。
ValleyRtcAPI.cs是对前者的封装,对于二次开发更加简单易用。本节主要介绍后者。
2.下载SDK
请在官网的下载页面获取。
注意,需要用到哪个平台,就把对应的平台拷贝到项目里去,如果全部放进去,会发生文件名同名冲突。
3.引入到工程里
将下载下来的文件夹放到项目根目录下的Assets即可。
如果是iOS项目,还需要添加系统依赖库。
CoreTelephoney.framework
libiconv.tbd
libc++.1.tbd
libz.tbd
4.添加权限
对于Android平台,在文件夹下有一个文件:AndroidManifest.xml,项目里需要包含这些权限。
对于iOS平台,需要添加麦克风权限,打开info.plist文件,添加Privacy - Microphone Usage Description 条目,描述里写“请求麦克风权限”或者自定义。

5.后台运行
如果需要APP切换到后台依然可以说话和播放,则做如下设置

功能实现文档

1.初始化环境
SDK的演示代码片段参考ValleyRtcDemo
在调用其他API之前,需要先初始化SDK的工作环境,调用接口

//静态成员函数,与CleanSDK一一对应,只需要调用一次。
public static void InitSDK(string path)
{
RtcChannelNative.Valley_InitSDK(path);
}
//第二个参数是java的application context对象
public static void InitSDK(string path, IntPtr javaAppContext)
{
RtcChannelNative.Valley_InitAndroid(javaAppContext);
RtcChannelNative.Valley_InitSDK(path);
}

第二个重载函数用于Android平台。
对应的,当不想用SDK的时候,调用清理函数

public static void CleanSDK()
{
RtcChannelNative.Valley_CleanSDK();
}

2.创建房间。

上层new一个实例即可创建一个房间。

channel = new Valley.RtcChannel();

然后开启相关的功能,默认是不开启的,建议全部开启。

channel.EnableInterface(Valley.RtcChannel.INTERFACE_USERS);//用户列表
channel.EnableInterface(Valley.RtcChannel.INTERFACE_REAL_AUDIO);//实时语音

注册回调函数用于接收异步事件。

channel.RegisterRtcSink(OnEvent)

3.登陆房间

channel.Login(roomkey, uid, null);

调用完,需要定时调用Poll函数去轮询事件。如果有事件产生会同步回调到OnEvent函数里。
当登陆成功后会收到事件。

public void OnEvent(int type, int ec, Valley.RtcChannel.RtcObjectBase ob)
{
if (type == (int)Valley.RtcChannel.RtcEvent.RTC_CALLBACK_RESPONED_LOGIN)
{
if (ec == 0)
{
LoginCanvas.SetActive(false);//更新界面
RoomCanvas.SetActive(true);//更新界面
GetUserList();//获取用户列表
}
else
{
textHintError.text = "进入房间失败:" + Valley.RtcChannelNative.Valley_GetErrDesc(ec);
}
}
...
}

比如登陆成功后可以获取用户列表,打开说话等相关操作。

4.登出房间

channel.Logout();

退出房间是立即返回,可以立即重新调用登陆操作。

5.销毁房间

channel.Release(true);
channel = null;

如果传false,则立即返回,不阻塞上层,sdk资源的释放异步执行,此刻应用程序应该保证不会立即退出进程,否则可能导致崩溃。

6.相关操作示例

public void OnClick(GameObject sender)
{
switch (sender.name)
{
case "Login":
{
Debug.Log("Login");
string uid = GameObject.Find("EditUserID").GetComponent<InputField>().text;
string roomkey = GameObject.Find("EditRoomKey").GetComponent<InputField>().text;
if (string.IsNullOrEmpty(uid) || string.IsNullOrEmpty(roomkey))
{
Debug.Log("请输入合法的字符串");
return;
}

RealAudioManager.GetInstance().Login(roomkey, uid);
}
break;
case "Logout":
{
Debug.Log("Logout");
RealAudioManager.GetInstance().Logout();
RoomCanvas.SetActive(false);
LoginCanvas.SetActive(true);
}
break;
case "Playout":
{
Debug.Log("Playout");
Text btntext = GameObject.Find("Playout/Text").GetComponent<Text>();
if (btntext.text == "播放中")
{
btntext.text = "停止播放";
RealAudioManager.GetInstance().Playout(false);
}
else
{
btntext.text ="播放中";
RealAudioManager.GetInstance().Playout(true);
}
}
break;
case "Speaking":
{
Debug.Log("Speaking");
Text btntext = GameObject.Find("Speaking/Text").GetComponent<Text>();
if (btntext.text == "说话中")
{
btntext.text = "停止说话";
RealAudioManager.GetInstance().Speak(false);
}
else
{
btntext.text = "说话中";
RealAudioManager.GetInstance().Speak(true);
}
}
break;
case "Headset":
{
Text btntext = GameObject.Find("Headset/Text").GetComponent<Text>();
if (btntext.text == "扬声器")
{
btntext.text = "听筒";
RealAudioManager.GetInstance().SetHeadSetOn(true);
}
else
{
btntext.text = "扬声器";
RealAudioManager.GetInstance().SetHeadSetOn(false);
}
}
break;
default:
Debug.Log("None");
break;
}
}