TWebLive基于TRTC和IM实现web群直播
本文主要通過介紹網(wǎng)頁版群直播基礎(chǔ)功能和實現(xiàn)流程來告訴大家TWebLive 能用來做什么,如何把TWebLive集成到項目中 。
一、網(wǎng)頁版群直播效果
二、網(wǎng)頁版群直播實現(xiàn)框架
三、網(wǎng)頁版群直播基礎(chǔ)功能介紹
3.1、在騰訊云即時通信IM Demo[2]中可以通過2種方式體驗群直播功能。
(1)、通過全局群直播入口進入,此時不會向任何群組發(fā)送群直播開播/停播消息通知
(2)、在Demo中創(chuàng)建Public、Work、Meeting任意一個群組類型(不支持在AVChatRoom中開啟群直播),打開會話窗口,點擊群直播按鈕開啟群直播。
3.2、進入群直播界面后可以輸入直播名稱,底部操作區(qū)設(shè)置有開始直播/結(jié)束直播,攝像頭和麥克風(fēng)開關(guān)按鈕。
3.3、開播時會給群組內(nèi)所有成員推送開播通知,群組成員可以通過點擊消息卡片進入直播間觀看直播。
3.4、直播過程中主播端可以查看主播個人信息、直播在人數(shù)、直播時長,主播可以發(fā)送普通文本消息進行互動。
3.5、觀眾進入直播間可發(fā)送普通文本和禮物消息,暫停觀看不影響與主播進行消息互動。
3.6、主播結(jié)束直播時會給群組內(nèi)推送結(jié)束直播通知,直播結(jié)束后再點擊卡片會提示直播已結(jié)束,不能再進入直播間。
3.7、網(wǎng)頁版群直播與云通信IM APP群直播互通體驗
四、實現(xiàn)群直播的核心技術(shù)—TWebLive
網(wǎng)頁版群直播功能的實現(xiàn)依賴TWebLive SDK。TWebLive集成了騰訊云實時音視頻TRTC[3]、騰訊云即時通信IM[4]、騰訊云超級播放器TcPlayer[5],覆蓋了Web直播互動場景常見的功能,封裝了簡單易用的API[6]。
TWebLive主要提供了三大核心功能:主播端推流,觀眾端觀看,直播互動。主播端推流基于實時音視頻TRTC實現(xiàn),觀眾端CDN觀看基于TcPlayer實現(xiàn),直播互動基于即時通信IM實現(xiàn)。
五、如何利用TWebLive實現(xiàn)群直播功能
5.1、接入TWebLive
在TRTC應(yīng)用或者IM應(yīng)用中均可接入TWebLive。這里主要介紹在IM應(yīng)用中接入TWeblive的流程。接入前,需要在騰訊云即時通信IM控制臺創(chuàng)建的IM應(yīng)用中開通騰訊云實時音視頻服務(wù),開通音視頻服務(wù)后,還需要在騰訊云直播控制臺配置直播域名且域名需要配置HTTPs。
在項目中通過npm安裝最新版本的tim-js-sdk、trtc-js-sdk、tweblive。如果項目已經(jīng)集成有tim-js-sdk或trtc-js-sdk,直接將其升級到最新版本即可。
在項目中引入tweblive
import TWebLive from 'tweblive' Vue.prototype.TWebLive = TWebLive如果需要通過script標(biāo)簽外鏈的方式引入,需要將tim-js.js、trtc.js、tweblive.js拷貝至項目中,按順序引入。
<script src="./trtc.js"></script> <script src="./tim-js.js"></script> <script src="./tweblive.js"></script>5.2、群直播主播端主要功能實現(xiàn)如下
// 初始化pusher init() { this.pusher = this.TWebLive.createPusher({userID: this.user.userID }) this.setRenderView() this.pusher.on(this.TWebLive.EVENT.RTC_CONNECTION_STATE_CHANGED, this.onRTCConnectionStateChanged) this.pusher.on(this.TWebLive.EVENT.RTC_CLIENT_BANNED,this.onRTCClientBanned) this.pusher.on(this.TWebLive.EVENT.RTC_CLIENT_ERROR,this.onRTCError) }, // eslint-disable-next-line no-unused-vars onRTCConnectionStateChanged(event) {}, // eslint-disable-next-line no-unused-vars onRTCClientBanned(event) {}, // eslint-disable-next-line no-unused-vars onRTCError(event) {}, //開啟本地預(yù)覽 setRenderView() {this.pusher.setRenderView({elementID: 'video-container',audio: true,video: true}).then(() => {// 設(shè)置背景let el =document.getElementById('videocontainer').childNodesel[0].style.backgroundColor = 'rgba(0,0,0,0)'this.isStartCamera = false}).catch(() => {}) },// 打開攝像頭 startCamera() {this.pusher.startCamera().then(() => {this.isStartCamera = false}).catch(() => {}) }, // 關(guān)閉攝像頭 stopCamera() {this.pusher.stopCamera().then(() => {this.isStartCamera = true}).catch(() => {}) }, // 打開麥克風(fēng) startMicrophone() {this.pusher.startMicrophone().then(() => {this.isMute = false}).catch(() => {}) }, // 關(guān)閉麥克風(fēng) stopMicrophone() {this.pusher.stopMicrophone().then(() => {this.isMute = true}).catch(() => {}) }, // 通過業(yè)務(wù)服務(wù)器創(chuàng)建直播房間 async createRoom() {}, //開始推流 async startPushStream() {await this.createRoom()// streamID生成規(guī)則:sdkappid_roomid_userid_mainconst streamID = `${this.user.sdkAppID}_${this.roomID}_${this.user.userID}_main`// 對userSig進行encode,防止userSig中帶有+時被瀏覽器解析為空格,導(dǎo)致trtc ws連接失敗const url = `room://livedomainname=xxx.xxx.com&sdkappid=${this.user.sdkAppID}&roomid=${this.roomID}&userid=${this.user.userID}&usersig=${encodeURIComponent (this.user.userSig)}&streamid=${streamID}`this.pusher.startPush(url).then(() => { // 發(fā)送開播群通知 this.sendNoticeToGroup(1)}).catch(() => {}) }, // 停止推流 async stopPush() {await this.pusher.stopPush()// 發(fā)送直播結(jié)束群通知 this.sendNoticeToGroup(0) }, // 給群內(nèi)發(fā)送開始直播、結(jié)束直播自定義消息 // roomStatus 1 開始直播 0 結(jié)束直播 sendNoticeToGroup(roomStatus) {if (!this.groupLiveInfo.groupID) { return }const { userID, nick, avatar } = this.user.currentUserProfile// 自定義消息結(jié)構(gòu)體,根據(jù)實際需要修改,以下結(jié)構(gòu)體僅為Demo使用const form = {roomId: this.roomID,roomName: this.roomName,roomCover: avatar,roomStatus: `${roomStatus}`,anchorName: nick,version: 4,roomType: 'liveRoom',anchorId: userID,businessID: 'group_live'}const message = this.tim.createCustomMessage({to: this.groupLiveInfo.groupID,conversationType: this.TIM.TYPES.CONV_GROUP,priority: this.TIM.TYPES.MSG_PRIORITY_NORMAL,payload: {data: JSON.stringify(form),description: '',extension: '',},})this.tim.sendMessage(message).then(() => {}).catch(() => {}) }5.3、群直播觀眾端主要功能實現(xiàn)如下
// 初始化player init() {this.player = this.TWebLive.createPlayer()this.player.setCustomConfig({autoplay: true,poster: { style:'cover', src: poster },pausePosterEnabled: false,wording: {1:'您觀看的直播已結(jié)束哦~ ',2:'您觀看的直播已結(jié)束哦~ ',4:'您觀看的直播已結(jié)束哦~ ',13:'您觀看的直播已結(jié)束',2032: '請求視頻失敗,請檢查網(wǎng)絡(luò)',2048: '請求m3u8文件失敗,可能是網(wǎng)絡(luò)錯誤或者跨域問題'}})// 監(jiān)聽播放事件 this.player.on(this.TWebLive.EVENT.PLAYER_PLAYING,this.onPlayerPlaying) // 監(jiān)聽暫停事件 this.player.on(this.TWebLive.EVENT.PLAYER_PAUSE,this.onPlayerPause) // 監(jiān)聽瀏覽器不允許自動播放事件 this.player.on(this.TWebLive.EVENT.PLAYER_AUTOPLAY_NOT_ALLOWED, this.onPlayerAutoPlayNotAllowed) // 監(jiān)聽播放異常事件 this.player.on(this.TWebLive.EVENT.PLAYER_ERROR,this.onPlayerError) this.setRenderView() }, // eslint-disable-next-line no-unused-vars onPlayerPlaying(event) {}, // eslint-disable-next-line no-unused-vars onPlayerPause(event) {}, // eslint-disable-next-line no-unused-vars onPlayerAutoPlayNotAllowed(event) {this.$store.commit('showMessage', {message: '不能自動播放',type: 'info'}) }, //開始播放 startPlay() {const streamID = `${this.user.sdkAppID}_${this.roomID}_${this.anchorId}_main`const flv = `https://xxx.xx.com/live/${streamID}.flv`const hls = `https://xxx.xx.com/live/${streamID}.m3u8` const url = `https://flv=${encodeURIComponent(flv)}&hls=${encodeURIComponent(hls)}`this.player.startPlay(url).then(() => {this.isPlaying = true}).catch(() => {}) }, //暫停播放 pauseVideo() {this.player.pauseVideo().then(() => {this.isPlaying = false}).catch(() => {}) }, // 恢復(fù)播放 resumeVideo() {this.player.resumeVideo().then(() => {this.isPlaying = true}).catch(() => {}) }, // 調(diào)節(jié)播放器音量 setPlayoutVolume() {this.player.setPlayoutVolume(this.volumeValue) }, // 停止播放 stopPlay() {this.player.stopPlay()this.isPlaying = false }5.4、群直播互動功能實現(xiàn)
由于騰訊云即時通信IM Demo[2]中已經(jīng)集成了IM應(yīng)用,直播互動部分的功能通過IM SDK API實現(xiàn)。
代碼片段是在Vue框架下實現(xiàn),代碼中使用到的變量維護在Vuex 和組件data屬性中。可以復(fù)制以上代碼片段到Vue項目中,即可快速搭建一個網(wǎng)頁版群直播功能。
六、TWebLive SDK體積優(yōu)化
TWebLive SDK 1.0.0打包時將IM SDK、TRTC SDK、TcPlayer 集成輸出,導(dǎo)致輸出的包體積很大(接近1M),如果在已有IM或者TRTC應(yīng)用中接入TWebLive時,存在重復(fù)引用的問題。為了提升接入體驗,已發(fā)布TWebLive 1.1.0版本,主要是在1.0.0的基礎(chǔ)上優(yōu)化SDK的打包方式,把IM SDK和TRTC SDK作為外部依賴打包,SDK體積減少了78%。接入TWeblive時手動安裝IM SDK和TRTC SDK即可。
七、注意事項
第一、接入TWebLive時,需要安裝最新版本的tim-js-sdk、trtc-js-sdk,避免引起版本兼容性問題。
第二、Pusher和Player中使用到的SDKAppID必須與IM應(yīng)用的SDKAppID保持一致。
第三、由于 H.264 版權(quán)限制,華為系統(tǒng)的 Chrome 瀏覽器和以 Chrome WebView 為內(nèi)核的瀏覽器均不支持 TRTC 桌面瀏覽器端 SDK 的正常運行。
參考資料:
[1] TWebLive詳情
[2] 騰訊云即時通信IM在線 Demo
[3] 騰訊云實時音視頻 TRTC
[4] 騰訊云即時通信IM
[5] 騰訊云超級播放器 TCPlayer
[6] TWebLive接口手冊
[7] 騰訊云即時通信接口手冊
[8] TWebLive 使用
[9] 騰訊點播視頻DEMO
總結(jié)
以上是生活随笔為你收集整理的TWebLive基于TRTC和IM实现web群直播的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 对比“码绘”与“手绘”的区别
- 下一篇: 最短路径--狄克斯特拉(Dijkstra