QQ视频直播架构及原理
作者:王宇(騰訊音視頻高級架構(gòu)師)
自我介紹下,畢業(yè)以來加入騰訊,一直從事客戶端研發(fā),身處互聯(lián)網(wǎng)公司,踏著互聯(lián)網(wǎng)的浪潮,一直在浪尖行走,從最早的PC QQ,到移動時代的手Q,再到騰訊物聯(lián)的嵌入式,以及最近這兩年直播領(lǐng)域風(fēng)起云涌,接下來主要給大家介紹下QQ視頻直播的架構(gòu)及原理。
今天主要給大家介紹三個方面的內(nèi)容,視頻直播的框架及基礎(chǔ)介紹;
直播中的一些關(guān)鍵技術(shù):主要包括播放控制問題,性能與質(zhì)量等;直播APP的整體解決方案。
首先來看下直播前后臺的大致框架,通過推流App或者第三方推流器將數(shù)據(jù)推送給后臺服務(wù)器;
服務(wù)器將收到的數(shù)據(jù)進行轉(zhuǎn)碼發(fā)送給DC;
觀看者從OC上拉取對應(yīng)的直播流進行觀看;
目前主要采用RMTP、HLS、FLV三種直播格式。接下來我們重點看下直播過程中客戶端架構(gòu)。
這是直播客戶端的大體框。
左側(cè)是推流端:音視頻采集;預(yù)處理;音視頻編解碼;數(shù)據(jù)封裝網(wǎng)絡(luò)發(fā)送;
右側(cè)是播放端:網(wǎng)絡(luò)收數(shù)據(jù);音視頻解碼;視頻渲染與音頻播放。
整個過程就是一個線性的流水化過程,流程看起來還是比較簡潔的。
視頻編碼,就是一個壓縮的過程,如何將視頻數(shù)據(jù)壓縮后便于網(wǎng)絡(luò)傳輸,這里有幾個緯度:
1.每一幀數(shù)據(jù)的幀內(nèi)壓縮,也就是這里的I幀,能夠獨立還原出圖像數(shù)據(jù),一般比較大;
2.連續(xù)的兩幀畫面之間存在相似性,參考前面一幀數(shù)據(jù),只記錄差異部分,這樣數(shù)據(jù)量就比較小,也就是這里的P幀,采用的是前向預(yù)測編碼;
3.更進一步,如果參考前后兩幀數(shù)據(jù)記錄差異部分,這樣數(shù)據(jù)量會更小壓縮率最高,也就是這里的B幀,采用雙向預(yù)測內(nèi)插編碼。
麥克風(fēng)采集到的原始PCM數(shù)據(jù)一般比較大,以44.1k,雙聲道為例,碼率大概有1M多,不做壓縮的話很難傳輸,音頻編碼,就是將采集到的PCM數(shù)據(jù),根據(jù)不同的音頻格式進行壓縮,當(dāng)然目的也是為了在保證音質(zhì)的前提下盡量壓縮音頻數(shù)據(jù),目前采用的是AAC來壓縮。
流媒體音視頻數(shù)據(jù)封裝格式,原始的編碼之后的音視頻數(shù)據(jù)不太利于網(wǎng)絡(luò)傳輸,目前有多種封裝格式:
1.RTMP協(xié)議,需要做拆包與組包,將每個數(shù)據(jù)幀拆成小分片加上協(xié)議頭發(fā)送,一般用于推流;
2.FLV格式,比較簡單每個數(shù)據(jù)幀加協(xié)議頭,一般用于播放;
3.HLS格式,將一組音視頻數(shù)據(jù)組合在一起,通過m3u8文體來關(guān)聯(lián),相當(dāng)于一個個的小文件,適用于網(wǎng)頁播放。
直播的框架及基本原理就這么簡潔,但是要做到好的體驗卻不是一件很簡單的事情,基本上幾個人花一兩個月就能做出來,但是要優(yōu)化出一個好的效果需要長期的積累與打磨。
接下來主要看下直播過程中的一些關(guān)鍵問題,主要包括:首屏秒開、流暢與延遲控制、實時音畫同步等等。
當(dāng)我們觀看一個直播的時候不能等半天才出畫面,體驗顯然很差,我們期望的是能夠立馬看到畫面,即首屏秒開。
首先來看下解碼過程:推流端上傳P幀,播放端拉到一個P幀,如果幀連續(xù),能立馬解出來正常顯示;如果沒有之前的參考幀,而僅僅只收到了一個P幀,解析不出來不能顯示,直到遇到一個關(guān)鍵幀;如果要做到數(shù)據(jù)來了就能立馬顯示,對于首次打開就必須要能收到一個I幀,那么問題來了,服務(wù)端如何保證返回給播放端的第一幀為I幀?
假設(shè)有一個人正在觀看,推流端上傳一個P幀,服務(wù)器將其發(fā)送給播放端,播放端正常播放,同時服務(wù)器將其放到一個緩存隊列里面;有了這樣一個臨近數(shù)據(jù)的緩存隊列,當(dāng)有一個新的觀看者來播放的時候,就可以直接從緩存隊列里面取最新的一個GOP一次性返回給觀看端,此時播放端就可以立馬解析出I幀渲染,這樣就能做到秒開。
流暢與時延控制,對播放而言,來數(shù)據(jù)就播放,這個問題應(yīng)該就這么簡單,但是..
播放有兩類需求:
1.游戲場景下更關(guān)注流暢性;
2.主播場景下更關(guān)注低延遲;
于是就有了流暢與極速兩種模式,流暢就是緩沖播放,極速就是來數(shù)據(jù)就播放,緩存大的時候就做速播;看起來還不錯,但是..
實際使用發(fā)現(xiàn)流暢模式會帶來延遲大的問題,而極速模式卡頓的概率又比較高;有沒有一種更好的方案?這里問題的根源在于網(wǎng)絡(luò)是抖動的,要保證低延遲的同時又能流暢播放,其實就是在流暢與低延遲之間做平衡;應(yīng)該怎么設(shè)計?
對于播放端而言,網(wǎng)絡(luò)來數(shù)據(jù),自己播放,這就是一個生產(chǎn)消費模型,正常情況是生產(chǎn)多少,消費多少,但網(wǎng)絡(luò)抖動引發(fā)卡頓與數(shù)據(jù)堆積從而造成時延。
這里統(tǒng)計過去一段時間內(nèi)的數(shù)據(jù),有兩個指標(biāo):
1.待播放數(shù)據(jù)的大小反應(yīng)時延,即這里的過去一段時間內(nèi)的AvgCache;
2.過去一段時間內(nèi)的網(wǎng)絡(luò)抖動大小決定了待播放數(shù)據(jù)抖動的大小,也即決定了卡頓,即這里的Jitter,Jitter隨時間推移而修正。
平均cache太大即延遲大,為了消除延遲就需要快速消耗掉一部分?jǐn)?shù)據(jù),這里要消耗掉多少數(shù)據(jù)呢?
理想情況下是要調(diào)整到紅色曲線所示的,加速MinCache的數(shù)據(jù),這樣既能保證不觸發(fā)卡頓又能做到最小延遲,但是這太理想化了,這里需要更謹(jǐn)慎一些,于是做了以下調(diào)整:
1.引入最小閾值,如圖所示最多加速到這個程度;
2.不是一次加速到最佳狀態(tài),設(shè)定最大加速時長。
總結(jié)下,統(tǒng)計數(shù)據(jù)決策加速;計算調(diào)整時長,恒定加速;如此循環(huán),就能調(diào)整到一個最佳狀態(tài),這就是自適應(yīng)播放控制策略。
這里加速有三種策略:
1.直接丟棄部分?jǐn)?shù)據(jù);
2.短時的快速播放;
3.長時的較快速的播放,讓人察覺不到在速播。
這里問題的根本就是要多消耗一部分?jǐn)?shù)據(jù),毫無疑問不論是丟棄、快速加速、慢速加速都是有損的,三種方案各有優(yōu)劣,瞬時的大損傷好,還是長時的低損傷好?這里還是看個人喜好,蘿卜白菜各有所愛,最終還是要看用戶反饋來選擇。既然做了速播,那不可避免會遇到音畫不同步的問題,如何解決?
音畫如何做同步?
經(jīng)典的音畫同步有三種方案:音頻同步到視頻;音視頻同步到外部時鐘;視頻同步到音頻;
方案一音頻很難去頻繁的做調(diào)速,所以直接pass了;
方案二在卡頓的時候需要做時間修正,做加減速的時候保持步調(diào)一致不是很好處理;
方案三視頻同步到音頻比較自然,視頻能夠很方便做調(diào)速處理,目前大多推薦的也是方案三,實現(xiàn)起來也比較簡單,接下來看下整個播放控制方案。
音視頻jitter隊列分開方便取數(shù)據(jù),控制器根據(jù)jitter大小及當(dāng)前策略來決定加速還是正常播放;
音頻按需播放,在最末端,音頻將PTS同步給視頻,視頻據(jù)此修正當(dāng)前幀的播放時機,解決音畫不同步問題;
引入一個負(fù)反饋機制來保證解碼后的數(shù)據(jù)不會太大;
聲音如何加速,聲音處理有變調(diào)變速,變調(diào)不變速,變速不變調(diào),這里采用了變速不變調(diào)算法來對聲音進行加速。
來看下實際效果,這分別是兩種損傷模型下的效果,左邊的是瞬時高損傷,右邊的是長時低損傷;可以感受下兩種的不同效果。
高分辨率下性能如何保證,360p一般都能達到比較好的性能,那么問題來了,720P推流與播放、1080P播放性能如何保證?主要包括以下幾個方面:
1.整個系統(tǒng)采用多線程處理,推流與播放都是流水化的過程,每個處理流程都采用獨立線程,每秒幀率完全由單一處理過程的最大耗時決定,而不是整個流程的處理時間。
2.多核手機已經(jīng)普及,采用軟編軟解能夠在手機性能達標(biāo)的情況下完成高幀率編解碼。
3.目前手機基本都支持硬編硬解,對于高分辨率采用硬件編解碼,可以顯著降低CPU占用,提升性能。
4.能用GPU處理的盡量用GPU來做,如本地渲染與鏡像處理、格式轉(zhuǎn)換等。
5.采用ARM指令集優(yōu)化來提升性能,比如視頻裁剪、旋轉(zhuǎn)等算法。
既然做直播SDK,那么有問題如何定位?直播質(zhì)量如何監(jiān)控?
這里問題主要包括兩大類:
1.開發(fā)測試過程中遇到的問題;
2.用戶現(xiàn)網(wǎng)問題;這里直播質(zhì)量主要包括CPU占用率、卡頓率、播放延遲、上下行帶寬等等。
用戶遇到的問題如何怎么定位,LOG肯定是第一手資料,如何方便快捷的獲取到LOG?
這里有一套LOG提取系統(tǒng),三個步驟:獲取地址軟色、問題重現(xiàn)、提取log分析;這個就是我們的LOG提取系統(tǒng)。
為了監(jiān)控直播質(zhì)量,這里做了完備的數(shù)據(jù)上報及分析系統(tǒng),基本上涵蓋了各種關(guān)鍵性指標(biāo),既能反應(yīng)直播的各種性能方便優(yōu)化,同時也能輔助定位各種問題;這個是播放端的整體統(tǒng)計數(shù)據(jù),下行帶寬、卡頓率、緩沖大小、CPU占用率,這是一個宏觀統(tǒng)計數(shù)據(jù),反應(yīng)了當(dāng)前直播觀看端的一個質(zhì)量。
有了直播質(zhì)量監(jiān)控,更精細(xì)一些我們可以做一些運營分析,比如說,最近我們內(nèi)部對一個游戲直播的流暢性做了一個運營統(tǒng)計分析,把外網(wǎng)用戶分成了三組,通過配置不同的播放端參數(shù)來統(tǒng)計質(zhì)量,最后我們得出了幾個比較有意思的結(jié)論:
這是對直播推流端做的一個質(zhì)量評估,根據(jù)一些指標(biāo)對每項進行打分,然后給出一個綜合得分來評估當(dāng)前直播推流端的質(zhì)量。
這個是直播后臺的整套大體框架。
上面主要是完成視頻的推流與播放,包含了接入集群,計算集群及CDN加速網(wǎng)絡(luò);
下面主要是帳號、消息等基礎(chǔ)服務(wù),及社交互動系統(tǒng),我們使用這些后臺服務(wù)構(gòu)建了小直播的App。
小直播客戶端App及業(yè)務(wù)后臺源碼對客戶開放,提供了直播App的整套集成解決方案,基于此可以很方便的完成一款直播App的開發(fā)。
這個就是我們做的小直播App,可以在官網(wǎng)下載體驗。
總結(jié)
以上是生活随笔為你收集整理的QQ视频直播架构及原理的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 原来... C++ explicit的作
- 下一篇: MVC模式和文档/视图结构