【2024】uniapp 接入声网音频RTC【H5+Android】Unibest模板下Vue3+Typescript

需求

最近开发一个项目,需要实现声网的接入。由于采用uniapp模式,按照最佳实践采用优先开发H5再适配的模式。因此实现了H5和Android两种模式的接入,Android里采用离线打包自定义基座来进行调试。怕自己忘记了,在这里详细的记录完整的核心整合逻辑

准备

开始前,准备了以下组件:

unibest        菲鸽开源的uniapp模板,对于安卓代码,采用的是中间编译模式。因此APP模式下已经是混淆压缩过的代码了,即使采用uniapp云打包上传代码,也是相对的安全。当然对于咱的开发来说可以更抠门一点,连云打包都不用了,直接离线编译基座🤪(项目没上线,银子有限而已)

JDK        万年不变的1.8版本,主要是因为下来的参考代码也都是jdk1.8编译级别的

AndroidStudio        版本是2024.1.2,SDK下载了30和28的版本(为什么是28?因为目前各大市场都要求最低最少兼容安卓9.0)

HBuilder安卓示例        这个是HBuilder的安卓示例项目。里面包含了AS插件项目以及AS整合项目。你需要以这个为基础项目来参考修改。【福利】百度网盘太慢,这里我自己收录了一份

Agora-RTC_3.7.0_example        AgoraRTC SDK使用的示例项目,由于unibest使用的是Typescript,因此需要这个项目里包含的typescript模式的sdk使用代码

Agora-RTC_3.7.2        AgoraRTC的uniapp插件包,可以从DCloud市场下载,里面包含了安卓插件编译aar文件

接入步骤

H5接入

H5接入的前提假设你使用unibest模板建立了一个基础项目。

1.添加npm组件

首先是给项目添加npm组件

pnpm i agora-rtc-sdk-ng

2.导入组件

在页面的script头部申明导入

import AgoraRTC, { IAgoraRTCClient } from 'agora-rtc-sdk-ng'

3.定义控制对象

对于H5,我们只需要两个组件变量即可,一个是RTC客户端,一个是用于控制本地音频采集的本地音轨

let client: IAgoraRTCClient, localAudioTrack

4.初始化引擎

client = AgoraRTC.createClient({ mode: 'rtc', codec: 'h264' })

5.订阅音轨

