第一步、先申请一个声网账号
[Agora官网链接](https://console.shengwang.cn/)
第二步在官网创建项目 ,选择无证书模式,证书模式需要tokenh和Appld才能通话
第三步 官网下载SDK 然后导入到unity,也可以直接在unity商店里下载,Agora官网下载链接
第四步 运行官方Demo
1、导入后会有这些文件
2、从官网新建的项目复制AppID,粘贴到这个位置,如果使用的是证书模式,Token也需要填写,否者运行报错110,第三个变量是频道,可以自定义, ,Examples里的场景都是Demo,
3、找到这个场景,这个是语音通话的Demo场景
按照以上步骤,这是运行,就可以实现语音通话了,
如果运行有显示110等错误码,可以查看官网的解决方法,
错误码处理链接
声网每个月有一万分钟免费时长,非常赞
也可以按照官方文档去实现语音通话,文档写的非常清楚,代码都有,我按照吧官方文档的代码粘贴到一个脚本里,运行完全没问题,
上脚本(外加了一些回调事件的补充),
csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Agora.Rtc;
using UnityEngine.UI;
using UnityEngine.Serialization;
using Agora_RTC_Plugin.API_Example;
using Logger = Agora_RTC_Plugin.API_Example.Logger;
public class Test : MonoBehaviour
{
[FormerlySerializedAs("appIdInput")]
[SerializeField]
private AppIdInput _appIdInput;
// 填入你的 app ID。
private string _appID = "";
// 填入你的频道名。
private string _channelName = "";
// 填入 Token。
private string _token = "";
internal IRtcEngine RtcEngine;
public Text conten;
internal Logger Log;
// Start is called before the first frame update
void Start()
{
LoadAssetData();
if(CheckAppId() )
{
SetupVideoSDKEngine();
InitEventHandler();
SetupUI();
}
}
private void LoadAssetData()
{
if (_appIdInput == null) return;
_appID = _appIdInput.appID;
_token = _appIdInput.token;
_channelName = _appIdInput.channelName;
}
private bool CheckAppId()
{
Log = new Logger(conten);
return Log.DebugAssert(_appID.Length > 10, "Please fill in your appId in API-Example/profile/appIdInput.asset!!!!!");
}
// Update is called once per frame
void Update()
{
CheckPermissions();
}
void OnApplicationQuit()
{
if (RtcEngine != null)
{
Leave();
// 销毁 IRtcEngine。
RtcEngine.Dispose();
RtcEngine = null;
}
}
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);
}
private void SetupUI()
{
GameObject go = GameObject.Find("Leave");
go.GetComponent<Button>().onClick.AddListener(Leave);
go = GameObject.Find("Join");
go.GetComponent<Button>().onClick.AddListener(Join);
}
public void Join()
{
Debug.Log("Joining _channelName");
// 启用音频模块。
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);
// 加入频道
// channelKey: 动态秘钥,无证书模式(非安全模式)传入 null;安全模式需要传入服务器生成的 Token
// channelName: 频道名称
// info: 开发者附带信息(非必要),不会传递给频道内其他用户
// uid: 用户ID,0 为自动分配
RtcEngine.JoinChannel(_token, _channelName, 0, options);
}
public void Leave()
{
Debug.Log("Leaving _channelName");
// 离开频道。
RtcEngine.LeaveChannel();
// 关闭音频模块。
RtcEngine.DisableAudio();
}
private void CheckPermissions()
{
#if (UNITY_2018_3_OR_NEWER && UNITY_ANDROID)
foreach (string permission in permissionList)//检查麦克风
{
if (!Permission.HasUserAuthorizedPermission(permission))
{
Permission.RequestUserPermission(permission);
}
}
#endif
}
}
// 实现你自己的回调类,可以继承 IRtcEngineEventHandler 接口类实现。
internal class UserEventHandler : IRtcEngineEventHandler
{
private readonly Test _audioSample;
internal UserEventHandler(Test audioSample)
{
_audioSample = audioSample;
}
// 发生错误回调。
public override void OnError(int err, string msg)
{
}
// 当前通话统计回调,每两秒触发一次。
public override void OnRtcStats(RtcConnection connection, RtcStats stats)
{
}
// Token 过期回调
public override void OnRequestToken(RtcConnection connection)
{
}
// Token 即将过期提醒
public override void OnTokenPrivilegeWillExpire(RtcConnection connection, string token)
{
base.OnTokenPrivilegeWillExpire(connection, token);
}
/// <summary>
/// 网络发生变化时的回调
/// </summary>
/// <param name="connection"></param>
/// <param name="state">当前连接的状态</param>
/// <param name="reason">连接状态改变的原因</param>
public override void OnConnectionStateChanged(RtcConnection connection, CONNECTION_STATE_TYPE state, CONNECTION_CHANGED_REASON_TYPE reason)
{
}
// 网络中断回调(建立成功后才会触发)
public override void OnConnectionInterrupted(RtcConnection connection)
{
}
// 网络连接丢失回调
public override void OnConnectionLost(RtcConnection connection)
{
base.OnConnectionLost(connection);
}
//重新链接网络后加入频道
public override void OnRejoinChannelSuccess(RtcConnection connection, int elapsed)
{
}
// 本地用户成功加入频道时,会触发该回调。
// channelId:频道名称
// uid:用户ID(发起请求时候如果没有指定,服务器会自动分配一个)
// elapsed:从本地用户调用 JoinChannelByKey 到该回调触发的延迟(毫秒)。
public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
{
string joinChannelMessage = string.Format("用户ID:{0},加入频道:{1}", connection.localUid, connection.channelId);
_audioSample.Log.UpdateLog(joinChannelMessage);
}
// 本地用户离开频道的回调
// stats:通话统计的数据
// duration:通话时长
// txBytes:发送字节数(bytes)
// rxBytes:接收字节数(bytes)
// txKBitRate:发送码率(kbps)
// rxKBitRate:接收码率(kbps)
public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
{
string leaveMessage = string.Format("用户ID:{0},离开频道:{1},通话时长:{2}秒", connection.localUid, connection.channelId, stats.duration);
_audioSample.Log.UpdateLog(leaveMessage);
}
// 远端用户成功加入频道时,会触发该回调。
public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
{
string userJoinedMessage = string.Format("远端用户ID:{0},加入频道:{1}", uid, connection.channelId);
_audioSample.Log.UpdateLog(userJoinedMessage);
}
// 远端用户离开当前频道时会触发该回调。
// reason:离线原因(主动离开、超时、直播模式身份切换)
public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
{
string userOfflineMessage = string.Format("远端用户ID:{0},离开频道:{1}", uid, connection.channelId);
_audioSample.Log.UpdateLog(userOfflineMessage);
}
// 提示频道内谁在说话
// speakers:说话人信息
// speakerNumber:说话人数[0,3]
// totalVolume:总音量
public override void OnAudioVolumeIndication(RtcConnection connection, AudioVolumeInfo[] speakers, uint speakerNumber, int totalVolume)
{
base.OnAudioVolumeIndication(connection, speakers, speakerNumber, totalVolume);
}
// 用户静音提示回调
// uid:用户 ID
// muted:是否静音
public override void OnUserMuteAudio(RtcConnection connection, uint remoteUid, bool muted)
{
base.OnUserMuteAudio(connection, remoteUid, muted);
}
}
脚本使用方法,新建一个场景,以及搭两个按钮,和一个滑动框,把脚本随便挂载一个物体身上即可,
ContentSizeFitter可以让UI随文字自适应
然后运行,点击加入频道,打包PC包,在另一台电脑运行,也点击加入频道。
以下是运行效果,如果另外一台也加入频道,上面会显示远端用户加入频道,
这个文章里有视频通话,需要的小伙伴可以看这个