1. 程式人生 > >打通US現金盤平臺出租小程序音視頻和webRTC

打通US現金盤平臺出租小程序音視頻和webRTC

完整 chrome 源碼包 得來 蘋果 deb url 團隊 vid

2017年US現金盤平臺出租【大神源碼論壇】dsluntan.com 【布丁源碼論壇】budingbbs.com 企娥3393756370 騰訊視頻雲團隊跟微信團隊聯合,將視頻雲 SDK 跟微信小程序整合在一起,並通過 <live-pusher> 和 <live-player> 兩個標簽的形式開放內部的功能。通過這兩個標簽,開發者可以實現在線直播、低延時監控、雙人視頻通話以及多人視頻會議等功能。

那麽WebRTC又是什麽?

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

兩者區別在哪裏?

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

如果你對技術比較感興趣,那我們就可以從多個技術的角度去列舉兩者的區別,下面是一張詳細對比的表格:

技術分享圖片
  • 實現原理: 小程序音視頻是將騰訊視頻雲的 liteavsdk 嵌入到微信內部實現的,然後通過 <live-pusher> 和 <live-player> 兩個標簽將 SDK 內部的音視頻能力開放出來。所以小程序的標簽起到了開發者 API 的作用,而內部的 SDK 則是真正用來實現音視頻功能。

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

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

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

  • 移動端碎片化問題 小程序音視頻由於是微信統一實現的,而且微信團隊每個版本都盡量要求功能對齊,否則寧可不上,所以在碎片化問題上基本不存在。

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

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

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

  • 桌面瀏覽器 相信您已經發現US現金盤平臺出租【大神源碼論壇】dsluntan.com 【布丁源碼論壇】budingbbs.com 企娥3393756370 ,在前面幾個問題的分析上,我的觀點都傾向小程序音視頻。確實,在目前國內的移動領域裏,谷歌和蘋果都不能一家說了算,真正說了算的還是微信。

但是在桌面瀏覽器這個部分,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暴露十幾個接口類,而是繼續采用小程序音視頻的 <live-pusher> 和 <live-player> 標簽來解決問題。

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

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

其實不會,因為小程序音視頻和WebRTC的視頻編碼標準在常規應用場景中是一致的,都是H.264標準,這是音頻格式不同而已。這就意味著,翻譯員要做的事情很少,兩邊基本都能挺對對方在說什麽,所以延時不會增加太多。

成功的握手

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

技術分享圖片

(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)了。而房間的門板上始終寫著:“目前在房間裏有哪幾個人”。

有了房間的概念,我們就可以將小程序的兩個簡單的 <live-pusher> 和 <live-player> 標簽,同 WebRTC 那一套復雜的 API 進行功能上的對齊,我們甚至不需要修改我們在第一版中定義的接口,就可以達成這個目標:

技術分享圖片

(1)<live-pusher> 的 url 接口不再傳遞 rtmp:// 協議的推流地址,而是傳遞 room:// 協議的推流地址。room:// 協議的使用方式可以參考我們的原理版文檔 DOC。

(2)<live-pusher> 標簽在 start 成功之後,就相當於成功進入一個 room,之後,您可以通過 onPushEvent (PUSH_EVT_ROOM_USERLIST = 1020) 事件,收到房間裏還有那些人的信息。在視頻通話期間,房間內各個成員的進進出出,也都會通過這個事件通知給您的小程序代碼。

(3)ROOM_USERLIST 裏每一項都是一個二元組(如果是 1v1 的視頻通話,ROOM_USERLIST 裏只會有一個人): userid 和 playurl。 userid 代表是哪個用戶, playurl 則是這個用戶遠程畫面的播放地址。您要做的只是使用 <live-player> 標簽播放這些遠程畫面的圖像和聲音而已。

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

如何快速接入?

如果您希望一天內就打通 webrtc 和 小程序音視頻 的互通,那麽我推薦您不要從零開始,因為那會耗費您太多時間去踩坑和 bugfix,推薦您直接使用我們封裝好的 <webrtc-room> ,這套方案既可以幫助您完成快速接入,又能滿足一定的定制需求。

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

技術分享圖片

標簽說明

<webrtc-room> 標簽是基於 <live-pusher> 和 <live-player> 實現的用於 WebRTC 互通的自定義組件。如果您希望直接使用 <live-pusher> 和 <live-player> 標簽完成對接,或者想要了解 <webrtc-room> 的內部原理,可以參考 DOC。

版本要求

  • 微信 6.6.6 版本開始支持。

效果演示

  • PC 端 用 Chrome 瀏覽器打開 體驗頁面 可以體驗桌面版 WebRTC 的效果。
  • 微信端 發現=>小程序=>搜索“騰訊視頻雲”,點擊 WebRTC 功能卡,就可以體驗跟桌面版 Chrome 互通的效果了。
技術分享圖片

對接資料

對接資料

說明

下載鏈接

小程序源碼

包含<webrtc-room>的組件源碼以及demo源碼

DOWNLOAD

PC端源碼

基於WebrtcAPI實現的Chrome版WebRTC接入源碼(其中 component/WebRTCRoom.js 實現了一個簡單的房間管理功能,component/mainwindow.js包含了對 WebRTC API 的使用代碼)

webrtc(Chrome).zip

後臺源碼

實現了一個簡單的房間列表功能,同時包含<webrtc-room>幾個所需參數的生成代碼

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

必要,監聽 <webrtc-room> 組件返回的事件

enableIM

Boolean

true, false

可選,默認false

bindIMEvent

function

當IM開啟時必要,監聽 IM 返回的事件

操作接口

<webrtc-room> 組件包含如下操作接口,您需要先通過 selectComponent 獲取 <webrtc-room> 標簽的引用,之後就可以進行相應的操作了。

函數名

說明

start()

啟動

pause()

暫停

resume()

恢復

stop()

停止

switchCamera()

切換攝像頭

var webrtcroom = this.selectComponent("#webrtcroomid")
webrtcroom.pause();

事件通知

<webrtc-room> 標簽通過 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: 下載自定義組件源碼

<webrtc-room> 並非微信小程序原生提供的標簽,而是一個自定義組件,所以您需要額外的代碼來支持這個標簽。點擊 小程序源碼 下載源碼包,您可以在 wxlite 文件夾下獲取到所需文件。

step2: 在工程中引入組件

  • 在 page 目錄下的 json 配置文件內引用組件,這一步是必須的,因為 <webrtc-room> 並非原生標簽。 "usingComponents": { "webrtc-room": "/pages/webrtc-room/webrtc-room" }
  • 在 page 目錄下的 wxml 文件中使用標簽<webrtc-room id="webrtcroomid" 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>

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();
	}
})

<h2 id="CustomUI"> 界面定制 </h2>

  • 創建界面模版
//第一步:新建 /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 視頻通話,因為不是本文檔的重點,此處不做贅述。US現金盤平臺出租【大神源碼論壇】dsluntan.com 【布丁源碼論壇】budingbbs.com 企娥3393756370

打通US現金盤平臺出租小程序音視頻和webRTC