如何构建高并发高可用的剧场直播云端混流服务?
在LiveVideoStack線上交流分享中,愛奇藝技術研究員李曉威分享了基于愛奇藝Hydra平臺的劇場直播云端混流方案,重點講解如何提升WebRTC推流成功率并提升音視頻質量,如何做到點播流在客戶端和云端同步解碼,以及混流服務如何做到高并發、高可用等。
文 / 李曉威
整理 / LiveVideoStack
直播回放
https://www2.tutormeetplus.com/v2/render/playback?mode=playback&token=308d66a1b64d401a9a983db51a59777d
大家好,我是來自愛奇藝的技術研究員李曉威,在愛奇藝主要負責視頻通話相關業務的落地與視頻混流的技術實踐。接下來我將為大家分享愛奇藝的劇場直播云端混流解決方案。
?
我將從以下三個方面為大家分享今天的話題:
劇場直播背景
云端混流架構
系統優化
我們通過優化提高推流成功率與音視頻質量,并嘗試構建高并發、高可用的混流服務架構。
1.?技術背景
?
劇場直播作為我們的技術背景,與主播端設備上的麥克風與攝像頭采集主播音視頻數據并于本地完成編碼后推送至CDN而后分發給在線的觀眾的游戲直播略有不同,其主要應用場景是主播一邊觀看某視頻,一邊對視頻內容進行評述;同時客戶端用戶在觀看與主播端相同的視頻畫面的同時也會聽到主播對此視頻的評述。相對于游戲直播,劇場直播需要處理兩路流,這里就牽扯到混流問題。混流不僅是為向觀眾呈現更統一的觀看體驗,更是為了節省帶寬占用。但這兩路流的類型、協議、傳輸時間、延遲可能都不同,并且隨著網絡的抖動,數據流也會發生變化。我們應該如何妥善處理混流問題?能否在客戶端進行混流?
?
答案是可以,但在客戶端混流面臨許多問題。如果選擇高清編碼那么混流對上行帶寬的要求非常高,一般的Android手機性能無法承受此性能壓力;同時對一般的家用帶寬而言,上行帶寬資源十分有限,編碼出的結果也會不盡如人意;除此之外,如果手機端沒有一些現成的混流工具,單純采用錄屏方式會造成個人隱私的泄漏,這些都是我們不愿意看到的。
2.?云端混流架構
?
于是云端混流成為我們著力探索的最佳解決方案,我們與英特爾合作,開發了一套被稱為Hydra的云端混流平臺,用于構建我們公司內部的視頻會議系統,支持個人或多人之間的視頻會議,會議桌面投影等功能,同時結合了愛奇藝視頻平臺的SDK與后臺服務使其能夠被用于公司的其他業務如愛奇藝的秀場、直播推流等,接下來我將以劇場直播的直播推流為例。我們主要為Android與iOS開發了客戶端與其相應的SDK,后臺包括SIP呼叫系統、TURN P2P傳輸與MCU混流,硬件平臺則是基于VCA加速卡構建。
?
來看看這個直播推流的架構,這里面有三個角色,第一個有主播,第二個是我們愛奇藝的云服務,第三個就是觀眾,我們看看每個角色它承受的有哪些數據,主播呢,第一,他是要去觀看一個電影,他要去拉點播流,因為一般可能在移動端,他拉下來那個點播流,它可能自適應的話,它可能不是非常高清的,它可能就是一個720P的。另外一方面,這個還要做評述,評述這個我們是用WebRTC,把它推到我們的那個MCU服務器上面去,
?
作為Hydra平臺最核心的組件,MCU混流器用于劇場直播,在接受WebRTC流的同時還會從點播CDN端拉取同樣的點播流,但此點播流的質量要高于主播端點播流;成功拉取兩路點播流之后MCU會對其進行混流處理,根據用戶終端不同觀眾的觀看需求采取不同的混流方案,例如以主播為主畫面,以點播電影為主畫面或使兩種畫面都以高分辨率形式播放。
?
MCU全稱為“多點觸控單元”,負責各種類型的數據接入、轉碼、混流與推送。MCU支持WebRTC、RTMP、F4V等各種直播流點播流與其他數據的接入,同時向外提供向外提供HTTP與SocketIO兩種用于信令控制的接口。
3.?系統優化
3.1 網絡優化
?
接下來我將為大家分享我們對于此平臺所進行的系統優化,包括為了保證推流成功率、速度與畫質,同時降低時延而對網絡、業務框架等進行的優化,同時保證客戶端與服務器端的流狀態同步與高并發下的高可用。
?
許多用戶在使用客戶端訪問服務時都會遇見各種各樣的網絡故障,其中一個很重要的原因是跨運營商問題。例如一個中國電信的網絡用戶訪問基于中國移動網絡部署的服務器,期間出現服務不穩定的情況似乎難以避免。為解決此問題,MCU集群采取了一系列策略,包括在進行數據接入時提供多種數據接入點。例如如果有一個客戶端想要在MCU上推一路WebRTC流,那么他首先需要尋找到數據接入點并向節點調度器發送相應請求,隨后節點調度器會分析此訪問者的IP并識別這是一個電信客戶端,從而在集群中尋找負載最低的電信數據接入點分配給此電信客戶端,使其能夠向此電信接入點上推數據,從而避免跨運營商的網絡接入問題,顯著提高信令連接成功的概率與WebRTC推流的質量。根據我們的實際統計,加入了多運營商可使數據連通的成功率達到99%以上,如果將那些不在我們控制之內的其他業務與其節點考慮在內,我們最終的數據連通成功率為96%。除了移動運營商接入點,我們還有針對小規模運營商設立的多線接入BGP機房與針對海外用戶部署的海外虛擬機,雖然這會使成本有所提高,但相應的面向更多用戶提供高品質服務也能為我們創造更多收益。
?
在MCU混流過程中,點播流與混合后的流都是內網推拉流。其中我們部署了內網機制與外網機制;而我們自己的服務器主要通過內網拉取這些數據,這樣可在提高數據傳輸成功率的同時顯著提升服務訪問速度。
?
除了上述網絡優化內容,我們還針對特殊網絡環境采取了以下應對措施。有時我們會面臨客戶端數據無法上傳的故障,這是由對稱型延遲造成的,面對此情形我們多采用(通用的Turn Server集群也就是P2P數據中轉)的解決方案;而面對IPV6的網絡適配問題,我們在集群中也部署了ipv6的數據節點,從而實現對ipv6協議的兼容;RTP包的尺寸限制也是一項亟待解決的問題,我們在實際應用當中發現客戶端向服務器推送數據時RTP包經常出現推送不成功的故障,其原因在于一些網絡的(MTU)尺寸較小,網絡中的路由器會將那些超過尺寸限制的包拆分并放棄對主包的負責,這就導致終端或者混流服務器MCU無法接收到一個完整的RTP包,繼而導致服務器無法解碼,這就要求我們需要有效控制RTP包的尺寸Size;我們在SDK中加入了對于弱網的優化,如斷網與自動切網就是為了解決手機端wifi與4G網絡切換瞬間服務無法連接MCU的狀況,雖然在切換時用戶并未有察覺但后臺其實已經自動切換并銜接數據鏈路,服務的用戶體驗明顯提高;而多層重試機制,則是為了應對SDK中的某一層的點對點數據通道出現故障,上一層或多層即可重新與MCU建立連接并恢復推流;備災域名同樣至關重要,一旦支持正式業務的某個機房出現故障或整個集群出現問題,我們即可自動且迅速切換到備災域名以確保服務不會受到影響。
3.2 推送質量與時延
?
上文我向大家分享了我們對于網絡優化的一些實踐探索,接下來我將分享推送質量與時延也就是WebRTC流質量控制。上圖展示了WebRTC中RTP傳輸與RTCP質量反饋的工作機制,我們根據RTCP的反饋尤其是RTCP中往返時延也就是RTP的時間與丟包率,可以估算在這之后的H.264編碼器碼率應當設置為多少,并根據碼率調整分辨率;如果網絡環境堪憂那么降低FPS與丟幀處理,或者解碼器發現一段長期編碼錯誤并強制要求編碼器發送IDR編碼等也需要RTCP接收端的編碼器控制來實現。而在底層網絡傳輸的另一端也就是RTP發送端存在一種被稱為FEC的工作機制,也就是將丟失的包作為冗余并要求其重傳。這是WebRTC的一套丟包控制策略,其中包括對碼率估計算法的改進,原因是WebRTC默認的碼率控制算法更適合平穩網絡,而用于WiFi或者其他不穩定的網絡環境時,敏感的碼率控制算法會造成當出現如大量丟包等情況時估算的碼率波動非常之大,我們希望調整控制算法使其預測過程更為平滑。除此之外,改進分辨率調整算法也是我們的一項目標,此項改進主要針對網絡環境變差導致的估算碼率下降,但分辨率卻維持在較高水平,這顯然是對產品體驗不利的。WebRTC可根據編碼器編碼QP判斷圖像質量,QP比較大意味著圖像質量較差,分辨率就會被自動降低,相應的QP也會降低;但此項工作機制在一些設備上并不可用,此時我們就需要另一套可根據當前碼率估算分辨率的策略,我們已將此策略集成至我們的平臺;視頻自動啟停主要是當網絡環境非常糟糕時視頻會長期卡頓在某一時間點處,此時系統可以自動暫停視頻以減少對于帶寬的占用,等待網絡狀況有所好轉時迅速恢復正常播放狀態;我們在直播推流的情形,尤其是面對較差網絡環境時會關閉NACK,以減少時延的影響。
?
云端適配是一項針對推流質量與時延的重要優化,有時在一些WebRTC推流模式下會出現視頻播放的音量非常小或者對某些Codec的支持不佳的情況,此時就需要我們采取云端適配措施,在SDK初始化時檢查云端設備有哪些缺陷并針對不同設備預備相應解決方案。
?
混合流質量控制取決于WebRTC流與點播流的質量,業務后臺會給點播流一個MapData,我們可根據此MapData值獲得其含有很多不同分辨率與格式的點播流。對于點播流而言,系統會調用一種分辨率足夠高,質量足夠好且滿足相應格式需求點播流作為混合流的輸入,從而確保混合后數據流的質量;對于WebRTC流而言,一定程度上的弱網與低質量在可容忍的范圍內,而一旦出現解碼出錯、大面積馬賽克等,系統則會強制要求主播端重新傳輸IDR以確保WebRTC流能夠被正確解碼,從而避免混合后出現花屏等問題。混合流的質量控制,其中的混合流可以是多路輸出,根據不同個體的喜好,系統后臺會為每一個觀眾匹配合適的業務類型,相應的碼率也有所不同。有時當我們面對WebRTC混流畫面的分辨率不斷變化或點播流的分辨率無法確定時,系統會基于畫面縱橫比對圖像做自適應縮放與裁減;如果出現主播開始休息或切換至后臺導致WebRTC流突然中斷的情況,那么我們則需要在混合流中加入過場片段以提示觀眾主播已經下線,確保用戶體驗不會受到不良影響。
?
針對時延的優化同樣必不可少。主播端采集到的WebRTC流會經過MCU混流送至CDN,最終推送至觀眾端,整個過程造成的畫面時延可達兩秒左右。其中的最主要原因是CDN的分發,而MCU混流等其他步驟只占時延的很小一部分。為妥善解決此項問題,我們首先嘗試優化主播推流過程,在主播端向MCU發送連接請求之前提前預判獲知IP等關鍵配置,同時過濾ICE中的一些不必要的IP從而加快整個點對點握手過程;除此之外,我們還嘗試建立DTRS通道以傳遞SRTP密鑰。每當進行一個DTLS握手過程就生成一個DTLS密鑰,一些密鑰的生成時間很長,使用效率更高的算法替換會節省許多時間。
為降低混流造成的時延,我們減小緩沖存儲使得出現時延時通過丟包降低其造成的影響;除此之外我們部署了一套針對編碼器的控制策略,也就是通過合理配置H.264 Codec來降低時延。
觀眾端對于GOP的設置十分敏感,如果GOP設置過大那么觀眾需要等待很長時間才能開播,因此我們建議將GOP設置為2秒左右,確保一般用戶等待兩秒左右即可獲得第一個關鍵幀。
3.3 流狀態同步
?
流進度同步主要是為了應對點播流場景下,當主播快進或者跳過視頻的某一部分時,觀眾端也會同步接收到快進或跳過之后的流數據,還有當主播暫停視頻并截圖分析,或者調整音量時,觀眾端也可同步相應調整。而在直播流場景下,主播有時在直播過程中不想讓觀眾看到自己的畫面,會將視頻流關閉,此時我們也需要在混流時用相應貼圖來取代缺少的一路視頻流。
流進度同步的第一項關鍵點在于點播流的分片下載,愛奇藝的在線視頻流一般會被分為很小的片段而非一個完整的視頻,這樣做是為了方便在CDN分發時,不同的終端用戶可就近選擇CDN下載相應的片段;如果是多片段那么就意味著完成一個片段的下載需要重新建立連接,可能會由于建立連接的過程中一部分視頻片段的缺失造成視頻的短暫卡頓,一般情況下我們會建立一個緩沖區并保證其中預存的幀數目至少滿足10分鐘左右的播放需求,從而避免重新建立連接時用戶觀看體驗受到影響。
緩存視頻流之后,平臺還需要按照時間戳按照一定周期取相應的幀至解碼器進行解碼,以確保最終視頻按照25FPS的幀率解碼與播放,這就是我們所說的點播流幀消費節奏控制。
在前文我們介紹了,雖然客戶端與服務器的點播流在內容上完全一致,但清晰度并不相同,片源的不同導致二者的關鍵幀位置也不經相同,這就需要我們通過快進等方式精準同步關鍵幀;信令不可靠也至關重要,一些代表主播端操作的信令并非主播端的實際操作,可能是由于網絡環境變差導致,此時就需要我們周期性地檢查每個環節的狀態并及時做出調整。
?
A/V Sync是流狀態同步當中的一項重要內容,其包含以下三種情況:
點播流A/V 同步
由于Audio流與Video流的時間戳起點都是0且都以毫秒為單位,每一幀的時間戳間隔均勻,我們只需按照時間戳同步Video與Audio 的jitter buffer。
直播流A/V 同步
由于WebRTC直播流基于RTP包,而Audio與Video第一幀的RTP包時間戳一般不同,且在傳輸過程中第一個包開始時時間戳上就會被添加一個隨機數,這這些都意味著當收到包時MCU難以將其同步處理。此時就需要借助RTCP SR,將NTP與RTP時間戳對齊以方便MCU同步處理Audio流與Video流。
點播流與直播流之間的同步
針對點播流的播放,我們嘗試盡可能將播放進度差異最小化;而針對直播流我們則是降低傳輸時延,通過以上策略盡可能減輕用戶對上述操作的感知;針對混流過程,我們則采取積極的緩沖區丟幀策略與混流器勻速消費等措施盡量保證畫面的平滑。
3.4 高并發、高可用
?
利用MCU實現高并發集群,首先需要混流服務器。這是一個分布式的集群,其中的進程都相對獨立,且進程與進程之間通過IP和端口實現通訊,可隨便部署于某臺機器,同時支持節點的熱插拔;混流服務器的另外一項特性是負載均衡,根據網絡節點的調度情況實時匯報網絡負載,包括上行與下行帶寬、GPU與CPU狀態等;節點調度器在了解每一個節點的負載情況之后就能在獲得新任務請求時知道哪些節點處于空閑狀態并科學分配節點負載,從而保證最終所有節點的負載均衡;對于整個視頻編碼行業來說,硬件加速的潛力十分巨大,所以我們使用了非常多的視頻編解碼卡以加快處理速度并顯著降低成本。
?
為有效應對高并發狀況并確保整個網絡的高可用,我們需要此集群能夠適應各種網絡突發狀況。客戶端通過域名訪問我們的業務,而此域名并非直接來自我們實際的服務器IP而是來自虛擬IP;通過虛擬IP代替真實IP,其下有一系列集群:工作集群主要用于處理一般性任務,臨時集群則會在主播上線時投入使用,而備災集群則是為了應對突發狀況。其中的工作集群由于在大部分時間中都會投入使用,其掌握最豐富的資源;臨時集群與備災集群則被分配了適量的資源。假設最底層的工作集群中有關鍵進程出現中斷,那么監控機制會立即作出反應并啟動備用進程接管工作來維持服務的穩定;客戶端的SDK一旦發現某一域名無法訪問系統就可以自動切至備災域名,同時觸發報警以通知運維人員及時做出干預這種異常自適應可極大提高平臺整體的穩定性。同時我們也進行了撥測,通過對集群的周期性波測來確保報警的及時與有效;基礎監控同樣必不可少,其主要職責是監控服務器的CPU、網絡、磁盤等相關參數,一旦有某一參數超過我們設定的閾值,系統就會報警以通知運維人員排查相關問題;借助業務統計與日志投遞,系統會定期調查業務的成功率并將相關信息通過電子郵件等形式告知我們,使我們及時獲知整個平臺的運行情況,并在業務成功率出現異常時第一時間作出干預。
LiveVideoStack? 招募
LiveVideoStack正在招募編輯/記者/運營,與全球頂尖多媒及技術專家和LiveVideoStack年輕的伙伴一起,推動多媒體技術生態發展。了解崗位信息請在BOSS直聘上搜索“LiveVideoStack”,或通過微信“Tony_Bao_”與主編包研交流。
LiveVideoStackCon 2019北京正在招募講師,無論你是技術派還是學術派,亦或是行業專家,無論你的團隊有多小、有多新,都可以來申請成為LiveVideoStackCon的講師。點擊【閱讀原文】了解更多大會相關信息。
總結
以上是生活随笔為你收集整理的如何构建高并发高可用的剧场直播云端混流服务?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LiveVideoStack线上分享第三
- 下一篇: 音视频技术的高光时刻: LiveVide