小程序與WebRTC聯姻能擦出怎樣的火花?

歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~javascript

本文由騰訊視頻雲終端團隊發表於雲+社區專欄java

騰訊視頻雲終端技術總監,rexchang(常青), 2008 年畢業加入騰訊,一直從事客戶端研發相關工做,前後參與過 PC QQ、手機QQ、QQ物聯 等產品項目,目前在騰訊視頻雲團隊負責音視頻終端解決方案的優化和落地工做,幫助客戶在可控的研發成本投入之下,得到業內一流的音視頻解決方案,目前咱們的產品線包括:互動直播、點播、短視頻、實時視頻通話,圖像處理,AI 等等。git

img
本篇文章的思惟導圖

分開作一下介紹

小程序音視頻是什麼?github

2017年騰訊視頻雲團隊跟微信團隊聯合,將視頻雲 SDK 跟微信小程序整合在一塊兒,並經過 和 兩個標籤的形式開放內部的功能。經過這兩個標籤,開發者能夠實如今線直播、低延時監控、雙人視頻通話以及多人視頻會議等功能。web

那麼WebRTC又是什麼?算法

WebRTC(Web Real-Time Communication),是一個支持網頁瀏覽器進行實時語音對話或視頻對話的技術,是谷歌收購 GIPS 公司而得到的一項技術,在 Chrome 瀏覽器上無需安裝插件,經過 javascript 就能夠編寫實時音視頻通話程序。json

二者區別在哪裏?

若是您跟我同樣是一個實用主義者,那我就簡單從實用主義角度說一下個人結論:小程序搞定了手機,WebRTC拿下了PC。小程序

若是你對技術比較感興趣,那咱們就能夠從多個技術的角度去列舉二者的區別,下面是一張詳細對比的表格:微信小程序

img

  • 實現原理: 小程序音視頻是將騰訊視頻雲的 liteavsdk 嵌入到微信內部實現的,而後經過 和 兩個標籤將 SDK 內部的音視頻能力開放出來。因此小程序的標籤起到了開發者 API 的做用,而內部的 SDK 則是真正用來實現音視頻功能。

WebRTC 由谷歌收購 GIPS 得來(這裏不得不提一下,我加入騰訊時所在的第一個團隊就是 QQ 團隊,當時 QQ 的音視頻仍是購買的 GIPS 公司的產品,不過因爲各類不靠譜,後來就轉爲自研路線了)。因此其技術被完整的保留而且加入到了 Google 的 Chrome 瀏覽器內核當中。並且最近蘋果也已經開始在 Safari 瀏覽器中支持 WebRTC 的相關能力。api

  • 底層協議 小程序音視頻的主要協議是目前在直播領域最爲經常使用的 RTMP 推流協議,以及 HTTP-FLV 播放協議,這兩種協議都已經有多年的沉澱並且在互聯網上的資料也是汗牛充棟。

WebRTC的底層則是使用RTP和RTCP兩種數據協議,其中RTP主要用於音視頻數據傳輸,而RTCP則通常用於控制。

  • 移動端碎片化問題 小程序音視頻因爲是微信統一實現的,並且微信團隊每一個版本都儘可能要求功能對齊,不然寧肯不上,因此在碎片化問題上基本不存在。

WebRTC在這裏則要尷尬的多,一方面Android系統的碎片化自己讓WebRTC的具體表現呈現「百花齊放」的景象,同時,iOS 目前的內嵌WebView(也就是在微信等APP裏打開的各類內嵌網頁)不支持WebRTC也仍是個很麻煩的問題。

  • 擴展性 小程序音視頻跟隨微信的版本發佈,有什麼問題通常是當前代碼流修正,而後跟隨下一個版本發佈,因此通常一個功能點(好比給 pusher 加一個美顏的功能)或者一個問題點(好比不支持手勢放大)從確立到最終實現(或解決)僅須要一個月的時間,並且微信APP新版本的覆蓋速度也確實挺快。

