瑞云 x 声网Unity的接入文档
下载最新音频Agora SDK
- 前往 SDK 下载页面,在音频 SDK 中下载最新版的 Unity SDK。
- 下载完成后在你的 Unity 编辑器中打开 SDK 包并取消勾选不需要的插件(默认会勾选 SDK 包含的所有插件),然后点击 Import。
下载RayvisionSocket网络通讯插件
- 前往 SDK 下载页面,在下载最新版RayvisionSocket.unitypackage,并导入项目中
- 将预设拖入Hierarchy中,预设路径:Assets-->RayvisonWebsocket-->Prafab-->Rayvison_WSMgr
WebSocket预设
Rayvison_WSMgr预设上挂挂载了WSMgr脚本,这是一个不被销毁的单例实例,您可以在任意需要的地方通过WSMgr.Instance进行调用
鉴权消息收取
云平台会在事件发生时(有用户通过云渲染页面访问应用),将音频鉴权信息发送给应用,收到鉴权信息后,进行下一步接口请求。
//订阅事件
WSMgr.Instance.OnStringMsgRevice += OnMsg;
//取消订阅事件
WSMgr.Instance.OnBinaryMsgRecv -= OnMsg;
//鉴权信息
private string _Agora_Service_Verify = "";
void OnMsg(string msg)
{
Debug.Log(msg);
if (msg.Contains("_Agora_Service_Verify"))
{
JsonData jsonData = JsonMapper.ToObject(msg);
_Agora_Service_Verify = jsonData["_Agora_Service_Verify"].ToString();
//准备请求接口
}
}
接口请求
后台有两个POST请求接口
生成接口:"https://app.3dcat.live/api/3dcat/application/agora/generate"生成接口请求参数(channel为频道名,可以来自用户输入,或者使用预定义的房间名):
{
"channel":"",
"serviceVerify":""
}
返回示例:
{
"version": "1.0.0",
"result": true,
"message": "success",
"code": 200,
"data": {
"account": "1611267243147137024",
"token": "007eJxTYHg/+1Kd/r2Iwuq/9o9ffv8xSehZtXmIeId101fVelW/7WoKDEbJZsYWaZbmRmbGpiamKcZJJmnJJslJhpYGSUYWxqmpuhe3JzcEMjK8fH3sBSMDIwMLEIP4TGCSGUyyQNnGJibCDIZmhoZGZuZGJsaGJuaGxuYGRiYALO8oEg=="
},
"serverTime": 1672991022001,
"requestId": "d703c811b1105e18"
}
更新接口请求参数:
{
"account":"",
"channel":"",
"serviceVerify":""
}
返回示例:
{
"version": "1.0.0",
"result": true,
"message": "success",
"code": 200,
"data": {
"account": "1611267243147137024",
"token": "007eJxTYMjbFrBlteLRGxMfVq3a9zXz04bLbWo77WMMvK4us92alfdOgcEo2czYIs3S3MjM2NTENMU4ySQt2SQ5ydDSIMnIwjg1tfvi9uSGQEYGx11VBowMjAwsQAziM4FJZjDJAmUbm5gIMxiaGRoamZkbmRgbmpgbGpsbGJkAAGspKAE="
},
"serverTime": 1672991115934,
"requestId": "5055c2e1dca02015"
}
初次使用时,请使用生成接口,接口所返回的token信息有效期为24小时,建议将token、account和获取时间保存到本地,下次启动时先核验是否过期,如果已过期则调用更新接口。serviceVerify无需保存,每次启动服务端都会发送新的值。
POST请求: IEnumerator IE_RequestPost(string url, string postJson, Action<string> callback = null)
{
byte[] postBytes = System.Text.Encoding.Default.GetBytes(postJson);
UnityWebRequest request = new UnityWebRequest(url, "POST");
request.uploadHandler = new UploadHandlerRaw(postBytes);
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.SendWebRequest();
if (request.result == UnityWebRequest.Result.ConnectionError || request.result == UnityWebRequest.Result.ProtocolError)
{
Debug.LogError(request.error);
}
else
{ //返回的数据
callback?.Invoke(request.downloadHandler.text);
}
}
void GenerateToken()
{
JsonData postData = new JsonData();
postData["serviceVerify"] = _Agora_Service_Verify;
postData["channel"] = "testChannel";
StartCoroutine(IE_RequestPost("https://app.3dcat.live/api/3dcat/application/agora/generate", postData.ToJson(), Callback));
}
void Callback(string msg)
{
JsonData generateData = JsonMapper.ToObject(msg);
if (generateData["data"] == null)
{
return;
}
string _token = generateData["data"]["token"].ToString();
string _account = generateData["data"]["account"].ToString();
}
加入频道
void JoinChannel()
{
SetupVideoSDKEngine();
InitEventHandler();
// 启用音频模块。
RtcEngine.EnableAudio();
// 设置频道媒体选项。
ChannelMediaOptions options = new ChannelMediaOptions();
// 自动订阅所有音频流。
options.autoSubscribeAudio.SetValue(true);
// 将频道场景设为直播。
options.channelProfile.SetValue(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING);
// 将用户角色设为主播。
options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
// 加入频道。
RtcEngine.JoinChannelWithUserAccount(_token, "testChannel", _account, options);
}
private void SetupVideoSDKEngine()
{
// 创建 IRtcEngine 实例。
RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
RtcEngineContext context = new RtcEngineContext(_appID, 0, CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING, AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT);
// 初始化 IRtcEngine。
RtcEngine.Initialize(context);
}
// 创建用户回调类实例,并设置回调。
private void InitEventHandler()
{
UserEventHandler handler = new UserEventHandler(this);
RtcEngine.InitEventHandler(handler);
}
实现回调类
用户成功加入频道、退出频道,以及发生错误等事件发生时,可以通过回调类获得监听。
// 实现你自己的回调类,可以继承 IRtcEngineEventHandler 接口类实现。
internal class UserEventHandler : IRtcEngineEventHandler
{
private readonly RayVisionWithAgora _audioSample;
internal UserEventHandler(RayVisionWithAgora audioSample)
{
_audioSample = audioSample;
}
// 发生错误回调。
public override void OnError(int err, string msg)
{
Debug.Log("err:" + err + ", msg:" + msg);
}
// 本地用户成功加入频道时,会触发该回调。
public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
{
Debug.Log("OnJoinChannelSuccess _channelName");
}
// 远端用户成功加入频道时,会触发该回调。
public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
{
Debug.Log("Remote user joined");
}
public override void OnUserStateChanged(RtcConnection connection, uint remoteUid, uint state)
{
base.OnUserStateChanged(connection, remoteUid, state);
}
public override void OnLocalUserRegistered(uint uid, string userAccount)
{
base.OnLocalUserRegistered(uid, userAccount);
}
// 远端用户离开当前频道时会触发该回调。
public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
{
}
}
离开频道
public void Leave()
{
// 离开频道。
RtcEngine.LeaveChannel();
// 关闭音频模块。
RtcEngine.DisableAudio();
}
销毁音频组件
void OnApplicationQuit()
{
if (RtcEngine != null)
{
Leave();
// 销毁 IRtcEngine。
RtcEngine.Dispose();
RtcEngine = null;
}
}