这样可以收听到其它用户声音,注意时间额度用光后,这里是进不来的

      client.on('user-published', async (user, mediaType) => {// 声网IP/ID每日免费额度到了后这里进不来(大坑)console.log('==== start subscribe audio track ====')// 开始订阅远端用户。await client.subscribe(user, mediaType)console.log('subscribe success')// 表示本次订阅的是音频。if (mediaType === 'audio') {// 订阅完成后,从 `user` 中获取远端音频轨道对象。const remoteAudioTrack = user.audioTrack// 播放音频因为不会有画面,不需要提供 DOM 元素的信息。remoteAudioTrack.play()}})

6.加入Channel

这里由于我们后端采用的是雪花分片算法,属于64位长整型,因此不能直接采用number传入,这里有坑。API备注写的很清楚,如果要长整型的用户ID,请使用string传入

生成token其它文章官网或其它的文章很多,我就不啰嗦了,包括生成临时token或者channel专用token。不懂生成token的先搜索下其他文章。appId是你在声网建立的应用ID。

      const uid = await client.join(groupVoiceConf.appId,groupId.toString(),groupVoiceConf.token,currentUserId.toString())

7.发布音频

发布和停止发布音频即上麦和下麦功能。

上麦代码:

  try {if (client) {localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack()await client.publish(localAudioTrack) // 发布音频}} catch (e) {console.log(e)}

下麦代码:

  try {if (localAudioTrack) {await client.unpublish(localAudioTrack)localAudioTrack.stop()localAudioTrack.close()}} catch (e) {console.log(e)}

8.离开频道

离开频道后不会收听以及发言,代码如下:

  if (client) await client.leave()

9.HTML引擎不支持怎么办

对于某些精简的浏览器以及小米浏览器,存在无法兼容AgoraRTC代码的情况。是否可以根据支持情况提前判断呢?其实AgoraRTC提供了检测API checkSystemRequirements,只需要先检测,然后再执行RTC的代码即可,格式看上去这样的:

  const result = AgoraRTC.checkSystemRequirements()if (result) {try {// your RTC code} catch (e) {console.log(e)}} else {utils.alert('您的浏览器不支持交互语音')}

注意RTC引擎都是Promise结构,因此都需要await调用和try...catch接口来判断调用失败

另外请在https环境下执行代码(搜一下plugin-basic-ssl把这个接入到vite去),直接在http环境下功能是受限制的。

另外按照官方的要求,自己生成token后,是需要定时刷新的,这部分代码页面使用一个定时器刷新即可,具体代码请自己琢磨前后端代码。

安卓接入

由于unibest开发模式推荐VSCode不是基于HBuilder,这里会有取舍:

坏处:不能像直接使用HBuilder那样在Manifest提供多个可视化选项来进行插件云打包。
好处:如果不用打自定义基座,云打包上传的代码都是压缩编译过的,相对来说比较安全。

虽然无法直接使用云打包的插件,但是我们可以使用离线打包,来弥补这个不足。

注意后面如果不特别说明,项目都是指AndroidStudio项目。

1.导入AS

我们解开Android-SDK@4.28.82186_20240923.zip,将里面的HBuilder-Integrate-AS目录释放到一个文件夹,将这个项目导入到AndroidStudio,开始配置。

2.AS配置:证书

按照官网的流程,生成自己的证书,并上传到DCloud后台(这里不是HBuilder,要登录DCloud开发者平台)。详细的自己查,这里只记录几个简要的流程:
生成证书:

set PATH=C:/JDK11/bin
keytool -genkey -alias <aliasName> -keyalg RSA -keysize 2048 -validity 36500 -keystore simpleDemo/<aliasName>.keystore

 aliasName以及密码等根据自己实际情况设置。注意后面上传到DCloud后台要用这些信息的。

查看填写到DCloud后台的几个信息

set PATH=C:/JDK11/bin
keytool -list -v -keystore simpleDemo/<aliasName>.keystore
pause

查看时要输入前面genkey时的密码

然后要把证书的几个信息都配置到simpleDemo/build.gradle的signingConfigs

    signingConfigs {config {keyAlias '<aliasName>'keyPassword '<yourPass>'storeFile file('<aliasName>.keystore')storePassword '<yourStorePass>'v1SigningEnabled truev2SigningEnabled true}}

建议前面的keypass和storepass设置成一致,免得密码太多了操作蛋疼

这里有坑,注意如果上传DCloud后台时包名发生了变更,也一定要在AndroidManifest.xml里修改包名,不然有签名设置不正确报错

3.AS配置:权限

打开项目的manifests/AndroidManifest.xml,在<manifest xmlns:android>这个节点下加入权限申明(本项目只使用音频):

    <!-- 声音 --><uses-permission android:name="android.permission.RECORD_AUDIO"/><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

4.AS配置:开启调试

修改项目的assets/data/dcloud_control.xml,将根节点修改为以下格式:

<hbuilder debug="true" syncDebug="true">

这个模式表示是打包自定义调试基座,如果要做正式发布时,要把debug和syncDebug去掉

另外按照uniapp整合规范,需要把appid修改为你自己项目的appid值        

5.AS配置:相关的gradle组件包

打开项目根目录下的simpleDemo/build.gradle,在dependencies节点下添加4个组件

    implementation 'io.agora.rtc:agora-special-full:3.7.2.4'implementation 'io.agora.rtc:full-screen-sharing:3.7.2.4'implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.3.50'//自定义基座需要的implementation 'com.squareup.okhttp3:okhttp:4.12.0'

okhttp如果不导入的话,当做自定义基座就会无法将调试信息发送到HBuilder,如果你用adb的话就无所谓。建议始终带上。

另外在Agora-Uniapp-SDK.zip里找到uniplugin_agora_rtc-release.aar,把这个放入项目simpleDemo\libs下。如果要打正式release包,要把这个组件去掉,不用删除,直接写在exclude里好了:

    implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: ['debug-server-release.aar'])

然后记得点AS菜单File->Sync Project With Gradle Files

6.AS配置:配置自定义插件

在项目simpleDemo\assets下建立文件dcloud_uniplugins.json,内容如下:

{"nativePlugins": [{"plugins": [{"type": "module","name": "Agora-RTC-EngineModule","class": "io.agora.rtc.uni.AgoraRtcEngineModule"},{"type": "module","name": "Agora-RTC-ChannelModule","class": "io.agora.rtc.uni.AgoraRtcChannelModule"},{"type": "component","name": "Agora-RTC-SurfaceView","class": "io.agora.rtc.uni.AgoraRtcSurfaceView"},{"type": "component","name": "Agora-RTC-TextureView","class": "io.agora.rtc.uni.AgoraRtcTextureView"}]}]
}

7.链接你的编译结果

在你的unibest项目下执行命令

pnpm build:app-android --mode production

然后把项目dist\build\app拷贝到项目的simpleDemo/assets/apps/<你项目的UNIAPP_ID>/www下。

如果你嫌每次拷贝麻烦,直接建立一个软链接过去就好(WINDOWS下不会?搜一下mklink怎么用)

最后一步,注意了,我就是在这里没操作正确导致卡了2天。

删除项目下的simpleDemo/build目录,然后
A)出基座,使用Build -> Build App Bundle(s)/APK(s)
B)出release,使用Build -> Generate Singed App Bundle /APK

如果你的操作正确,后面接入代码后HBuilder启动时就不会出现下面报错:

[JS Framework] 当前运行的基座不包含原生插件[Agora-RTC-ChannelModule],请在manifest中配置该插件,重新制作包括该原生插件的自定义运行基座

[JS Framework] 当前运行的基座不包含原生插件[Agora-RTC-EngineModule],请在manifest中配置该插件,重新制作包括该原生插件的自定义运行基座

8.接入TypeScript组件

下一步要接入代码了,但是unibest是Typescript代码,Agora-RTC_3.7.0_example里的就不顶用了。实际上,在官网github里有一份typescript代码,只是没放到发布包里。从github里把整个项目下下来,找到src/components,把整个目录放到unibest项目的src/components下。在VSCode里看上去的文件是这样:

9.引入组件

然后就可以在语音界面开始调用了,script里引入组件

import RtcEngine, { RtcChannel } from '../../components/Agora-RTC-JS/index'
import { ClientRole, ChannelProfile } from '../../components/Agora-RTC-JS/common/Enums'

10.定义rtcEngine

APP这里定义变量简单点,只需要定义好rtcEngine即可

let rtcEngine: RtcEngine

11.初始化引擎

申请录音权限是自己的框架代码,您可以自己封装一下。然后就是收听其它人员,加入频道等。这里就不一一解释了,加入频道支持雪花ID需要使用joinChannelWithUserAccount。代码在下面

  if (uni.getSystemInfoSync().platform === 'android') {// 华为市场规范,先申请权限await requestPermission('RECORD', '用于听美丽的歌声啊啊啊啊')}rtcEngine = await RtcEngine.create(groupVoiceConf.appId) // 创建引擎await rtcEngine.enableAudio() // 收听其它伙伴的发言await rtcEngine.setChannelProfile(ChannelProfile.LiveBroadcasting)await rtcEngine.setClientRole(ClientRole.Broadcaster)await rtcEngine.joinChannelWithUserAccount(groupVoiceConf.token,groupId.toString(),currentUserId.toString())await rtcEngine.enableLocalAudio(false) // 默认进入频道麦克风是开启的,需要关闭

12.上/下麦

代码如下

  await rtcEngine.enableLocalAudio(true) // 上麦await rtcEngine.enableLocalAudio(false) // 下麦

12.离开频道

  if (rtcEngine) await rtcEngine.leaveChannel()

IOS接入(略)

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

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

相关文章

Hadoop之WordCount测试

1、Hadoop简介&#xff1a; Hadoop是Apache旗下的一个用Java语言实现的开源软件框架&#xff0c;是一个开发和运行处理大规模数据的软件平台。 Hadoop的核心组件包括Hadoop分布式文件系统&#xff08;HDFS&#xff09;和MapReduce编程模型。HDFS是一个高度容错的系统&#xf…

OpenGL笔记十九之相机系统

OpenGL笔记十九之相机系统 —— 2024-10-02 晚上 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记十九之相机系统1.运行1.1.游戏相机1.2.轨迹球相机 2.游戏相机与轨迹球相机切换3.博主笔记本要运行需要更改的文件更改1:28_OpenGL_CameraSystem/applicat…

基于SpringBoot的学习资源共享平台

运行环境: jdk8tomcat9mysqlIntelliJ IDEAmavennodejs 设计选用前后端分离的单体架构方式 后端&#xff1a;SpringBootMybatis-PluslogbackElasticsearchRedisMySQLJwtsmtp阿里云OSS 前端&#xff1a;WebPackVueJsAnt Designaxios 主要模块&#xff1a;反馈管理、资源管理、…

GitLab flow工作流及其使用

问题背景 Git flow和Github flow及其问题 使用GitLab flow 目录 什么是GitLab工作流 功能分支 生产分支 使用GitLab flow环境分支 使用GitLab flow发布分支 使用GitLab flow合并/拉取请求 使用GitLab flow进行问题跟踪 链接和关闭合并请求中的问题 用rebase压缩提交…

实战案例:结合大模型与爬虫技术实现12306智能查票系统

大语言模型&#xff0c;例如 GPT-4&#xff0c;拥有强大的知识储备和语言理解能力&#xff0c;能够进行流畅的对话、创作精彩的故事&#xff0c;甚至编写代码。然而&#xff0c;它们也面临着一些难以克服的困境&#xff0c;就像一个空有知识却无法行动的巨人 信息滞后&#xf…

[ESP32]ESP-IDF使用组件添加U8g2图形库

U8g2 在ESP32使用u8g2的时候可以使用添加component的方式进行, 由于官方的component库没有, 这里我找到了一个可以使用的github库, 使用git的方式进行添加这一个库 具体的原理可以看[官方手册](https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-guides/to…

使用seata管理分布式事务

做应用开发时&#xff0c;要保证数据的一致性我们要对方法添加事务管理&#xff0c;最简单的处理方案是在方法上添加 Transactional 注解或者通过编程方式管理事务。但这种方案只适用于单数据源的关系型数据库&#xff0c;如果项目配置了多个数据源或者多个微服务的rpc调用&…

C语言 | Leetcode C语言题解之第459题重复的子字符串

题目&#xff1a; 题解&#xff1a; bool kmp(char* query, char* pattern) {int n strlen(query);int m strlen(pattern);int fail[m];memset(fail, -1, sizeof(fail));for (int i 1; i < m; i) {int j fail[i - 1];while (j ! -1 && pattern[j 1] ! pattern…

63.5 注意力提示_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录注意力提示生物学中的注意力提示查询、键和值注意力的可视化使用 show_heatmaps 显示注意力权重代码示例 代码解析结果 小结练习 注意力提示 &#x1f3f7;sec_attention-cues 感谢读者对本书的关注&#xff0c;因为读者的注意力是一种稀缺…

在Linux系统安装Nginx

注意&#xff1a;Nginx端口号是80(云服务器要放行) 我的是基于yum源安装 安装yum源(下面这4步就好了) YUM源 1、将源文件备份 cd /etc/yum.repos.d/ && mkdir backup && mv *repo backup/ 2、下载阿里源文件 curl -o /etc/yum.repos.d/CentOS-Base.repo ht…

LabVIEW机床加工监控系统

随着制造业的快速发展&#xff0c;机床加工的效率与稳定性成为企业核心竞争力的关键。传统的机床监控方式存在效率低、无法远程监控的问题。为了解决这些问题&#xff0c;开发了一种基于LabVIEW的机床加工监控系统&#xff0c;通过实时监控机床状态&#xff0c;改进生产流程&am…

安卓 /proc 目录详解:从内核到进程的桥梁

在安卓系统中&#xff0c;/proc 目录是开发者、调试者、甚至是普通用户深入了解系统状态、性能及行为的一个重要入口。这个虚拟文件系统不仅包含了丰富的内核信息&#xff0c;还反映了运行中的每个进程的状态。 /proc 文件系统 /proc 文件系统&#xff08;procfs&#xff09;是…

振动分析-30-振动信号的幅值概率密度函数CWRU西楚大学轴承数据(实战)

文章目录 1 背景2 幅值概率密度函数3 实现流程3.1 自定义函数3.2 模拟正弦信号4 CWRU轴承数据4.1 加载数据4.2 相同工况不同故障4.3 相同数据不同份数5 参考附录1 背景 很多初学者刚接触故障诊断可能觉得很简单,套用深度学习模型进行训练,分类准确率达到99%即可。 在写论文时…

AL生成文章标题指定路径保存:创新工具助力内容创作高效启航

在信息爆炸的时代&#xff0c;一个吸引人的标题是文章成功的第一步。它不仅要准确概括文章内容&#xff0c;还要能激发读者的好奇心&#xff0c;促使他们点击阅读。随着人工智能技术的飞速发展&#xff0c;AL生成文章标题功能正逐渐成为内容创作者的新宠&#xff0c;看看它是如…

Python基本库的使用--urllib

开篇 本篇文章旨在总结urlib基本库的一些常用用法。 相关方法 urlopen 用户打开和读取URL。 import urllib.requestresponse urllib.request.urlopen(https://www.python.org) print(response.read().decode(utf-8))带data参数 import urllib.parse import urllib.requestda…

队列的实现与讲解

一.概念与结构 1.概念 只允许在⼀端进行插⼊数据操作&#xff0c;在另⼀端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出FIFO(First In First Out) ​ 入队列&#xff1a;进⾏插⼊操作的⼀端称为队尾 ​ 出队列&#xff1a;进⾏删除操作的⼀端称为队头 注意&…

WebRTC Connection Negotiate解决

最近有个项目 &#xff0c;部署之后一直显示&#xff0c;查了一些资料还是没有解决&#xff0c;无奈只有自己研究解决&#xff1f; 什么是内网穿透&#xff1f; 我们访问我们自己的官网产品页面&#xff0c;我们的服务器是一个单独的个体&#xff0c;有独立的公网ip&#xf…

2024年10月6日历史上的今天大事件早读

23年10月06日西汉“新莽政权”领袖王莽被刺身亡 1866年10月06日清政府批准筹设天津机器局 1905年10月06日俄国爆发铁路工人大罢工 1913年10月06日中、英西姆拉会商“西藏问题” 1927年10月06日阿尔-乔尔森主演第一部有声电影 1940年10月06日新四军获黄桥决战胜利 1949年1…

《迁移学习》—— 将 ResNet18 模型迁移到食物分类项目中

文章目录 一、迁移学习的简单介绍1.迁移学习是什么&#xff1f;2.迁移学习的步骤 二、数据集介绍三、代码实现1. 步骤2.所用到方法介绍的文章链接3. 完整代码 一、迁移学习的简单介绍 1.迁移学习是什么&#xff1f; 迁移学习是指利用已经训练好的模型&#xff0c;在新的任务上…

Windows应急响应-Auto病毒

文章目录 应急背景分析样本开启监控感染病毒查看监控分析病毒行为1.autorun.inf分析2.异常连接3.进程排查4.启动项排查 查杀1.先删掉autorun.inf文件2.使用xuetr杀掉进程3.启动项删除重启排查入侵排查正常流程 应急背景 运维人员准备通过windows共享文档方式为公司员工下发软件…