相比之下,WebRTC則不是一個團隊或者一家公司的問題了,由於它如今已經走標準路線,因此每個新特性都是先肯定標準,而後再推進瀏覽器廠商(包括蘋果)進行跟隨。這裏面的故事就多了,時間也就更久了。

  • 桌面瀏覽器 相信您已經發現,在前面幾個問題的分析上,個人觀點都傾向小程序音視頻。確實,在目前國內的移動領域裏,谷歌和蘋果都不能一家說了算,真正說了算的仍是微信

可是在桌面瀏覽器這個部分,Chrome目前在PC瀏覽器市場上留到地位的存在決定了 WebRTC 的優點就很大了,開發者能夠在不安裝插件的狀況下就能夠實現本身想要的功能。

相比之下,因爲沒有 Chrome 的原生支持,因此若是咱們要在 PC 上對接小程序音視頻,就須要安裝瀏覽器插件或者經過 wxlite://start 這樣的僞協議喚起本地 exe 應用程序(相似在網頁上打開 QQ 聊天窗口)。

並不是零和博弈

小程序音視頻和WebRTC支架並不是零和博藝,雙方都有本身的優點和不足,因此本着「打不過他們,就加入他們」的思路,騰訊視頻雲團隊在2018年春節回來後,就快馬加鞭地開始了小程序音視頻和WebRTC互通的相關工做。

目前,須要向各位開發者彙報的是,在最新版本的微信中,小程序音視頻已經能夠跟WebRTC打通,目前在PC 的Chrome瀏覽器上就能夠跟小程序進行實時音視頻互通。

// to-do

固然,若是您想知道這個功能是怎麼實現的,能夠繼續看下去:

充分了解WebRTC

就像結婚同樣,既然你決定要選擇另外一我的做爲人生下半輩子的伴侶,那你確定會先深刻地瞭解一下TA這我的,好比性格,脾氣,愛好等各個方面。

一樣,咱們要想很好的將小程序音視頻和WebRTC打通,那也必需要多瞭解一下WebRTC,這裏我就說一下我對 WebRTC 這個「人」 在性格上的一些理解。

首先,她雖然長得不太好看,但頗有內涵。

說WebRTC長得很差看,只是個人一種比喻,個人意思是想說WebRTC的學習成本不低,雖然Google作了不少淺顯易懂的PPT來教你怎麼 Getting Start,但真要完整的學進去,仍是須要靜下心來,慢慢地把她當成本身承認的目標去學下去。可是若是你是第一次戀愛(也就是第一次接觸實時音視頻),你會發現學習WebRTC的過程,自己就是了解一個實時音視頻技術細節的過程。

其次,她很是喜歡遷就別人,各類架構方案她都能支持到。

說WebRTC喜歡遷就比人,也是一種比喻,WebRTC所支持的後臺架構很是多(好比 Mixer, Mesh,Router),並且谷歌認爲這些後臺實現都比較簡單,因此既沒有開放後臺相關的源碼,也沒有提供統一的後臺解決方案。這種開放式的設計思路很是好,但反作用就是實現成本高。在真刀真槍的項目落地時,小規模的公司或者開發者就很容易被這種技術門檻擋在門外。尤爲是想要將 WebRTC 真正應用到企業級解決方案中,面對錄製和存檔的剛性需求,就須要花費大量時間進行定製開發。

方案的確立

瞭解到 WebRTC 的這些特色後,咱們的互通方案也就比較清晰了:

首先,小程序音視頻的特色是接口簡單,快速上手,這是小程序的優點;而這一點偏偏是WebRTC的劣勢,因此咱們沒有必要在小程序端爲WebRTC暴露十幾個接口類,而是繼續採用小程序音視頻的 和 標籤來解決問題。

其次,WebRTC 的後臺沒有官方實現,那就意味着這裏有很大的發揮空間,騰訊視頻雲就能夠實現一套WebRTC後臺並將其同小程序音視頻所使用RTMP後臺進行打通。簡單來講,騰訊視頻雲要在小程序音視頻和WebRTC之間充當紅娘(更確切的說,應該是翻譯員)的角色。

