1、TRTC是什么
实时音视频(Tencent RTC)基于腾讯21年来在网络与音视频技术上的深度积累,以多人音视频通话和低延时互动直播两大场景化方案,通过腾讯云服务向开发者开放,致力于帮助开发者快速搭建低成本、低延时、高品质的音视频互动解决方案。
对于即时通信,腾讯有着深度的技术积累,QQ、微信的音视频通话、腾讯会议,这些常用的场景都是基于TRTC技术方案,TRTC不仅有着详尽的官方API文档,还提供了详细的demo演示,社区也非常完善。
流程图
2、简述TRTC中的核心概念
(1)房间
房间是TRTC的虚拟概念,本质上用于用户之间的信息隔离,一个ID对应一个房间号,TRTC云服务通过房间ID确定音视频信息流要发送给哪些人。加入房间,是音视频通讯的开始,退出房间,是音视频通讯的结束。
(2)trtc-wx.js文件
trtc-wx.js是管理 TRTC 状态的类文件,它集成了腾讯云的trtc-room协议,同时集成了很多操作TRTC的方法,trtc-wx 可以管理所有与实时音视频相关的状态,以及调用挂载在live-pusher/live-player
上的方法,最终将信息透传到底层,底层调用驱动控制硬件设备,从而对终端硬件进行驱动(摄像头、麦克风、音视频播放等)。
trtc-wx SDK 意在帮助用户处理原生标签复杂的状态码以及各种属性状态变更。用户通过对live-pusher/live-player
标签绑定回调,从而与 trtx-wx.js 建立联系:
<live-pusher
url="{{pusher.url}}"
bindstatechange="_pusherStateChangeHandler"
bindnetstatus="_pusherNetStatusHandler"
binderror="_pusherErrorHandler"
bindbgmstart="_pusherBGMStartHandler"
bindbgmprogress="_pusherBGMProgressHandler"
bindbgmcomplete="_pusherBGMCompleteHandler"
bindaudiovolumenotify="_pusherAudioVolumeNotify"
/>
// 请保持跟 wxml 中绑定的事件名称一致
_pusherStateChangeHandler(event) {
this.TRTC.pusherEventHandler(event)
},
_pusherNetStatusHandler(event) {
this.TRTC.pusherNetStatusHandler(event)
},
_pusherErrorHandler(event) {
this.TRTC.pusherErrorHandler(event)
},
_pusherBGMStartHandler(event) {
this.TRTC.pusherBGMStartHandler(event)
},
_pusherBGMProgressHandler(event) {
this.TRTC.pusherBGMProgressHandler(event)
},
_pusherBGMCompleteHandler(event) {
this.TRTC.pusherBGMCompleteHandler(event)
},
_pusherAudioVolumeNotify(event) {
this.TRTC.pusherAudioVolumeNotify(event)
}
(3)音视频的推拉流逻辑
小程序通过live-pusher/live-player
与底层建立联系,trtc-wx.js和live-pusher/live-player
的调用逻辑相对简单,他们的调用关系如下:
回到trtc-wx.js,通过以下代码实例化TRTC对象:
import TRTC from '@/common/trtc/trtc-wx.js'
this.TRTC = new TRTC()
通过以下代码返回一个pusher对象,并将相关参数传递给live-pusher标签,这个数据初始化过程完成后,就可以调用this.TRTC.getPusherInstance().start()
进行推流。
this.pusher = this.TRTC.enterRoom({
userID: userId,
sdkAppID: xxx,
userSig: xxx,
roomID: roomId,
enableMic: true,
enableCamera: true
})
3、开发过程中遇到的一些问题:
1、进入房间后越来越卡顿
开启房间后,正常推拉流后开始即时通话,在测试的过程中,出现了一个异常:通话大概2分钟后,页面上的按钮交互出现明显的卡顿。
我们用不同手机进行测试,排除了是终端设备的原因,随后切换不同的网络,从4G、5G到WiFi,甚至把手机放在路由器旁边做测试,发现手机App各种网页、视频加载飞起,但是卡顿问题依然存在...
跑到腾讯云的官方专栏查看是否有类似问题总结,各种社区、博客搜了一遍,发现没有类似的问题记录,接着各种尝试:杀掉小程序,重新加载,手机关机重启,....,问题还是没有解决...
盯着开发调试模式,看着开发模式下欢快的打印着日志,突然想到:有没有可能日志打印过多过于频繁,导致内存占用过大?赶紧试试,先做个测试:for循环console.log()
200次,果然,卡顿问题复现了,经过查找分析,发现控制台打印的日志基本来自trtc-wx.js文件,trtc-wx.js是一个压缩文件,定位到频繁打印的日志有6个:
console.log("Pusher reset",this.context)
console.log("Pusher context.stop()")
console.log(e.currentTarget.dataset,"playerNetStatus")
console.log("pusherInstance",this.pusherInstance)
console.log(e.currentTarget.dataset,"playerAudioVolumeNotify")
console.log(e,"====")
删除以上文件,问题搞定!
2、扬声器设置禁音异常情况
在开启房间后,测试扬声器和麦克风的开启和关闭功能,发现扬声器无法正常设置静音,通过对上行音频流和下行音频流的理解,对pusher / player
的属性进行了有效的设置,示例代码如下:
麦克风:
麦克风是上行本地音视频流,上行指的是音视频采集端将画面通过采集设备(摄像头,麦克风)采集后,通过编码后上行到TRTC服务器,针对麦克风我们操作的对象是pusher,使用 this.TRTC.setPusherAttributes:
pusherAudioHandler() {
let options = {
enableMic: !this.pusher.enableMic, // 关闭音频上行
}
this.pusher = this.TRTC.setPusherAttributes(options)
}
扬声器:
扬声器是下行音视频流,下行是指上行的视频流经过在server处理或者转发后,传输到 CDN 或者观众端。扬声器是本地控制远端流的状态,针对扬声器操作的对象是playerList,如果远端用户超过1个,则需要遍历用户列表,更新soundMode的属性值,使用 this.setPlayerAttributesHandler:
playerSoundModeHandler() {
this.isMuted = !this.isMuted;
this.playerList.forEach(list => {
this.setPlayerAttributesHandler(list, {
soundMode: this.isMuted ? 'ear' : 'speaker',
})
})
}
3、this.setData()引起的坑
this.setData()
是小程序中用于修改页面数据的函数,它会将传入的对象的属性和值应用到小程序页面的数据对象上,并触发页面的重新渲染,这是小程序的响应式设计。this.setData()
有一个页面数据更新渲染完毕后的回调函数
this.setData()
的用法如下:
this.setData({
key: value,
key2: value2,
.......
}, () => { }) //第二个参数是回调函数,可选
官网上的示例代码:
enterRoom(options) {
this.setData({
pusher: this.TRTC.enterRoom( options ),
}, () => {
this.TRTC.getPusherInstance().start() // 开始进行推流
})
}
在项目中,大家基本上都是基于开源框架进行业务开发,习惯上更多的使用如下方式赋值:
this.pusher = this.TRTC.enterRoom({ })
this.TRTC.getPusherInstance().start()
以上写法可能会出现pusher对象还未完成初始化,就开始推流的情况,直观的表现就是用户无法正常进入房间,这里我们可以加一个百毫秒级别的推流延迟:
this.pusher = this.TRTC.enterRoom({
userID: userId,
sdkAppID: xxx,
userSig: xxx,
roomID: roomId,
enableMic: true,
enableCamera: true,
})
setTimeout(() => {
this.TRTC.getPusherInstance().start();
},100)
4、页面效果
5、兼容问题
小程序的兼容问题在开发中经常遇到,可以多逛逛微信开发社区,很多时候可以找到类似问题的解决方案:社区地址,以下是本人在开发过程中遇到的兼容问题:
- 微信APP版本兼容
- 小程序基础库版本兼容
- 不同机型的样式兼容
- 不同机型的日期格式兼容
- 接口API版本升级的兼容
- 原生组件对部分属性的兼容
- 自定义导航栏的兼容问题