紅點王宇航:以實時鏈接場景爲目標的一些技術架構探索

圖片描述

文 | 紅點聯合創始人 王宇航javascript

我今天分享的主題,是以實時鏈接場景爲目標的一些技術架構探索。主要是關於紅點在產品研發過程當中,咱們的技術選擇,架構變化,還有這個過程當中,咱們的一些考慮。java

有不少科幻的做品,描述人類突破天然界對時間、空間的客觀限制,去作一些事情。互聯網在不少方面已經對咱們的這種能力有了一個很強的補充,好比咱們每一個人均可以用微信,能夠實時的與不一樣地域的人們對話。可是咱們以爲這個能力還能夠進一步提升,尤爲在多人的場景。linux

咱們但願在互聯網上可以進一步提升信息的傳輸效率,進一步下降信息的傳輸延遲,去讓一些線上的多人場景,有更好的體驗。這是咱們技術迭代的初衷,因此在後面的內容裏你們能夠看到,咱們不少的技術選擇跟這一點有很大關係。android

紅點的第一個版本nginx

紅點的第一個版本功能比較簡單。咱們當時要作一款手機端能夠錄音,網頁端能夠播放的直播產品。手機端只支持 iOS 就能夠了,可是要可以全平臺播放。對這個版本迭代的要求是可以快速上線,提供服務。c++

這個功能需求中,首要的問題是調研各個平臺的 web 頁面支持哪些音頻直播格式。你們在圖上能夠看到調研結果,可是這個不是咱們當時就使用的方案,這是咱們花了一段時間經過線上實際運行的狀況,總結的一個方案。golang

圖片描述

這裏咱們只列了兩個格式,HLS,這是蘋果主力推廣的手機網頁直播格式 Http Live Streaming,這個格式其實是一個多媒體的播放列表,這個列表要求最少有三個文件,每一個文件是一個獨立的多媒體文件,經過在播放端循環更新文件列表,依次將最新的多媒體文件插入本地播放列表,順序播放,來實現直播的效果,這個格式作直播的延遲在 8 秒以上會比較穩定,也就是每一個文件的時長應該在 2 秒以上;另外一個格式是 Http mp3 流,這個流是一個直播的流,不是咱們平時常常見到的 mp3 點播的格式。web

Pc 平臺由於有 flash 對富媒體的支持,咱們產品要求的多媒體形式都有成熟解決方案,好比基於 tcp 的 rtmp 協議,這是 adobe 公司推出的流媒體協議,等等。 iOS 平臺上,蘋果大力推廣 HLS 做爲他的標準格式,因此在 iOS 平臺上也沒有太多問題。算法

可是在安卓平臺上狀況並不理想。可能開發過須要運行在安卓平臺上的 native 應用或者 H5 頁面的朋友可能會了解,因爲安卓廠商種類繁多,各自又存在脫離安卓標準修改 rom 的狀況,安卓平臺對多媒體的兼容性有很大問題。咱們對 HLS 調研的狀況最誇張的時候,複雜度是瀏覽器種類 設備種類 安卓系統版本 *安卓 Rom 種類。咱們本身作的小樣本調研結果是,大約一半的安卓瀏覽器,包括應用內的 webview,沒法正確播放HLS格式的直播。可是對於 Http mp3 流這種音頻直播格式,效果就好不少,支持的比例在 90% 以上。windows

咱們最初的全平臺使用的是 HLS 方案,而後逐步過渡到, PC 網頁和 iOS 使用 HLS 方案,安卓使用 http mp3 流的方案。

圖片描述

這是咱們初版產品的架構。客戶端使用 tcp 協議上傳 mp3 流,這裏對照可選的還有 http 和 udp 兩種,不過這兩種的研發成本都較 tcp 高一些。咱們這個版本的後臺服務是一個單機的服務,支持接收 mp3 流的上傳和 http mp3 流分發,同時可以本地落盤生成 HLS 切片和文件列表。HLS 經過 nginx 反向代理,對外提供分發服務。