可是看過《新聞聯播》裏國家領導人之間談話鏡頭的人都知道,這種翻譯是會影響交流速度的。小程序音視頻和WebRTC之間互通,中間引入一個翻譯員,是否是通信延時也就增長了?

其實不會,由於小程序音視頻和WebRTC的視頻編碼標準在常規應用場景中是一致的,都是H.264標準,這是音頻格式不一樣而已。這就意味着,翻譯員要作的事情不多,兩邊基本都能挺對對方在說什麼,因此延時不會增長太多。

成功的握手

下圖所展現的就是騰訊視頻雲在小程序音視頻和WebRTC互通問題上所採起的方案:

img

(1)首先,微信端的小程序經過騰訊視頻雲SDK將音視頻流推送到騰訊雲 RTMP 服務器。

(2)其次,騰訊雲 RTMP 服務器的會對音視頻數據進行初步的轉化處理,而後透傳給騰訊視頻雲的實時音視頻後臺集羣。

(3)再次,實時音視頻後臺會再次將數據交給一個叫作 WebRTC-Proxy 的模塊,就在這裏, WebRTC-Proxy 要未來自小程序音視頻的音視頻數據翻譯成 WebRTC 理解的「語言」。

(4)最後,在PC上的Chrome瀏覽器,就能夠經過瀏覽器內置的WebRTC模塊跟 WebRTC-Proxy 通信,進而看到小程序端的視頻影像。

(5)上面的四個過程倒過來,就能夠實現雙向視頻通話;而將騰訊視頻雲做爲星型結構的中心節點,多個端(無論是小程序仍是Chrome瀏覽器)都接入進來,那就能夠造成多人音視頻解決方案。

打通房間邏輯

僅僅完成了音視頻數據在小程序和WebRTC之間的握手還遠遠不夠,由於在一次成功的音視頻通話背後,不只僅是把一端的音視頻數據傳遞到另外一端這麼簡單,還有狀態的同步和成員間的狀態協同。

好比多人視頻通話中,涉及到呼叫和接通的流程,其中一方若是掛斷了,其餘人要收到掛斷的通知。同時,若是有新的參與者加入,那麼其餘人也要收到相應的通知。WebRTC 中有不少組件,好比 RTCPeerConnection 就在處理上訴林林種種的邏輯。可是 WebRTC 的接口中引入的新名詞很是多,對於初學者來講仍是有必定的入門門檻,爲了簡化這裏的邏輯,咱們引入一個叫作「房間」的概念。

所謂房間(Room),就是把同時參與視頻通話的各方圈在一塊兒的一個東西。好比雙人通話中,通話中的兩我的 A 和 B 就能夠認爲在一個房間中。再好比在多人通話中,通話中的五我的(A B C D E)也能夠認爲是在一個房間裏。

有了房間的概念,那咱們就能夠對剛纔說的狀態協同用兩個簡單的動做描述一下:若是有一我的加入了視頻通話,那麼就能夠理解爲他/她已經進房(EnterRoom)了;若是有一個退出了視頻通話,那麼就能夠理解爲他/她已經離開房間(LeaveRoom)了。而房間的門板上始終寫着:「目前在房間裏有哪幾我的」。

有了房間的概念,咱們就能夠將小程序的兩個簡單的 和 標籤,同 WebRTC 那一套複雜的 API 進行功能上的對齊,咱們甚至不須要修改咱們在初版中定義的接口,就能夠達成這個目標:

img

(1) 的 url 接口再也不傳遞 rtmp:// 協議的推流地址,而是傳遞 room:// 協議的推流地址。room:// 協議的使用方式能夠參考咱們的原理版文檔 DOC

