unity 使用声网(Agora)实现语音通话

第一步、先申请一个声网账号
[Agora官网链接](https://console.shengwang.cn/)
第二步在官网创建项目 ,选择无证书模式,证书模式需要tokenh和Appld才能通话
在这里插入图片描述
第三步 官网下载SDK 然后导入到unity,也可以直接在unity商店里下载,Agora官网下载链接
在这里插入图片描述
第四步 运行官方Demo
1、导入后会有这些文件
在这里插入图片描述
2、从官网新建的项目复制AppID,粘贴到这个位置,如果使用的是证书模式,Token也需要填写,否者运行报错110,第三个变量是频道,可以自定义, ,Examples里的场景都是Demo,
在这里插入图片描述
3、找到这个场景,这个是语音通话的Demo场景
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
按照以上步骤,这是运行,就可以实现语音通话了,
如果运行有显示110等错误码,可以查看官网的解决方法,
错误码处理链接

声网每个月有一万分钟免费时长,非常赞
也可以按照官方文档去实现语音通话,文档写的非常清楚,代码都有,我按照吧官方文档的代码粘贴到一个脚本里,运行完全没问题,
上脚本(外加了一些回调事件的补充),

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 updatevoid 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 framevoid 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包,在另一台电脑运行,也点击加入频道。
以下是运行效果,如果另外一台也加入频道,上面会显示远端用户加入频道,
在这里插入图片描述

借鉴的文章
这个文章里有视频通话,需要的小伙伴可以看这个

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/80655.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux界的老古董

Slackware 是由 Patrick Volkerding 制作的 Linux 发行版&#xff0c;从 1993 年发布至今也一直在 Patrick 带领下进行维护。7 月 17 日&#xff0c;Slackware 才刚刚过完它 24 岁的生日&#xff0c;看似年纪轻轻的它&#xff0c;已然是 Linux 最古老的发行版。 Slackware 的发…

第 363 场 LeetCode 周赛题解

A 计算 K 置位下标对应元素的和 模拟 class Solution { public:int pop_cnt(int x) {//求x的二进制表示中的1的位数int res 0;for (; x; x >> 1)if (x & 1)res;return res;}int sumIndicesWithKSetBits(vector<int> &nums, int k) {int res 0;for (int i…

Linux文件属性操作函数

1.access函数 #include <unistd.h> int access(const char *pathname, int mode); 作用&#xff1a;判断某个文件是否有某个权限&#xff0c;或者判断文件是否存在 参数: -pathname:判断的文件路径 -mode: R_OK&#xff1a;判断是否有读权限 W_OK X_OK F_OK&#xff1a;…

【海报生成器源码】设计海报生成器网站开源源码(更新)

源码简介: 随着社会经济和商业发展&#xff0c;对产品宣传的需求也加大了。如何快速制作海报也成了很大的需求。这里分享的是一个海报生成器网站的最新源代码。 这个海报编辑器有着实用强大的功能&#xff0c;它的最左侧是组件列表。可以在最左侧选择组件&#xff0c;比如文本…

华为云云耀云服务器L实例评测 | 开启OPC UA之旅

OPC Unified Architecture (OPC UA)是一种用于工业自动化的M2M协议(Machine-to-machine)&#xff0c;具有平台独立性&#xff0c;在Windows和Linux上都可以运行。随着云服务在工业现场的不断普及&#xff0c;OPCUA服务也开始大量部署在云端。 本文以华为云云耀云服务器L为基础…

3D目标检测数据集 KITTI(标签格式解析、点云转图像、点云转BEV)

本文介绍在3D目标检测中&#xff0c;理解和使用KITTI 数据集&#xff0c;包括KITTI 的基本情况、下载数据集、标签格式解析、点云转图像、点云转BEV。 目录 1、KITTI数据集中3D框可视化的效果 2、先看个视频&#xff0c;了解KITTI 的基本情况 3、来到KITTI官网&#xff0c;下…

计算机竞赛 机器视觉的试卷批改系统 - opencv python 视觉识别

文章目录 0 简介1 项目背景2 项目目的3 系统设计3.1 目标对象3.2 系统架构3.3 软件设计方案 4 图像预处理4.1 灰度二值化4.2 形态学处理4.3 算式提取4.4 倾斜校正4.5 字符分割 5 字符识别5.1 支持向量机原理5.2 基于SVM的字符识别5.3 SVM算法实现 6 算法测试7 系统实现8 最后 0…

Docker Swarm集群部署

Docker Swarm集群部署 任务平台 3台虚拟机&#xff0c;一台作为manager 节点&#xff0c;另两台作为work节点。 文章目录 Docker Swarm集群部署安装docker配置防火墙开放端口在 manager 节点创建 Swarm 集群创建用于swarm服务的自定义的overlay网络测试跨主机容器通信 安装do…

React使用useImperativeHandle实现父组件触发子组件事件

相关知识&#xff1a; useImperativeHandle forwardRef 相关代码&#xff1a; 获取子组件实例&#xff0c;由于这是函数组件&#xff0c;没有this因此不能整体获取&#xff0c;我们可以通过useImperativeHandle获取想要的变量或者方法。 父组件import React, { useRef } fro…

【华为云云耀云服务器L实例评测|云原生】自定制轻量化表单Docker快速部署云耀云服务器

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

CSS 浮动布局

浮动的设计初衷 float: left/right/both;浮动是网页布局最古老的方式。 浮动一开始并不是为了网页布局而设计&#xff0c;它的初衷是将一个元素拉到一侧&#xff0c;这样文档流就能够包围它。 常见的用途是文本环绕图片&#xff1a; 浮动元素会被移出正常文档流&#xff0c;…

【算法|链表】环形链表Ⅱ

环形链表Ⅱ 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统…

无涯教程-JavaScript - COS函数

描述 COS函数返回给定Angular的余弦值。 语法 COS (number)争论 Argument描述Required/OptionalNumber The angle in radians for which you want the cosine.Required Notes 如果Angular以度为单位,则将Angular乘以PI()/180或使用RADIANS函数将Angular转换为弧度 弧度(…

Python 魔法方法

视频版教程 Python3零基础7天入门实战视频教程 Python的魔法方法&#xff0c;也称为特殊方法或双下划线方法&#xff0c;是一种特殊的方法&#xff0c;用于在类中实现一些特殊的功能。这些方法的名称始终以双下划线开头和结尾&#xff0c;例如__init__&#xff0c;repr&#x…

uniapp实现大气质量指标图(app端小程序端均支持,app-nvue不支持画布)

效果图如下&#xff1a; 思路&#xff1a; 1.首先我想到的就是使用图标库echarts或ucharts&#xff0c;可是找了找没有找到类似的。 2.其次我就想用画布来实现这个效果&#xff0c;直接上手。&#xff08;app-vue和小程序均可以实现&#xff0c;但是在app-nvue页面不支持画布…

033:跨域,vue端和 Nignx反向代理的配置详细解析

第033个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

Linux调试器-gdb使用

目录 一、gdb的使用 二、查看可执行程序的信息&#xff08;readelf&#xff09; 三、gdb常用的指令 1. 显示源代码&#xff08;list/l&#xff09; 2. 运行程序&#xff08;r或run&#xff09; 3. 在某一行设置断点&#xff08;b指令&#xff09; 4. 显示断点&#xff0…

Logstash介绍

Logstash介绍 Logstash是一个开源数据收集引擎&#xff0c;具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来&#xff0c;并将数据标准化到你所选择的目的地。 集中、转换和存储你的数据 Logstash是一个开源的服务器端数据处理管道&#xff0c;可以同时从多…

0.UML

1.图 1.1类图含义 第一层显示类的名称,如果是抽象类,则就用斜体显示。第二层是类的特性,通常就是字段和属性。第三层是类的操作,通常是方法或行为。注意前面的符号, ,表示public,-,表示private,#,表示protected。 1.2接口图 与类图的区别主要是顶端有<< interface >…

esp32-S3-electric-vehicle-expansion(EVE_V2)硬件分享

一. 简介 本次将给大家分享一个QSPI圆形屏幕DIY的小项目&#xff0c;这是我做的第二个版本的&#xff0c;相较于第一个版本有了比较大的改动(第一版就不放出来了&#xff0c;需要的可以私聊)&#xff0c;可以在上面实现更多的功能&#xff0c;做些更有趣的项目 &#xff0c;也…