最近需要使用實時音視頻完成功能,於是使用了騰訊雲的音視頻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返回空數組。