最近需要使用实时音视频完成功能,于是使用了腾讯云的音视频sdk,先附带上他的文档地址:
https://cloud.tencent.com/document/product/647
这文档里面大体上还是完善的,只是有很多细节没能描述出来。我个人只是用了web端以及小程序端的两个模块。
web端WebRTC
WebRTC 技术由 Google 最先提出,目前主要在桌面版 Chrome 浏览器、桌面版 Safari 浏览器以及移动版的 Safari 浏览器上有较为完整的支持,其他平台(例如 Android 平台的浏览器)支持情况均比较差。
- 首先需要一些sdk认证,当然这部分似乎需要购买的,大体上可以直接去官网上看看,大概上需要sdkAppId、userSig还有userID之类的,可以自行配置,然后引入sdk就可以使用了
import TRTC from ‘trtc-js-sdk’
- 开始web端的使用:
this.client = TRTC.createClient({
mode: 'videoCall',
sdkAppId: this.sdkAppId,
userId: this.userId,
userSig: this.userSig
})
this.client.on('stream-added', event => {
// console.log('远端流增加: ' + event.stream.getId())
if (this.shareScreenUserId === event.stream.getUserId()) {
// 取消订阅自己的屏幕分享流
this.client.unsubscribe(event.stream)
return
}
// 订阅远端流
this.client.subscribe(event.stream)
})
this.client.on('stream-subscribed', event => {
const remoteStream = event.stream
// console.log('远端流订阅成功:' + remoteStream.getId())
// 播放远端流
// 这里失去订阅远端流,这里面返回的流可以直接使用,包含了他的全部信息,比如我需要加入流对应的name和status等
const divId = this.addRemoteStream(remoteStream)
remoteStream.play(divId)
})
this.client
.join({ roomId: this.roomId })
.catch(error => {
console.error('进房失败: ' + error)
})
.then(() => {
// console.log('进房成功')
// 这里是去创建本地流
this.initLocalStream()
})
})
},
- 创建自己的本地流,其中含有音频流和视频流,也可以直接在创建是进行配置。在页面上直接使用
<div id="local_stream"></div>
就可以播放。
this.localStream = TRTC.createStream({ userId: this.userId, audio: true, video: true, useCloud: 0 })
this.localStream
.initialize()
.catch(error => {
console.error('初始化本地流失败: ' + error)
})
.then(() => {
// console.log('初始化本地流成功')
this.localStream.play('local_stream', {
objectFit: 'contain',
muted: true
})
this.client.publish(this.localStream).catch(error => {
console.error('本地流发布失败: ' + error)
}).then(() => {
// console.log('本地流发布成功')
})
})
- 控制本地的音视频开关,文档中有相应的api,直接在本地流中调用对应方法就行:
【禁用音频】this.localStream.muteAudio() 【启用音频】this.localStream.unmuteAudio()
【禁用视频】this.localStream.muteVideo() 【启用视频】this.localStream.unmuteVideo()
- 还有屏幕分享,其实就是相当于在本地发布一个只推不收的视频流,其中关于如何检测停止共享,我并没有在文档中找到,无奈之下,去他的流里面寻找相关属性,发现了存在一个active的属性可以检测到,当然对于没办法主动触发的情况下,只好去轮询查看来进行判断,这方面可能有些问题,如下:
this.shareScreenClient = TRTC.createClient({
mode: 'shareScreenCall',
sdkAppId: this.sdkAppId,
userId: this.shareScreenUserId,
userSig: this.shareScreenUserSig
})
/ 指明该 shareClient 默认不接收任何远端流 (它只负责发送屏幕分享流)
this.shareScreenClient.setDefaultMuteRemoteStreams(true)
this.shareScreenClient.join({ roomId: this.roomId }).then(() => {
// console.log('shareClient join success')
// 创建屏幕分享流
this.shareScreenLocalStream = TRTC.createStream({ audio: false, screen: true })
this.shareScreenLocalStream.initialize().then(() => {
// screencast stream init success
this.shareScreenClient.publish(this.shareScreenLocalStream).then(() => {
let shareStatus = setInterval(() => {
if (!this.shareScreenLocalStream.mediaStream_.active) {
this.shareScreenClient.unpublish(this.shareScreenLocalStream).then(() => {
this.shareScreenClient = null
this.shareScreenLocalStream = null
clearInterval(shareStatus)
console.log('屏幕分享停止')
})
}
}, 1000)
})
})
})
- 如果还需要检测远端流的状态(即音视频是否开启)的话,我总觉得给出来的api不够准确,开始的时候我通过对应流的
hasVideo()
和hasAudio()
去判断,结果发现hasAudio()
一直返回1(即存在)只有在视频关闭hasVideo()
为0后,才会准确的返回远端流的状态。 - 这部分找了半天,才发现有一个api可以满足:
getRemoteMutedState()
这个api可以直接获取远端所有用户的状态数组。 - 当然,这里面还有个坑(我也不知道是不是我的操作不够准确),在远端视频关闭后,可能会出现整个流断掉的情况,这个api返回空数组。