303 lines
12 KiB
Markdown
303 lines
12 KiB
Markdown
|
# Trtc-wx快速集成
|
|||
|
|
|||
|
## 概要介绍
|
|||
|
|
|||
|
小程序的实时音视频是基于微信原生组件标签<live-pusher>和<live-player>实现的,您可以通过[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)对这两个标签有一个简单认识。本篇介绍的 trtc-wx 包是一个专门为您管理 TRTC 状态的一个类,作为一个纯 js 模块,您可以根据业务场景,自主编写页面的元素布局,trtc-wx 则可以帮助您管理所有与实时音视频相关的状态,和调用挂载在<live-pusher>和<live-player>上的方法。整体的调用逻辑如下图所示,`trtc-room.wxml`是您自主编写的 wxml 文件,其中包括<live-pusher>和<live-player>节点,`trtc-room.js`是您的业务层代码,您需要在这个文件中引用我们的`trtc-wx.js`。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
## 准备工作
|
|||
|
|
|||
|
在集成小程序 SDK 前,请确保您已完成以下步骤,具体操作请参见 [跑通Demo(小程序)](https://cloud.tencent.com/document/product/647/32399)。
|
|||
|
|
|||
|
- 创建了腾讯云实时音视频应用,购买了相应的套餐,并获取到 SDKAppID 和密钥信息。
|
|||
|
- 开通小程序类目与推拉流标签权限。
|
|||
|
- 小程序服务器域名配置。
|
|||
|
|
|||
|
## 环境要求
|
|||
|
|
|||
|
- 微信 App iOS 最低版本要求:7.0.9
|
|||
|
- 微信 App Android 最低版本要求:7.0.8
|
|||
|
- 小程序基础库最低版本要求:2.10.0
|
|||
|
- 由于微信开发者工具不支持原生组件(即<live-pusher>和<live-player>标签),需要在真机上进行运行体验。
|
|||
|
|
|||
|
## 如何引用
|
|||
|
|
|||
|
您可以通过npm包的方式进行引用,也可以通过 [SDK 资源]() 下载 trtc-wx.js 文件,直接进行引用
|
|||
|
|
|||
|
npm 方式安装
|
|||
|
```
|
|||
|
npm install trtc-wx
|
|||
|
```
|
|||
|
|
|||
|
```javascript
|
|||
|
import TRTC from 'trtc-wx'
|
|||
|
```
|
|||
|
|
|||
|
## 接入指引
|
|||
|
|
|||
|
以下会为您简单介绍一个1V3场景下,每一个步骤的实现。
|
|||
|
|
|||
|
### step1 创建符合您业务场景WXML文件模板
|
|||
|
根据您的业务场景,编写 wxml 文件,创建<live-pusher>和<live-player>,并将标签上的属性与 trtc-wx 提供的方法相绑定,如果您是1V3教育类场景的话,可能需要区分教师端和学生端,自主编写不同的样式模板,因此 css 部分的代码就暂不做展示。
|
|||
|
|
|||
|
*提示:在<live-player>上需要额外绑定`data-streamid="{{item.streamid}}"`*是因为状态机需要区分标签绑定的 handler 是从哪一个 player 调用的。
|
|||
|
|
|||
|
```html
|
|||
|
//page.wxml
|
|||
|
<live-pusher
|
|||
|
class="pusher"
|
|||
|
url="{{pusher.url}}"
|
|||
|
mode="{{pusher.mode}}"
|
|||
|
autopush="{{pusher.autopush}}"
|
|||
|
enable-camera="{{pusher.enableCamera}}"
|
|||
|
enable-mic="{{pusher.enableMic}}"
|
|||
|
muted="{{!pusher.enableMic}}"
|
|||
|
enable-agc="{{pusher.enableAgc}}"
|
|||
|
enable-ans="{{pusher.enableAns}}"
|
|||
|
enable-ear-monitor="{{pusher.enableEarMonitor}}"
|
|||
|
auto-focus="{{pusher.enableAutoFocus}}"
|
|||
|
zoom="{{pusher.enableZoom}}"
|
|||
|
min-bitrate="{{pusher.minBitrate}}"
|
|||
|
max-bitrate="{{pusher.maxBitrate}}"
|
|||
|
video-width="{{pusher.videoWidth}}"
|
|||
|
video-height="{{pusher.videoHeight}}"
|
|||
|
beauty="{{pusher.beautyLevel}}"
|
|||
|
whiteness="{{pusher.whitenessLevel}}"
|
|||
|
orientation="{{pusher.videoOrientation}}"
|
|||
|
aspect="{{pusher.videoAspect}}"
|
|||
|
device-position="{{pusher.frontCamera}}"
|
|||
|
remote-mirror="{{pusher.enableRemoteMirror}}"
|
|||
|
local-mirror="{{pusher.localMirror}}"
|
|||
|
background-mute="{{pusher.enableBackgroundMute}}"
|
|||
|
audio-quality="{{pusher.audioQuality}}"
|
|||
|
audio-volume-type="{{pusher.audioVolumeType}}"
|
|||
|
audio-reverb-type="{{pusher.audioReverbType}}"
|
|||
|
waiting-image="{{pusher.waitingImage}}"
|
|||
|
beauty-style="{{pusher.beautyStyle}}"
|
|||
|
filter="{{pusher.filter}}"
|
|||
|
bindstatechange="_pusherStateChangeHandler"
|
|||
|
bindnetstatus="_pusherNetStatusHandler"
|
|||
|
binderror="_pusherErrorHandler"
|
|||
|
bindbgmstart="_pusherBGMStartHandler"
|
|||
|
bindbgmprogress="_pusherBGMProgressHandler"
|
|||
|
bindbgmcomplete="_pusherBGMCompleteHandler"
|
|||
|
bindaudiovolumenotify="_pusherAudioVolumeNotify"
|
|||
|
/>
|
|||
|
<!-- 这个playerList应该是个长度为3的数组,具体会由房间内有多少人决定 -->
|
|||
|
<view wx:for="{{playerList}}" wx:key="id" id="{{'player-'+item.streamID}}">
|
|||
|
<live-player
|
|||
|
class="player"
|
|||
|
id="{{item.id}}"
|
|||
|
data-streamid="{{item.streamid}}"
|
|||
|
src= "{{item.src}}"
|
|||
|
mode= "RTC"
|
|||
|
autoplay= "{{item.autoplay}}"
|
|||
|
mute-audio= "{{item.muteAudio}}"
|
|||
|
mute-video= "{{item.muteVideo}}"
|
|||
|
orientation= "{{item.orientation}}"
|
|||
|
object-fit= "{{item.objectFit}}"
|
|||
|
background-mute= "{{item.enableBackgroundMute}}"
|
|||
|
min-cache= "{{item.minCache}}"
|
|||
|
max-cache= "{{item.maxCache}}"
|
|||
|
sound-mode= "{{item.soundMode}}"
|
|||
|
enable-recv-message= "{{item.enableRecvMessage}}"
|
|||
|
auto-pause-if-navigate= "{{item.autoPauseIfNavigate}}"
|
|||
|
auto-pause-if-open-native= "{{item.autoPauseIfOpenNative}}"
|
|||
|
debug="{{debug}}"
|
|||
|
bindstatechange="_playerStateChange"
|
|||
|
bindfullscreenchange="_playerFullscreenChange"
|
|||
|
bindnetstatus="_playerNetStatus"
|
|||
|
bindaudiovolumenotify="_playerAudioVolumeNotify"
|
|||
|
/>
|
|||
|
</view>
|
|||
|
```
|
|||
|
|
|||
|
在 trtc-wx 包中导出的是一个名为 TRTC 的类,您需要在 onLoad 的生命周期中,在当前页面去实例化这个类,同时创建 Pusher,并监听 TRTC 抛出的事件,同时由于微信小程序框架编译的机制,您需要在当前页面绑定这些处理函数,这些函数,trtc-wx 已经为您提供了。
|
|||
|
|
|||
|
```javascript
|
|||
|
//page.js
|
|||
|
import TRTC from 'trtc-wx.js'
|
|||
|
|
|||
|
// 在生命周期中新建一个TRTC的类
|
|||
|
onLoad(){
|
|||
|
this.TRTC = new TRTC(this)
|
|||
|
this.setData({
|
|||
|
// rtcConfig 是初始化参数,返回初始化后的推流状态,需要与模板想结合
|
|||
|
pusher: this.TRTC.createPusher(rtcConfig).pusherAttributes
|
|||
|
})
|
|||
|
this.TRTC.on() // 这里需要绑定一系列的事件监听方法,下文会详细介绍
|
|||
|
}
|
|||
|
|
|||
|
_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)
|
|||
|
}
|
|||
|
|
|||
|
_playerStateChange(event) {
|
|||
|
this.TRTC.playerEventHandler(event)
|
|||
|
}
|
|||
|
_playerFullscreenChange(event) {
|
|||
|
this.TRTC.playerFullscreenChange(event)
|
|||
|
}
|
|||
|
_playerNetStatus(event) {
|
|||
|
this.TRTC.playerNetStatus(event),
|
|||
|
}
|
|||
|
_playerAudioVolumeNotify(event) {
|
|||
|
this.TRTC.playerAudioVolumeNotify(event),
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
### step2 如何开始推流
|
|||
|
您首先需要进入我们的 TRTC 房间,调用 enterRoom 的方法,之后您可以手动控制开始推流,这里您可以参考 [API 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() // 开始进行推流
|
|||
|
})
|
|||
|
},
|
|||
|
```
|
|||
|
#### 控制是否上行本地音视频流
|
|||
|
需要变更 live-pusher 标签上 enable-mic 和 enable-camera 的属性,您可以通过调用 setPusherAttributes 对状态机中管理的推流状态进行改变,会返回给您更新后的状态值,更新到页面中。
|
|||
|
```javascript
|
|||
|
// 上行音频流
|
|||
|
this.setData({
|
|||
|
pusher: this.TRTC.setPusherAttributes({enableMic: true})
|
|||
|
})
|
|||
|
|
|||
|
// 上行视频流
|
|||
|
this.setData({
|
|||
|
pusher: this.TRTC.setPusherAttributes({enableCamera: true})
|
|||
|
})
|
|||
|
```
|
|||
|
如果您想其他的属性,您可以阅读 [API 文档](),对于一些属性不生效的问题,您可以先阅读[问题指南](#问题指南)
|
|||
|
|
|||
|
### step3 对于远端流进行处理
|
|||
|
|
|||
|
#### 收到远端视频流增加通知
|
|||
|
|
|||
|
如果收到远端新增视频流,您可以开始播放这路视频,将这个 player 的 muteVideo 状态设置为 false,这里需要您传入这个 player 的 id,更新完成后会返回给您更新后的 playerList 列表,您只需要将页面的 playerList 同步更新即可。
|
|||
|
|
|||
|
```javascript
|
|||
|
// 收到视频流新增的通知
|
|||
|
this.TRTC.on(EVENT.REMOTE_VIDEO_ADD, (event) => {
|
|||
|
const { player } = event.data
|
|||
|
// 开始播放远端的视频流,默认是不播放的
|
|||
|
let playerList = this.TRTC.setPlayerAttributes(player.id, {'muteVideo': false})
|
|||
|
// 如果您是1V3的教育场景,学生端这里可能会需要处理下playerList的顺序,如将教师的那个player放置于首位。
|
|||
|
this.setData({
|
|||
|
playerList: playerList,
|
|||
|
})
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
#### 收到远端音频流增加通知
|
|||
|
|
|||
|
如果收到远端新增音频流,您可以开始播放这路音频,将这个 player 的 muteAudio 状态设置为 false,这里需要您传入这个 player 的 id,更新完成后会返回给您更新后的 playerList 列表,您只需要将页面的 playerList 同步更新即可。
|
|||
|
|
|||
|
```javascript
|
|||
|
// 收到视频流新增的通知
|
|||
|
this.TRTC.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
|
|||
|
const { player } = event.data
|
|||
|
// 开始播放远端的视频流,默认是不播放的
|
|||
|
let playerList = this.TRTC.setPlayerAttributes(player.id, {'muteAudio': false})
|
|||
|
// 如果您是1V3的教育场景,学生端这里可能会需要处理下playerList的顺序,如将教师的那个player放置于首位。
|
|||
|
this.setData({
|
|||
|
playerList: playerList,
|
|||
|
})
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
#### 收到远端音频流减少通知
|
|||
|
|
|||
|
如果收到这个远端流减少的通知时,您可以取消对这一路的订阅,将 muteAudio 设置为 true。
|
|||
|
|
|||
|
```javascript
|
|||
|
// 收到视频流新增的通知
|
|||
|
this.TRTC.on(EVENT.REMOTE_AUDIO_ADD, (event) => {
|
|||
|
const { player } = event.data
|
|||
|
// 开始播放远端的视频流,默认是不播放的
|
|||
|
let playerList = this.TRTC.setPlayerAttributes(player.id, {'muteAudio': true})
|
|||
|
// 如果您是1V3的教育场景,学生端这里可能会需要处理下playerList的顺序,如将教师的那个player放置于首位。
|
|||
|
this.setData({
|
|||
|
playerList: playerList,
|
|||
|
})
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
#### 主动停止某个player的播放
|
|||
|
|
|||
|
如果您想要主动停止某个 player 的视频播放,您只需要变更这个 player 的 muteVideo 属性为 true 即可,音频也是同理。
|
|||
|
|
|||
|
```javascript
|
|||
|
this.setData({
|
|||
|
playerList: this.TRTC.setPlayerAttributes(player.id, {'muteVideo': true}),
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
想要了解更多 live-player 的功能可以参考[微信官方文档 live-player](https://developers.weixin.qq.com/miniprogram/dev/component/live-player.html)
|
|||
|
|
|||
|
### step4 结束音视频通话
|
|||
|
|
|||
|
退房,重置所有状态,并同步到页面中,放置下次进房发生状态的混乱。
|
|||
|
```javascript
|
|||
|
exitRoom() {
|
|||
|
const result = this.TRTC.exitRoom()
|
|||
|
this.setData({
|
|||
|
pusher: result.pusher,
|
|||
|
playerList: result.playerList,
|
|||
|
})
|
|||
|
},
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
<h2 id="问题指南">问题指南</h2>
|
|||
|
|
|||
|
1、`devicePosition`设置为什么失效了呢,设置为 back,为什么还是前置摄像头?
|
|||
|
|
|||
|
这个属性目前由于微信的限制,只支持在 live-pusher 的 insert 阶段进行设置,建议您在生命周期 onLoad 函数中执行 createPusher 并设置这个属性。
|
|||
|
|
|||
|
2、我看到微信 live-pusher 和 live-player 上还有好多方法可以调用呢?
|
|||
|
|
|||
|
您可以通过`this.TRTC.getPusheInstance()`和`this.TRTC.getPlayerInstance(id)`获取相应的实例,调用这些方法。
|
|||
|
|
|||
|
3、如何开启预览
|
|||
|
|
|||
|
```javascript
|
|||
|
enterRoom(options) {
|
|||
|
this.setData({
|
|||
|
pusher: this.TRTC.enterRoom({roomID: 1234}),
|
|||
|
}, () => {
|
|||
|
this.TRTC.getPusherInstance.startPreview() // 开启预览
|
|||
|
})
|
|||
|
},
|
|||
|
```
|
|||
|
之后您可以在希望开始推流的时候调用` this.TRTC.getPusherInstance.start()`开始推流
|