(2) 標籤在 start 成功以後,就至關於成功進入一個 room,以後,您能夠經過 onPushEvent (PUSH_EVT_ROOM_USERLIST = 1020) 事件,收到房間裏還有那些人的信息。在視頻通話期間,房間內各個成員的進進出出,也都會經過這個事件通知給您的小程序代碼。

(3)ROOM_USERLIST 裏每一項都是一個二元組(若是是 1v1 的視頻通話,ROOM_USERLIST 裏只會有一我的): userid 和 playurl。 userid 表明是哪一個用戶, playurl 則是這個用戶遠程畫面的播放地址。您要作的只是使用 標籤播放這些遠程畫面的圖像和聲音而已。

(4)在 WebRTC 這一端,您能夠參考咱們的 webrtc API,這套 API 相對於 WebRTC 原生的 API,更適合初學者使用。

如何快速接入?

若是您但願一天內就打通 webrtc 和 小程序音視頻 的互通,那麼我推薦您不要從零開始,由於那會耗費您太多時間去踩坑和 bugfix,推薦您直接使用咱們封裝好的 ,這套方案既能夠幫助您完成快速接入,又能知足必定的定製需求。

另外,不要忘記在微信=>發現=>小程序=>騰訊雲視頻雲,體驗一下騰訊雲官方 Demo 中的 WebRTC 互通效果哦。

img

標籤說明

標籤是基於 和 實現的用於 WebRTC 互通的自定義組件。若是您但願直接使用 和 標籤完成對接,或者想要了解 的內部原理,能夠參考 DOC

版本要求

  • 微信 6.6.6 版本開始支持。

效果演示

  • PC 端 用 Chrome 瀏覽器打開 體驗頁面 能夠體驗桌面版 WebRTC 的效果。
  • 微信端 發現=>小程序=>搜索「騰訊視頻雲」,點擊 WebRTC 功能卡,就能夠體驗跟桌面版 Chrome 互通的效果了。

img

對接資料

對接資料 說明 下載連接
小程序源碼 包含的組件源碼以及demo源碼 DOWNLOAD
PC端源碼 基於WebrtcAPI實現的Chrome版WebRTC接入源碼(其中 component/WebRTCRoom.js 實現了一個簡單的房間管理功能,component/mainwindow.js包含了對 WebRTC API 的使用代碼) webrtc(Chrome).zip
後臺源碼 實現了一個簡單的房間列表功能,同時包含幾個所需參數的生成代碼 webrtc_server_list.zip

標籤詳解

屬性定義