歷史回聽

圖片描述

接着咱們對這個版本作了一次功能迭代,此次功能迭代咱們主要增長了音頻直播的歷史回聽。因此咱們增長了新的後臺服務,用於將直播結束後生成的歷史多媒體文件上傳到 UPYUN 上面。這個功能的主體部分咱們是依靠 UPYUN 來完成的,這節省了咱們大量的成本、時間和精力。你們都知道創業團隊不少時候就是在跟時間和成本賽跑,因此可以直接使用成熟的第三方服務,是很是有幫助的。

多人語音

圖片描述

而後咱們產品功能作了一次大的更新。咱們須要實現多人語音功能,支持 iOS 和安卓兩個平臺的錄音和播放。這裏的多人語音是一個語音會議的能力,好比像 yy 語音,qtalk 這樣的,可以多人實時會話的產品功能。

這個功能引入了這幾個技術點,你們能夠看到。首先是混音,混音就是將多路聲音混爲一路聲音。這是咱們播放能力帶來的衍生需求。在 flash 裏面,播放多路聲音是沒問題的,就是同時下載多路流,而後播放就好了,可是在手機 H5 頁面裏,沒有這個能力。手機 H5 頁面只容許同時播放一路聲音,這就要求咱們必須在後臺實現多路轉一路這個功能,而後才能支持手機 H5 的播放。

而後是音頻格式。 Mp3 格式並不適用於低延遲場景, mp3的編碼延遲在 200ms 左右,這在音頻編碼中是特別高的。而且 mp3 這個格式自己是上下文相關的,也就是說一段聲音的編解碼依賴上一段或者下一段,這個特色也不適用於音頻會議這種功能需求。因此咱們須要選擇一個新的音頻格式。

下一個是網絡協議,我初版使用 tcp 的傳輸格式,可是基於 tcp 的協議有一個很嚴重的問題,就是沒法改變擁塞控制策略。Tcp 在遇到有丟包的狀況時,會有很是嚴重的懲罰,影響傳輸效率,這也是語音通話不能容忍的,須要使用基於 udp 的協議來傳輸音頻數據。

還有一個我沒有列在上面的,是 AEC,也就是回聲消除。什麼是回聲消除呢,這個場景特別好理解。就是咱們打電話的時候,若是咱們打開免提,若是電話的回聲消除作的很差,就會出現很是刺耳的尖叫聲音,這個聲音叫嘯叫。這是因爲設備自己的錄音中包含了這個設備本身播放的聲音,若是不能在錄音中把本身播放的這部分去掉,就會出現循環,也就無法使用了。這個點咱們在產品體驗上規避了一下,咱們要求安卓用戶必須帶耳機纔可使用多人語音功能, iOS 由於蘋果提供系統支持,效果很是好,因此在 iOS 上沒有這個問題。

相關項目與方案

圖片描述

右邊是一些相關的項目和方案。

FFmpeg 是業界最流行的多媒體處理框架和多媒體處理工具集。它有一套成熟的多媒體處理架構,包括從採集到編解碼,格式轉換等一系列處理需求。它還整合了大部分音視頻格式的封裝與解析工具,音視頻編解碼器,公共的工具函數,還有視頻後期的效果處理等功能服務。支持命令行使用,也支持做爲函數庫使用。

WebRTC 實現了基於網頁的視頻會議,標準是 WHATWG 協議,目的是經過瀏覽器提供簡單的 javascript 就能夠達到實時通信能力。它的音視頻處理部分源自於 google 收購的一家ip 解決方案服務商 Global IP Solutions,這個引擎是這個公司的核心技術之一。 它包括音視頻的採集、編解碼、網絡傳輸、顯示等功能,而且還支持跨平臺: windows,linux ,mac, android 均可以使用。

