第一次接触trtc小程序的同学和可能会对茫茫多的api接口产生疑惑,createPusher是做什么的,enterRoom又是干嘛,为什么我调用了之后没有用,硬件设备我又要怎么控制?
这里就要解释一下trtc-wx的定位,它是一个辅助,用于帮业务层简化代码,它不能单独使用,需要与微信小程序的原生组件live-pusher/live-player进行搭配使用。
一、小程序推拉流实现逻辑(live-pusher、live-player与底层之间的关系)
要说trtc-wx那么小程序这两个原生标签就是不能绕开的东西,小程序通过live-pusher/live-player与底层建立联系,如下图所示:它们的调用逻辑链比较简单,小程序之所以可以对手机硬件进行控制(开启摄像头、麦克风等),就是因为我们通过调用链执行了底层代码,底层通过硬件驱动控制硬件设备,这部分不是这篇要说的重点,大量的工作微信已经帮助我们实现,开发者只需要关注应用层代码即可。
回到live-pusher/live-player,标签本身有很多属性,我们可以把这两个原生标签当作是一个组件,通过传值给该组件,组件对值做一定处理传递到底层,底层调用驱动控制硬件设备,同样对音视频的解码播放也是在这个过程中完成,调用api也是同样的道理,具体api可以查看文档:wx.createLivePusherContext、wx.createLivePlayerContext。
二、trtc-wx.js的作用
通过上面描述我们已经知道,只需要有一个推拉流地址我便可以直接实现推拉流,那么trtc-wx是是用来做什么的?
这里需要重新提一下trtc-wx的定位是辅助,它集成了腾讯云的trtc-room协议,相较于普通的rtmp协议它包含房间概念并且对数据流做了优化处理,使得会议、直播室等业务场景的处理更加简便、推拉流延迟更低。
因此你可以把trtc-wx当作一个推拉流地址生成器以及回调翻译器,以enterRoom举例:
代码语言:javascript复制enterRoom(options) {
this.setData({
pusher: this.TRTC.enterRoom({
sdkAppID: 1400xxxxx, // 您的腾讯云账号
userID: 'trtc-user', //当前进房用户的userID
userSig: 'xxxxxxx', // 您服务端生成的userSig
roomID: 1234, // 您进房的房间号,
enableMic: true, // 进房默认开启音频上行
enableCamera: true, // 进房默认开启视频上行
}),
}, () => {
this.TRTC.getPusherInstance().start() // 开始进行推流
})
},
enterRoom:接口的返回值pusher为一个对象,对象包含live-pusher组件所需要的属性信息。这时候我们结合上面所说的小程序推拉流实现逻辑,仅仅是js层调用enterRom而没有调用到底层sdk,因此也不会产生推流,其意义相当于const name = 'xxx',name却没有被使用,因此需要通过setData将值传递给live-pusher,live-pusher监听到属性的change做一些业务处理后传递给底层sdk。
这时候回过头看一下调用enterRoom传入的参数,sdkAppID、userID、userSig、roomID是用来生成pusherUrl的必要参数,enableMic、enableCamera则为非必传的配置项,而这些配置项我们也可以直接赋值给live-pusher,并不一定需要通过trtc-wx返回的pusher对象去赋值,这也是为什么把trtc-wx当作推拉流地址生成器的原因。
下面来说trtc-wx的另一大作用--回调翻译器,以代码为例:
代码语言:javascript复制<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)
}
通过给live-pusher标签绑定trtc的相关方法,这样在底层将一些回调抛给live-pusher,live- pusher触发这些方法,在通过trtc-wx进行处理抛出给用户,用户只需监听通过trtc-wx翻译过后的事件即可,为什么不让用户自己处理?一方面是因为中间处理过程比较复杂,处理完抛给用户可以让接入更加简单;另一方面,有些特殊状态码是trtc room协议特有的,不方便在live-pusher文档中表述,因此我们封装了trtc-wx。
三、trtc-wx接入流程
结合上面所说,trtc-wx的接入流程非常简单:
- 生成pusherUrl:调用enterRoom获取返回值后赋值给live-pusher;
- 绑定回调:在live-pusher上绑定trtc相关方法后,用户通过trtc.on()进行绑定,事件表;
- 根据业务需求修改标签属性或者调用 API;
四、常见问题
1. 调用enterRoom接口、属性设置接口,不生效
js层调用enterRoom并没有触发后台相关操作,只有setData将pusherUrl赋值给live-pusher标签后,通过中间层处理,底层才会收到enterRoom,然后抛出进房回调。属性设置接口为相同原因。
2. 收不到对应事件回调
如果只是通过trt.on接口绑定事件,那么是一定不会触发回调的,回调的触发是通过给live-pusher绑定trtc事件,trtc-wx内部经过处理后抛出。
3. 如何实现跨房连麦
trtc room协议是不支持跨房推拉流的,这时候需要使用trtc协议,具体可以参考:【TRTC小程序】跨房连麦功能实现(不混流实现)
五、相关文档汇总
trtc-wx API文档:https://cloud.tencent.com/document/product/647/17018
live-pusher:https://developers.weixin.qq.com/miniprogram/dev/component/live-pusher.html
live-player:https://developers.weixin.qq.com/miniprogram/dev/component/live-player.html
LivePusherContext:https://developers.weixin.qq.com/miniprogram/dev/api/media/live/wx.createLivePusherContext.html
LivePlayerContext:https://developers.weixin.qq.com/miniprogram/dev/api/media/live/wx.createLivePlayerContext.html
【TRTC小程序】跨房连麦功能实现(不混流实现):https://cloud.tencent.com/developer/article/2002839