屬性 類型 說明
template String '1v3' 必要,標識組件使用的界面模版(用戶若是須要自定義界面,請看 界面定製
sdkAppID String ‘’ 必要,開通 IM 服務所獲取到的 AppID
userID String '' 必要,用戶 ID
userSig String ‘’ 必要,身份簽名,至關於登陸密碼的做用
roomID Number ‘’ 必要,房間號
privateMapKey String ‘’ 必要,房間權限 key,至關於進入指定房間 roomID 的鑰匙
beauty Number 0~5 可選,默認 5, 美顏級別 0~5
muted Boolean true, false 可選,默認 false,是否靜音
debug Boolean true, false 可選,默認 false,是否打印推流 debug 信息
bindRoomEvent function 必要,監聽 組件返回的事件
enableIM Boolean true, false 可選,默認false
bindIMEvent function 當IM開啓時必要,監聽 IM 返回的事件

操做接口

組件包含以下操做接口,您須要先經過 selectComponent 獲取 標籤的引用,以後就能夠進行相應的操做了。

函數名 說明
start() 啓動
pause() 暫停
resume() 恢復
stop() 中止
switchCamera() 切換攝像頭
var webrtcroom = this.selectComponent("#webrtcroomid")
webrtcroom.pause();
複製代碼

事件通知

標籤經過 onRoomEvent 返回內部事件,經過 onIMEvent 返回 IM 消息事件,事件參數格式以下

"detail": {
  "tag": "事件tag標識,具備惟一性",
  "code": "事件代碼",
  "detail": "對應事件的詳細參數"
}
複製代碼

示例代碼

// Page.wxml 文件
<webrtc-room id="webrtcroom"
	roomID="{{roomID}}"
	userID="{{userID}}"
	userSig="{{userSig}}"
	sdkAppID="{{sdkAppID}}"
	privateMapKey="{{privateMapKey}}"
	template="1v3"
	beauty="{{beauty}}"
	muted="{{muted}}"
	debug="{{debug}}"
	bindRoomEvent="onRoomEvent"
	enableIM="{{enableIM}}"
	bindIMEvent="onIMEvent">
</webrtc-room>


// Page.js 文件
Page({
	data: {
		//...
		roomID: '',
		userID: '',
		userSig: '',
		sdkAppID: '',
		beauty: 3,
		muted: false,
		debug: false,
		enableIM: false
	},
    onRoomEvent: function(e){
        switch(e.detail.tag){
            case 'error': {
                //發生錯誤
                var code = e.detail.code;
                var detail = e.detail.detail;
                break;
            }
        }
    },
    onIMEvent: function(e){
        switch(e.detail.tag){
            case 'big_group_msg_notify': 
                //收到羣組消息
                console.debug( e.detail.detail )
                break;
            case 'login_event': 
                //登陸事件通知
                console.debug( e.detail.detail )
                break;
            case 'connection_event': 
                //鏈接狀態事件
                console.debug( e.detail.detail )
                break;
            case 'join_group_event': 
                //進羣事件通知
                console.debug( e.detail.detail )
                break;
        }
    },

  onLoad: function (options) {
		self.setData({
			userID: self.data.userID,
			userSig: self.data.userSig,
			sdkAppID: self.data.sdkAppID,
			roomID: self.data.roomID,
			privateMapKey: res.data.privateMapKey
		}, function() {
			var webrtcroomCom = this.selectComponent('#webrtcroom');
			if (webrtcroomCom) {
				webrtcroomCom.start();
			}
		})
	},
  	
})
複製代碼

使用指引

請確認已經參照 Demo部署 開通了相關服務和並正確的完成了配置。

step1: 下載自定義組件源碼

並不是微信小程序原生提供的標籤,而是一個自定義組件,因此您須要額外的代碼來支持這個標籤。點擊 小程序源碼 下載源碼包,您能夠在 wxlite 文件夾下獲取到所需文件。

step2: 在工程中引入組件

  • 在 page 目錄下的 json 配置文件內引用組件,這一步是必須的,由於 並不是原生標籤。 "usingComponents": { "webrtc-room": "/pages/webrtc-room/webrtc-room" } 在 page 目錄下的 wxml 文件中使用標籤

step3: 獲取 key 信息

按照以下表格獲取關鍵的 key 信息,這是使用騰訊雲互通直播服務所必須的幾個信息:

KEY 示例 做用 獲取方案
sdkAppID 1400087915 用於計費和業務區分 step1 中獲取
userID xiaoming 用戶名 能夠由您的服務器指定,或者使用小程序的openid
userSig 加密字符串 至關於 userid 對應的登陸密碼 由您的服務器簽發(PHP / JAVA
roomID 12345 房間號 能夠由您的服務器指定
privateMapKey 加密字符串 進房票據:至關因而進入 roomid 的鑰匙 由您的服務器簽發(PHP / JAVA

下載 sign_src.zip 能夠得到服務端簽發 userSig 和 privateMapKey 的計算代碼(生成 userSig 和 privateMapKey 的簽名算法是 ECDSA-SHA256)。

step4: 進入房間

self.setData({
	userID: userID,
	userSig: userSig,
	sdkAppID: sdkAppID,
	roomID: roomID,
	privateMapKey: privateMapKey
}, function() {
	var webrtcroomCom = this.selectComponent('#webrtcroomid');
	if (webrtcroomCom) {
		webrtcroomCom.start();
	}
})
複製代碼

界面定製

  • 建立界面模版
//第一步:新建 /pages/templates/mytemplate 文件夾,並建立 mytemplate.wxml 和 mytemplate.wxss 文件

//第二步:編寫 mytemplate.wxml 和 mytemplate.wxss 文件
//mytemplate.wxml
<template name='mytemplate'>
    <view class='videoview'>
        <view class="pusher-box">
            <live-pusher
                id="rtcpusher"
                autopush
                mode="RTC"
                url="{{pushURL}}"
                aspect="{{aspect}}"
                min-bitrate="{{minBitrate}}"
                max-bitrate="{{maxBitrate}}"
                audio-quality="high"
                beauty="{{beauty}}"
                muted="{{muted}}"
                waiting-image="https://mc.qcloudimg.com/static/img/ daeed8616ac5df256c0591c22a65c4d3/pause_publish.jpg"
                background-mute="{{true}}"
                debug="{{debug}}"
                bindstatechange="onPush"
                binderror="onError">
                <cover-image  class='character' src="/pages/Resources/mask.png"></cover-image>
                <cover-view class='character' style='padding: 0 5px;'>我</cover-view>
            </live-pusher>
        </view>
        <view class="player-box" wx:for="{{members}}" wx:key="userID"> 
            <view class='poster'>
                <cover-image class='set'
			       src="https://miniprogram-1252463788.file.myqcloud.com/roomset_{{index + 2}}.png">
				</cover-image>
            </view>
            <live-player
                id="{{item.userID}}"
                autoplay
                mode="RTC"
                wx:if="{{item.accelerateURL}}"
                object-fit="fillCrop"
                min-cache="0.1"
                max-cache="0.3"
                src="{{item.accelerateURL}}"
                debug="{{debug}}"
                background-mute="{{true}}"
                bindstatechange="onPlay">
                <cover-view class='loading' wx:if="{{item.loading}}">
                    <cover-image src="/pages/Resources/loading_image0.png"></cover-image>
                </cover-view>
                <cover-image  class='character' src="/pages/Resources/mask.png"></cover-image>
                <cover-view class='character' style='padding: 0 5px;'>{{item.userName}}</cover-view>
            </live-player>  
        </view> 
    </view>
</template>

//mytemplate.wxss
.videoview {
  background-repeat:no-repeat;
  background-size: cover;
  width: 100%;
  height: 100%;
}
複製代碼
  • webrtc-room 組件引入模版
//爲 <webrtc-room> 組件中的 webrtcroom.wxml 文件添加自定義模版
<import src='/pages/templates/mytemplate/mytemplate.wxml'/>
<view class='conponent-box'>
    <view styles="width:100%;height=100%;" wx:if="{{template=='1v3'}}">
        <template is='mytemplate' data="{{pushURL, aspect, minBitrate, maxBitrate, beauty, muted, debug, members}}"/>
    </view>
</view>

//爲 <webrtc-room> 組件中的 webrtcroom.wxss 文件添加自定義樣式
@import "../templates/mytemplate/mytemplate.wxss";
複製代碼

Chrome端對接

瞭解騰訊雲官網的 WebrtcAPI ,能夠對接 Chrome 端的 H5 視頻通話,由於不是本文檔的重點,此處不作贅述。

實時音視頻產品開通

想要嘗試這些接入,首先要開通騰訊雲實時音視頻,快來接入吧~

問答

怎樣部署小程序?

相關閱讀

教你1天搭建本身的「微視」

教你從0到1搭建小程序音視頻

教你快速搭建一場發佈會直播方案

【每日課程推薦】新加坡南洋理工大學博士,帶你深度學習NLP技術

此文已由做者受權騰訊雲+社區發佈,更多原文請點擊

搜索關注公衆號「雲加社區」,第一時間獲取技術乾貨,關注後回覆1024 送你一份技術課程大禮包!

海量技術實踐經驗,盡在雲加社區

相關文章
相關標籤/搜索