其中有兩個模塊對語音會話有顯著做用, NetEQ 和 aecm 。NetEQ 是自適應抖動控制算法以及語音包丟失隱藏算法。使其可以快速且高解析度地適應動態的網絡環境,確保音質優美且緩衝延遲最小。 NetEQ 對聲音的優化通常是經過減慢部分音頻的播放速率,或者加快部分音頻的播放速率,以及使用音頻編解碼自身的特性恢復丟包,等幾個策略綜合調節實際的播放效果。

Aecm 是 aec for mobile 的意思,是專門爲移動端優化的回聲消除算法。這個模塊自己的功能沒問題,可是在安卓上,因爲設備種類的問題,每一個設備仍然須要自行適配這個模塊的一些參數。其中一個最重要的參數是播放到採集的延遲,這個延遲是指從調用 API播放原始聲音數據,到這段聲音數據被手機採集,經過手機的錄製回調返回給程序,期間的間隔時長。這個時間參數對回聲消除的效果影響是最大的。

Rtp、rtcp 是 rfc 標準的音視頻傳輸協議。其中 rtp 是針對互聯網上多媒體數據流的一個傳輸協議, rtcp 是負責管理傳輸質量在當前應用進程之間交換控制信息的協議。通常實際使用須要兩種協議共同配合。 Rtp 能夠是基於 udp 的也能夠是基於 tcp 的。Webrtc 的網絡傳輸就是基於 rtp、rtcp 的。

Live555 是 c++ 實現的,支持 rtp、rtcp 、rtsp、 sip 的開源服務器。

圖片描述

咱們本身重點對比了自研的方案和基於 webrtc 二次開發的方案。咱們本身對自研工做的評估是這樣的,咱們須要實現的協議最小功能集合包括兩個點,一是協議要支持應用層的會話管理,二是協議要支持傳輸數據的排序。支持這兩個點的功能,就能夠初步實現多人語音了,不過效果還有很大提高空間。這個方案的實現成本能夠接受,可是在將來面對協議擴展等問題時,存在必定的風險。

Webrtc 是成熟框架,有 google 支持,而且是跨平臺項目。可是 Webrtc 是客戶端項目,沒有配套的成熟服務器,只有用於 p2p 的配對開源項目。同時, webrtc 並不是只實現了 rtp、 rtcp 協議的基本格式,它裏面增長了一些擴展字段,用於支持前向糾錯和流控,也就是擁塞控制。這就須要咱們本身對照他的協議,實現一個配套的服務,而且要給出分佈式方案。因此雖然 webrtc 有完整的多媒體處理流程,可是總體的使用成本仍是很高,因此咱們最後選擇了自研的方案。

音頻格式

