前端要實現(xiàn)直播,通常有以下兩種方式:
- RTMP協(xié)議
RTMP(Real Time Messaging Protocol)是Adobe公司獨有的一種可用于直播的傳輸流媒體協(xié)議??梢越⒎掌骱涂蛻舳酥g的遠程調(diào)用和流傳輸通道。
瀏覽器通過Flash插件播放RTMP流,實現(xiàn)直播效果。這種方式需要瀏覽器支持Flash,現(xiàn)在使用較少。
- WebRTC
WebRTC(Web Real-Time Communication)是支持瀏覽器端音視頻流傳輸?shù)募夹g標準。通過WebRTC API,瀏覽器可以獲取媒體流,并在本地進行編碼和處理,然后傳送給其他瀏覽器,實現(xiàn)視頻通話或直播。
實現(xiàn)步驟:
(1) 通過getUserMedia()獲取本地音視頻流
(2) 對流進行編碼,得到二進制的Track軌道數(shù)據(jù)
(3) 通過RTCPeerConnection把編碼后的軌道數(shù)據(jù)發(fā)送給遠端
(4) 遠端通過RTCPeerConnection接收軌道數(shù)據(jù)
(5) 遠端通過播放器進行解碼和渲染
WebRTC是目前最可靠、性能好的瀏覽器端直播方案。它無插件、跨平臺,是直播的首選技術。
什么是WebRTC?
WebRTC(Web Real-Time Communication)是一個谷歌開源項目,它提供了一套標準 API,使 Web 應用可以直接提供實時音視頻通信功能,不再需要借助任何插件。原生通信過程采用 P2P 協(xié)議,數(shù)據(jù)直接在瀏覽器之間交互,理論上不需要服務器端的參與。
“為瀏覽器、移動平臺、物聯(lián)網(wǎng)設備提供一套用于開發(fā)功能豐富、高質(zhì)量的實時音視頻應用的通用協(xié)議”是 WebRTC 的使命。
WebRTC的歷史
隨著網(wǎng)絡基礎設施日趨完善以及終端計算能力不斷提升,實時通信技術已經(jīng)滲透到各行各業(yè),支撐著人們的日常生活。在 WebRTC 誕生之前,實時通信技術非常復雜,想獲得核心的音視頻編碼及傳輸技術需要支付昂貴的專利授權費用。此外,將實時通信技術與業(yè)務結合也非常困難,并且很耗時,通常只有較大規(guī)模的公司才有能力實現(xiàn)。
WebRTC 的出現(xiàn)使實時通信技術得以廣泛應用。WebRTC 制定、實現(xiàn)了一套統(tǒng)一且完整的實時通信標準,并將這套標準開源。這套標準包含了實時通信技術涉及的所有內(nèi)容,使用這套標準,開發(fā)人員無須關注音視頻編解碼、網(wǎng)絡連接、傳輸?shù)鹊讓蛹夹g細節(jié),可以專注于構建業(yè)務邏輯,且這些底層技術是完全免費的。
WebRTC 統(tǒng)一了各平臺的實時通信技術,大部分操作系統(tǒng)及瀏覽器都支持 WebRTC,無須安裝任何插件,就可以在瀏覽器端發(fā)起實時視頻通話。
WebRTC 技術最初為 Web 打造,隨著 WebRTC 自身的演進,目前已經(jīng)可以將其應用于各種應用程序。
隨著 4G 的普及和 5G 技術的應用,實時音視頻技術正在蓬勃發(fā)展。在互聯(lián)網(wǎng)領域,花椒、映客等直播平臺吸引了大量的用戶;在教育領域,通過實時直播技術搭建的“空中課堂”惠及全球數(shù)億學生;在醫(yī)療行業(yè),隨著電子處方單納入醫(yī)保,互聯(lián)網(wǎng)看病、復診正在興起,地域之間醫(yī)療資源不均衡的問題被實時直播技術逐步消除。
WebRTC 1.0 規(guī)范發(fā)布以來,以 Chrome、Firefox 為代表的瀏覽器對 WebRTC 提供了全方面的支持,Safari 11 也開始對 WebRTC 提供支持。
WebRTC的發(fā)展歷史如下:
- 2010 年 5 月,谷歌收購視頻會議軟件公司 GIPS,該公司在 RTC 編碼方面有深厚的技術積累。
- 2011 年 5 月,谷歌開源 WebRTC 項目。
- 2011 年 10 月,W3C 發(fā)布第一個 WebRTC 規(guī)范草案。
- 2014 年 7 月,谷歌發(fā)布視頻會議產(chǎn)品 Hangouts,該產(chǎn)品使用了 WebRTC 技術。
- 2017 年 11 月,WebRTC 進入候選推薦標準(Candidate Recommendation,CR)階段。
WebRTC的技術架構
從技術實現(xiàn)的角度講,在瀏覽器之間進行實時通信需要使用很多技術,如音視頻編解碼、網(wǎng)絡連接管理、媒體數(shù)據(jù)實時傳輸?shù)?,還需要提供一組易用的 API 給開發(fā)者使用。這些技術組合在一起,就是 WebRTC 技術架構,如圖 1 所示。
圖 1 WebRTC技術架構
WebRTC 技術架構的頂層分為兩個部分:
- Web API:一組 JavaScript 接口,由 W3C 維護,開發(fā)人員可以使用這些 API 在瀏覽器中創(chuàng)建實時通信應用程序。
- 適用于移動端及桌面開發(fā)的 libwebrtc:即使用 WebRTC C++ 源碼在 Windows、Android、iOS 等平臺編譯后的開發(fā)包,開發(fā)人員可以使用這個開發(fā)包打造原生的 WebRTC 應用程序。
第二層是 WebRTC C ++ API,它是 Web API 和 libwebrtc 的底層實現(xiàn)。該層包含了連接管理、連接設置、會話狀態(tài)和數(shù)據(jù)傳輸?shù)?API?;谶@些 API,瀏覽器廠商可以方便地加入對 WebRTC 的支持。
WebRTC 規(guī)范里沒有包含信令協(xié)議,這部分需要研發(fā)人員依據(jù)業(yè)務特點自行實現(xiàn)。
WebRTC 支持的音頻編碼格式有 OPUS 和 G.711,同時還在音頻處理層實現(xiàn)了回音消除及降噪功能。WebRTC 支持的視頻編碼格式主要有 VP8 和 H264(還有部分瀏覽器支持 VP9 及 H265 格式),WebRTC 還實現(xiàn)了 Jitter Buffer 防抖動及圖像增強等高級功能。
在媒體傳輸層,WebRTC 在 UDP 之上增加了 3 個協(xié)議:
- 數(shù)據(jù)包傳輸層安全性協(xié)議(DTLS):用于加密媒體數(shù)據(jù)和應用程序數(shù)據(jù);
- 安全實時傳輸協(xié)議(SRTP):用于傳輸音頻和視頻流;
- 流控制傳輸協(xié)議(SCTP):用于傳輸應用程序數(shù)據(jù)。
WebRTC 借助 ICE 技術在端與端之間建立 P2P 連接,它提供了一系列 API,用于管理連接。WebRTC 還提供了攝像頭、話筒、桌面等媒體采集 API,使用這些 API 可以定制媒體流。
WebRTC的網(wǎng)絡拓撲
WebRTC 規(guī)范主要介紹了使用 ICE 技術建立 P2P 的網(wǎng)絡連接,即 Mesh 網(wǎng)絡結構。在 WebRTC 技術的實際應用中,衍生出了媒體服務器的用法。
使用媒體服務器的場景,通常是因為 P2P 連接不可控,而使用媒體服務器可以對媒體流進行修改、分析、記錄等 P2P 無法完成的操作。
實際上,如果我們把媒體服務器看作 WebRTC 連接的另外一端,就很容易理解媒體服務器的工作原理了。媒體服務器是 WebRTC 在服務器端的實現(xiàn),起到了橋梁的作用,用于連接多個 WebRTC 客戶端,并增加了額外的媒體處理功能。通常根據(jù)提供的功能,將媒體服務器區(qū)分成 MCU 和 SFU。
1) Mesh網(wǎng)絡結構
Mesh 是 WebRTC 多方會話最簡單的網(wǎng)絡結構。在這種結構中,每個參與者都向其他所有參與者發(fā)送媒體流,同時接收其他所有參與者發(fā)送的媒體流。說這是最簡單的網(wǎng)絡結構,是因為它是 Web-RTC 原生支持的,無須媒體服務器的參與。
Mesh 網(wǎng)絡結構如圖 2 所示。
圖 2 Mesh網(wǎng)絡結構
在 Mesh 網(wǎng)絡結構中,每個參與者都以 P2P 的方式相互連接,數(shù)據(jù)交換基本不經(jīng)過中央服務器(部分無法使用 P2P 的場景,會經(jīng)過 TURN 服務器)。由于每個參與者都要為其他參與者提供獨立的媒體流,因此需要 N-1 個上行鏈路和 N-1 個下行鏈路。眾多上行和下行鏈路限制了參與人數(shù),參與人過多會導致明顯卡頓,通常只能支持 6 人以下的實時互動場景。
由于沒有媒體服務器的參與,Mesh 網(wǎng)絡結構難以對視頻做額外的處理,不支持視頻錄制、視頻轉(zhuǎn)碼、視頻合流等操作。
2) MCU網(wǎng)絡結構
MCU(Multipoint Control Unit)是一種傳統(tǒng)的中心化網(wǎng)絡結構,參與者僅與中心的 MCU 媒體服務器連接。MCU 媒體服務器合并所有參與者的視頻流,生成一個包含所有參與者畫面的視頻流,參與者只需要拉取合流畫面,MCU 網(wǎng)絡結構如圖 3 所示。
圖 3 MCU網(wǎng)絡結構
這種場景下,每個參與者只需要 1 個上行鏈路和 1 個下行鏈路。與 Mesh 網(wǎng)絡結構相比,參與者所在的終端壓力要小很多,可以支持更多人同時在線進行音視頻通信,比較適合多人實時互動場景。但是 MCU 服務器負責所有視頻編碼、轉(zhuǎn)碼、解碼、合流等復雜操作,服務器端壓力較大,需要較高的配置。同時由于合流畫面固定,界面布局也不夠靈活。
3) SFU網(wǎng)絡結構
在 SFU(Selective Forwarding Unit)網(wǎng)絡結構中,仍然有中心節(jié)點媒體服務器,但是中心節(jié)點只負責轉(zhuǎn)發(fā),不做合流、轉(zhuǎn)碼等資源開銷較大的媒體處理工作,所以服務器的壓力會小很多,服務器配置也不像 MCU 的要求那么高。每個參與者需要 1 個上行鏈路和 N-1 個下行鏈路,帶寬消耗低于 Mesh,但是高于 MCU。
我們可以將 SFU 服務器視為一個 WebRTC 參與方,它與其他所有參與方進行 1 對 1 的建立連接,并在其中起到橋梁的作用,同時轉(zhuǎn)發(fā)各個參與者的媒體數(shù)據(jù)。SFU 服務器具備復制媒體數(shù)據(jù)的能力,能夠?qū)⒁粋€參與者的數(shù)據(jù)轉(zhuǎn)發(fā)給多個參與者。
SFU 服務器與 TURN 服務器不同,TURN 服務器僅僅是為 WebRTC 客戶端提供的一種輔助數(shù)據(jù)轉(zhuǎn)發(fā)通道,在無法使用 P2P 的情況下進行透明的數(shù)據(jù)轉(zhuǎn)發(fā),TURN 服務器不具備復制、轉(zhuǎn)發(fā)媒體數(shù)據(jù)的能力。
SFU 對參與實時互動的人數(shù)也有一定的限制,適用于在線教學、大型會議等場景,其網(wǎng)絡結構如圖 4 所示。
圖 4 SFU網(wǎng)絡結構
Simulcast聯(lián)播
在進行 WebRTC 多方視頻會話時,參與人數(shù)較多,硬件設施、網(wǎng)絡環(huán)境均有差異,這種情況下如何確保會話質(zhì)量呢?使用 MCU 時,這個問題相對簡單一些。
MCU 可以根據(jù)參與者的網(wǎng)絡質(zhì)量和設備能力,提供不同的清晰度和碼率。但是隨之而來的問題是服務器資源壓力較大,難以支撐大規(guī)模并發(fā),同時也顯著增加了使用成本。
多人會話場景選擇 SFU 網(wǎng)絡結構是目前通用的做法。早期的 SFU 只是將媒體流從發(fā)送端轉(zhuǎn)發(fā)給接收端,無法獨立為不同參與者調(diào)整視頻碼率,其結果是發(fā)送者需要自行調(diào)整碼率,以適應接收條件最差的參與者。而那些網(wǎng)絡環(huán)境較好的參與者只能接收相同質(zhì)量的媒體流,別無選擇。
Simulcast 技術對 SFU 進行了優(yōu)化,發(fā)送端可以同時發(fā)送多個不同質(zhì)量的媒體流給接收端。SFU 能夠依據(jù)參與者的網(wǎng)絡質(zhì)量,決定轉(zhuǎn)發(fā)給參與者哪種質(zhì)量的媒體流。
因為發(fā)送者需要發(fā)送多個不同質(zhì)量的媒體流,所以會顯著增加發(fā)送設備的載荷,同時占用發(fā)送者上行帶寬資源。
可伸縮視頻編碼
可伸縮視頻編碼(Scalable Video Coding,SVC)是 Simulcast 的改進技術。它使用分層編碼技術,發(fā)送端只需要發(fā)送一個獨立的視頻流給 SFU,SFU 根據(jù)不同的層,解碼出不同質(zhì)量的視頻流,并發(fā)送給不同接收條件的參與者。
SVC 中多個層次的媒體流相互依賴,較高質(zhì)量的媒體數(shù)據(jù)需要較低質(zhì)量的媒體數(shù)據(jù)解碼。SFU 接收到 SVC 編碼的內(nèi)容后,根據(jù)客戶端的接收條件選擇不同的編碼層次,從而獲得不同質(zhì)量的媒體流。
如果媒體流包括多個不同分辨率的層,則稱該編碼具有空間可伸縮性;如果媒體流包含多個不同幀率的層,則稱該編碼具有時間可伸縮性;如果媒體流包含多個不同碼率的層,則稱該編碼具有質(zhì)量可伸縮性。
在編碼空間、時間、質(zhì)量均可伸縮的情況下,SFU 可以生成不同的視頻流,以適應不同客戶端的接收條件。
WebRTC的兼容性
據(jù)caniuse.com統(tǒng)計,大部分瀏覽器都實現(xiàn)了對 WebRTC 的支持,各瀏覽器支持情況如下:
- Firefox版本22+
- Chrome版本23+
- Safari版本11+
- iOS Safari版本11+
- Edge版本15+
- Opera版本18+
- Android Browser版本81+
- Chrome for Android版本84+
- Firefox for Android版本68+
- IE不支持
Android 和 iOS 原生應用都支持 WebRTC,可以使用原生 SDK 開發(fā)跨平臺的 WebRTC 應用。
Android WebView 自 36 版本之后,提供了對 WebRTC 的支持,這意味可以使用 WebRTC API 開發(fā) Android 混合 App。注意,一些手機廠商對部分 Android 版本里的 WebView 進行了裁剪,導致不能使用 WebRTC,這時候下載并安裝最新的 WebView 即可。
iOS WebView 目前還不支持 WebRTC,但是可以使用 cordova 的插件 cordova-plugin-iosrtc 在混合 App 中使用 WebRTC。
WebRTC 目前處于活躍開發(fā)階段,各個瀏覽器的實現(xiàn)程度不一樣。為了解決兼容性的問題,谷歌提供了 adapter.js 庫。
在 GitHub 上可以下載最新版本的 adapter.js 庫,地址是 https://github.com/webrtc/adapter/tree/master/release。將下載的文件放到 Web 服務器根目錄,在 Web 應用中引用。
<script src="adapter.js"></script>