![圖片描述

這兩幅圖是幾種音頻格式特性的對比,兩幅圖來自 opus 的官網,左圖縱軸表示壓縮的效果,橫軸表示支持的採樣率,右圖的縱軸是編解碼的延遲,編解碼延遲是指輸入必定時長的音頻數據到輸出壓縮後對應的音頻幀的時間間隔,橫軸是碼率。 Opus 壓縮後的實際效果是否真的在數值上這麼出色,咱們沒作詳細的測評,可是咱們對比了 ilbc 和 opus 對音樂壓縮的效果, opus 在人聲之外的場景仍然很是出色,而且編解碼延遲也的確是如圖中表示的這樣,因此咱們多人語音採用的音頻格式是 opus 編碼。

初版多媒體接入節點設計

圖片描述

這裏左圖是多人語音上傳分發功能的多媒體服務節點結構。每一個節點由三個模塊組成。 Room 模塊實現房間對多媒體數據的廣播;同時會將本地用戶上傳的數據轉交給 Master 模塊;Master 會將本地的上傳數據同步給其餘節點的 Slave 模塊;Slave 模塊是與 Master 配對的接收數據同步的模塊。這個節點結構是同構的,每一個節點的程序自己都同樣,在部署的時候只有配置不一樣。

這要求整個服務內部節點之間必須是全連通的組織方式,每兩個節點之間都須要有一個數據同步的鏈路。這種架構的好處是研發、運維成本很低,能夠很容易的實現必定程度的可靠性和可用性。對於宕機節點,能夠直接將這個點從服務列表中摘除,受影響的用戶會自動因爲本地網絡失敗,選擇其餘節點的服務。這個架構的問題在於,沒法跨機房部署。因爲是全連通的組織形式,若是跨機房,會致使機房間存在大量可能影響服務質量的數據鏈路,難以作網絡優化。

這是多人語音功能的架構。其中 codec 服務是 ffmpeg 的網絡封裝,方便橫向擴展。 Http mp3 流和 HLS 切片的輸入是混音服務的輸出。對 web 全平臺經過 CDN 分發。

多媒體接入節點重構

圖片描述

這個版本上線之後,接着咱們對多媒體服務節點作了一次重構。從全連通的組織形式改爲樹形組織形式。每一個服務節點由兩個模塊組成, Room 模塊實現對房間用戶的廣播, Client 模塊是 Room 配對的客戶端,用於實現節點間的數據節點。每一個節點有一個惟一的 ID,經過 ID 判斷數據的同步是否會產生數據迴路。當須要跨機房部署的時候,只須要多個機房可以共同經過同一個根節點進行數據同步便可完成整個功能。節點間咱們增長 etcd 提供服務協調能力,etcd 是 golang 版本的類 zookeeper 服務。

視頻

圖片描述

多人語音以後咱們增長了視頻功能。視頻功能的要求也是一個會議的場景,須要延遲儘量低。咱們爲協議增長了重傳能力,前向糾錯能力和選擇重傳算法。增長了私有協議轉 RTMP 流的服務,和一套音視頻同步的機制。轉成 RTMP 標準輸出之後,經過 CDN 支持 web 的播放。下面咱們詳細的看一下每個技術點和架構選擇。

H264格式的視頻有三種幀,I 幀 P 幀和 B 幀,其中 I幀能夠獨立解碼顯示,可是 P 幀和 B 幀都直接或者間接依賴最近的 I 幀。因此若是 I 幀存在數據丟失,會形成大片持久的馬賽克,這個在視頻體驗上是不能容忍的,因此重傳在這裏是必要的。 FEC,也就是前向糾錯,是對重傳的一種補充,經過增長數據傳輸過程當中的冗餘比例,實現丟包恢復。

咱們採用的是多項式方程的方案,這個方案能夠自由調節冗餘的比例和尺度。 Webrtc 中採用的冗餘算法是異或的方案,異或的方案只能容忍一個數據包的丟失,沒法處理連續丟失。選擇重傳算法要求數據重傳要有時間限制和長度限制,這個算法自己是提升重傳效率,提升網絡利用率。

音視頻同步這部分咱們採用以音頻爲主時間線的方案。是由於人耳對聲音更敏感,而對畫面容忍度較高。

混流這部分咱們實際採用的是客戶端混流的方案。這裏涉及到音視頻複用,就是在服務器將音視頻作好時間同步,再經過一個數據鏈路發送到客戶端,或者在客戶端作音視頻複用,兩個方案。因爲服務器的複用處理會引入額外延遲,咱們最終選擇音頻與視頻,採用平行的系統提供上傳與分發服務。這也帶來了一個產品上額外的好處,就是當畫面卡頓時,能夠很容易的選擇只播放聲音,中止播放視頻畫面。

以上就是咱們在迭代產品過程當中的技術架構變遷。

本文整理自 紅點直播聯合創始人 王宇航 於 11 月 28 日在 「UPYUN 架構與運維大會·北京站」 上的主題演講。

查看&下載本次大會所有講師的演講 SLIDES 及現場視頻,請訪問:http://opentalk.upyun.com/show/issue/29

相關文章
相關標籤/搜索