這個方向應(yīng)該是今年最火的了。7月份和8月份就接到直播公司的面試邀請,只不過當(dāng)時沒多少這方面的經(jīng)驗。之前的關(guān)于直播平臺的開發(fā),我的方向一直都是iOS多媒體開發(fā)工程師的,沒想太多。但是,逐漸的了解到很多公司都是接的第三方的直播框架和CDN。譬如樂視云,騰訊云,七牛等平臺的SDK。待續(xù)吧,東西太多了,之前藏了很多沒開放,因為很多想表達(dá)的東西不知道表達(dá)了。
直播服務(wù)普遍采用了RTMP作為流媒體協(xié)議,F(xiàn)LV作為封裝格式,H.264作為視頻編碼格式,AAC作為音頻編碼格式。采用RTMP作為直播協(xié)議的好處在于其被Flash播放器支持。而Flash播放器如今已經(jīng)安裝在全球99%的電腦上,并且與瀏覽器結(jié)合的很好。因此這種流媒體直播平臺可以實現(xiàn)“無插件直播”,極大的簡化了客戶端的操作。封裝格式,視頻編碼,音頻編碼方面,無一例外的使用了FLV + H.264 + AAC的組合。FLV是RTMP使用的封裝格式,H.264是當(dāng)今實際應(yīng)用中編碼效率最高的視頻編碼標(biāo)準(zhǔn),AAC則是當(dāng)今實際應(yīng)用中編碼效率最高的音頻編碼標(biāo)準(zhǔn)。視頻播放器方面,都使用了Flash播放器。
視頻直播,可以分為 采集,前處理,編碼,傳輸,解碼,渲染 這幾個環(huán)節(jié),下面分別說下:
采集,iOS是比較簡單的,Android則要做些機型適配工作,PC最麻煩各種奇葩攝像頭驅(qū)動,出了問題特別不好處理,建議放棄PC只支持手機主播,目前幾個新進(jìn)的直播平臺都是這樣的。
前處理,現(xiàn)在直播美顏已經(jīng)是標(biāo)配了,80%的主播沒有美顏根本沒法看。美顏算法需要用到GPU編程,需要懂圖像處理算法的人,沒有好的開源實現(xiàn),要自己參考論文去研究。難點不在于美顏效果,而在于GPU占用和美顏效果之間找平衡。GPU雖然性能好,但是也是有功耗的,GPU占用太高會導(dǎo)致手機發(fā)燙,而手機發(fā)燙會導(dǎo)致攝像頭采集掉幀,iPhone6尤其明顯,因為iPhone6的CPU和前置攝像頭很近。
前處理
在這個環(huán)節(jié)主要處理美顏、水印、模糊等效果。特別是美顏功能幾乎是直播的標(biāo)配功能,沒有美顏的直播主播們根本提不起興趣。我們見過太多case是因為沒有美顏功能被拋棄使用的。另外國家明確提出了,所有直播都必須打有水印并回放留存15天以上。所以,在選擇直播SDK時,沒有美顏和水印功能基本就可以選擇放棄了。
美顏實際上是通過算法去識別圖像中的皮膚部分,再對皮膚區(qū)域進(jìn)行色值調(diào)整。通常情況下人的膚色與周邊環(huán)境色調(diào)存在較大差異,通過顏色對比,找到皮膚的基本輪廓,進(jìn)一步進(jìn)行膚色檢查還可以確定人臉范圍。找到了皮膚的區(qū)域,可以進(jìn)行色值調(diào)整、添加白色圖層或調(diào)整透明度等來等來達(dá)到美白效果。美顏除了美白效果還需要磨皮功能,磨皮實際上就是用模糊濾鏡實現(xiàn)的。濾鏡有很多種,如高斯濾波,雙邊濾波,導(dǎo)向濾波,到底選擇什么樣的模糊濾鏡各家也有自己的喜好。
在美顏處理方面,最著名的GPUImage提供了豐富的效果,同時可以支持IOS和Android,還支持自己寫算法實現(xiàn)自己最理性的效果。GPUImage本事內(nèi)置了120多種常見濾鏡效果,添加濾鏡只需要簡單調(diào)用幾行代碼就可以了,比如大家可以試試使用GPUImageBilateralFiter的雙邊濾波濾鏡來處理基本的磨皮效果,想要實現(xiàn)更理想的效果還是要通過自定義算法去實現(xiàn)的,各家也都有自己一套算法。
編碼,肯定要采用硬編碼,軟編碼720p完全沒希望,勉強能編碼也會導(dǎo)致CPU過熱燙到攝像頭。硬編碼兼容性又是一個大坑,android上要有人去填。編碼要在分辨率,幀率,碼率,GOP等參數(shù)設(shè)計上找到最佳平衡點。
傳輸,自己做不現(xiàn)實,交給CDN服務(wù)商吧,也就是貴了點,相信有志于做直播平臺改變世界的你不差錢。假設(shè)2W PCU大約每月帶寬費用100萬左右,因為清晰流暢的720p要1.5mbps左右。CDN只提供了帶寬和服務(wù)器間傳輸,發(fā)送和接收端的網(wǎng)絡(luò)連接抖動緩沖還是要自己寫的。不想要卡頓,必然要加大緩沖,會導(dǎo)致延遲高,延遲高影響互動性,要做權(quán)衡。
解碼,也肯定要硬解碼,目前手機普遍支持硬解了,只是android上還是有兼容性大坑要填。
渲染,這個難點不在于繪制,而在于音畫同步,目前幾個直播做得都不好。
此外音頻還有幾個坑要填,比如降噪,音頻編碼器的選擇,各種藍(lán)牙耳機,各種播放模式的適配等,如果你想做主播和觀眾連線聊天,還有個回聲消除問題。
以上是媒體模塊,還有信令控制,登錄、鑒權(quán)、權(quán)限管理、狀態(tài)管理等等,各種應(yīng)用服務(wù),消息推送,聊天,禮物系統(tǒng),支付系統(tǒng),運營支持系統(tǒng),統(tǒng)計系統(tǒng)等。
后臺還有數(shù)據(jù)庫,緩存,分布式文件存儲,消息隊列,運維系統(tǒng)等。
現(xiàn)今移動直播技術(shù)上的挑戰(zhàn)要遠(yuǎn)遠(yuǎn)難于傳統(tǒng)設(shè)備或電腦直播,其完整的處理環(huán)節(jié)包括但不限于:音視頻采集、美顏/濾鏡/特效處理、編碼、封包、推流、轉(zhuǎn)碼、分發(fā)、解碼/渲染/播放等。
直播常見的問題包括
主播在不穩(wěn)定的網(wǎng)絡(luò)環(huán)境下如何穩(wěn)定推流?
偏遠(yuǎn)地區(qū)的觀眾如何高清流暢觀看直播?
直播卡頓時如何智能切換線路?
如何精確度量直播質(zhì)量指標(biāo)并實時調(diào)整?
移動設(shè)備上不同的芯片平臺如何高性能編碼和渲染視頻?
美顏等濾鏡特效處理怎么做?
如何實現(xiàn)播放秒開?
如何保障直播持續(xù)播放流暢不卡頓?
視頻、直播等基礎(chǔ)知識
什么是視頻?
首先我們需要理解一個最基本的概念:視頻。從感性的角度來看,視頻就是一部充滿趣味的影片,可以是電影,可以是短片,是一連貫的視覺沖擊力表現(xiàn)豐富的畫面和音頻。但從理性的角度來看,視頻是一種有結(jié)構(gòu)的數(shù)據(jù),用工程的語言解釋,我們可以把視頻剖析成如下結(jié)構(gòu):
內(nèi)容元素 ( Content )
圖像 ( Image )
音頻 ( Audio )
元信息 ( Metadata )
編碼格式 ( Codec )
Video : H.264,H.265, …
Audio : AAC, HE-AAC, …
容器封裝 (Container)
MP4,MOV,F(xiàn)LV,RM,RMVB,AVI,…
任何一個視頻 Video 文件,從結(jié)構(gòu)上講,都是這樣一種組成方式:
由圖像和音頻構(gòu)成最基本的內(nèi)容元素;
圖像經(jīng)過視頻編碼壓縮格式處理(通常是 H.264);
音頻經(jīng)過音頻編碼壓縮格式處理(例如 AAC);
注明相應(yīng)的元信息(Metadata);
最后經(jīng)過一遍容器(Container)封裝打包(例如 MP4),構(gòu)成一個完整的視頻文件。
如果覺得難以理解,可以想象成一瓶番茄醬。最外層的瓶子好比這個容器封裝(Container),瓶子上注明的原材料和加工廠地等信息好比元信息(Metadata),瓶蓋打開(解封裝)后,番茄醬本身好比經(jīng)過壓縮處理過后的編碼內(nèi)容,番茄和調(diào)料加工成番茄醬的過程就好比編碼(Codec),而原材料番茄和調(diào)料則好比最原本的內(nèi)容元素(Content)。
http://www.toutiao.com/i6278412629417394689/
直播入門級
- 推流、直播 和 點播分別是什么意思?
推流
主播將本地視頻源和音頻源推送到云服務(wù)器,在有些場景中也被稱為“RTMP發(fā)布”。
直播
即直接觀看主播實時推送過來的音視頻數(shù)據(jù),觀眾和視頻源之間的時間延遲一般不會太長。
點播
視頻源已經(jīng)事先存儲于服務(wù)器之上的音視頻文件,觀眾隨時可以觀看,類似優(yōu)酷土豆、愛奇藝和騰訊視頻。
影響視覺體驗的直播性能指標(biāo)
直播第一個性能指標(biāo)是延遲,延遲是數(shù)據(jù)從信息源發(fā)送到目的地所需的時間。
一個完整的直播過程,包括但不限于以下環(huán)節(jié):采集、處理、編碼、封包、推流、傳輸、轉(zhuǎn)碼、分發(fā)、拉流、解碼、播放。從推流到播放,再經(jīng)過中間轉(zhuǎn)發(fā)環(huán)節(jié),延遲越低,則用戶體驗越好。
第二個直播性能指標(biāo)卡頓,是指視頻播放過程中出現(xiàn)畫面滯幀,讓人們明顯感覺到“卡”。單位時間內(nèi)的播放卡頓次數(shù)統(tǒng)計稱之為卡頓率。
造成卡頓的因素有可能是推流端發(fā)送數(shù)據(jù)中斷,也有可能是公網(wǎng)傳輸擁塞或網(wǎng)絡(luò)抖動異常,也有可能是終端設(shè)備的解碼性能太差。卡頓頻次越少或沒有,則說明用戶體驗越好。
第三個直播性能指標(biāo)首屏耗時,指第一次點擊播放后,肉眼看到畫面所等待的時間。技術(shù)上指播放器解碼第一幀渲染顯示畫面所花的耗時。通常說的 “秒開”,指點擊播放后,一秒內(nèi)即可看到播放畫面。首屏打開越快,說明用戶體驗越好。
如上三個直播性能指標(biāo),分別對應(yīng)一個低延遲、高清流暢、極速秒開 的用戶體驗訴求。了解這三個性能指標(biāo),對優(yōu)化移動直播 APP 的用戶體驗至關(guān)重要。
移動直播場景其他優(yōu)化措施
一、怎么優(yōu)化打開速度,達(dá)到傳說中的 “秒開”?
大家可能會看到,市面上某些手機直播 APP 的打開速度非常快,一點就開。而某些手機直播 APP,點擊播放后要等好幾秒以后才能播放。是什么原因?qū)е氯绱说奶烊乐畡e呢?
大部分播放器都是拿到一個完成的 GOP 后才能解碼播放,基于 FFmpeg 移植的播放器甚至需要等待音畫時間戳同步后才能播放(如果一個直播里邊沒有音頻只有視頻相當(dāng)于要等待音頻超時后才能播放畫面)。
“秒開”可以從以下幾個方面考慮:
- 改寫播放器邏輯讓播放器拿到第一個關(guān)鍵幀后就給予顯示。
GOP 的第一幀通常都是關(guān)鍵幀,由于加載的數(shù)據(jù)較少,可以達(dá)到 “首幀秒開”。
如果直播服務(wù)器支持 GOP 緩存,意味著播放器在和服務(wù)器建立連接后可立即拿到數(shù)據(jù),從而省卻跨地域和跨運營商的回源傳輸時間。
GOP體現(xiàn)了關(guān)鍵幀的周期,也就是兩個關(guān)鍵幀之間的距離,即一個幀組的最大幀數(shù)。假設(shè)一個視頻的恒定幀率是 24fps(即1秒24幀圖像),關(guān)鍵幀周期為 2s,那么一個 GOP 就是 48 張圖像。一般而言,每一秒視頻至少需要使用一個關(guān)鍵幀。
增加關(guān)鍵幀個數(shù)可改善畫質(zhì)(GOP 通常為 FPS 的倍數(shù)),但是同時增加了帶寬和網(wǎng)絡(luò)負(fù)載。這意味著,客戶端播放器下載一個 GOP,畢竟該 GOP 存在一定的數(shù)據(jù)體積,如果播放端網(wǎng)絡(luò)不佳,有可能不是能夠快速在秒級以內(nèi)下載完該 GOP,進(jìn)而影響觀感體驗。
如果不能更改播放器行為邏輯為首幀秒開,直播服務(wù)器也可以做一些取巧處理,比如從緩存 GOP 改成緩存雙關(guān)鍵幀(減少圖像數(shù)量),這樣可以極大程度地減少播放器加載 GOP 要傳輸?shù)膬?nèi)容體積。
- 在 APP 業(yè)務(wù)邏輯層面方面優(yōu)化。
比如提前做好 DNS 解析(省卻幾十毫秒),和提前做好測速選線(擇取最優(yōu)線路)。經(jīng)過這樣的預(yù)處理后,在點擊播放按鈕時,將極大提高下載性能。
一方面,可以圍繞傳輸層面做性能優(yōu)化;另一方面,可以圍繞客戶播放行為做業(yè)務(wù)邏輯優(yōu)化。兩者可以有效的互為補充,作為秒開的優(yōu)化空間。
- 常見的直播協(xié)議有哪些?
目前常見的直播協(xié)議有三種:RTMP、 FLV 和 HLS。
RTMP
RTMP協(xié)議比較全能,既可以用來推送又可以用來直播,其核心理念是將大塊的視頻幀和音頻幀“剁碎”,然后以小數(shù)據(jù)包的形式在互聯(lián)網(wǎng)上進(jìn)行傳輸,而且支持加密,因此隱私性相對比較理想,但拆包組包的過程比較復(fù)雜,所以在海量并發(fā)時也容易出現(xiàn)一些不可預(yù)期的穩(wěn)定性問題。
FLV
FLV協(xié)議由Adobe公司主推,格式極其簡單,只是在大塊的視頻幀和音視頻頭部加入一些標(biāo)記頭信息,由于這種極致的簡潔,在延遲表現(xiàn)和大規(guī)模并發(fā)方面都很成熟。唯一的不足就是在手機瀏覽器上的支持非常有限,但是用作手機端APP直播協(xié)議卻異常合適。
HLS
蘋果推出的解決方案,將視頻分成5-10秒的視頻小分片,然后用m3u8索引表進(jìn)行管理,由于客戶端下載到的視頻都是5-10秒的完整數(shù)據(jù),故視頻的流暢性很好,但也同樣引入了很大的延遲(HLS的一般延遲在10-30s左右)。相比于FLV, HLS在iPhone和大部分android手機瀏覽器上的支持非常給力,所以常用于QQ和微信朋友圈的URL分享。

- 常見的點播協(xié)議有哪些?
目前常見的點播格式有三種:MP4、HLS和FLV。
MP4
非常經(jīng)典的文件格式,在移動終端和PC瀏覽器上的支持度都很好(在IOS和大部分Android設(shè)備上,都可以使用系統(tǒng)瀏覽器進(jìn)行播放,在PC上可以使用FLASH控件進(jìn)行播放)。但是MP4的視頻文件格式比較復(fù)雜,所以處理成本高,而且由于索引表復(fù)雜度高,導(dǎo)致時長稍大(比如半小時)的MP4文件在線播放時加載速度會很慢。
HLS
蘋果公司力推的標(biāo)準(zhǔn),在移動終端的瀏覽器上的支持度較好,但I(xiàn)E的支持情況依賴FLASH的二次開發(fā)工作(建議使用騰訊視頻云的FLASH播放器控件)。其精簡的m3u8的索引結(jié)構(gòu)可以規(guī)避MP4的索引慢問題,如果是用于點播,是非常不錯的選擇。
FLV
Adobe公司所推的標(biāo)準(zhǔn),目前直播平臺最常用的封裝格式,在PC端有FLASH的強力支持,但在移動終端只有APP實現(xiàn)播放器才有可能支持(或者使用本播放器),大部分手機端瀏覽器均不支持。目前騰訊視頻云的直播錄制,采用的就是FLV視頻格式。

- 常見的推流協(xié)議有哪些?
雖然RTMP在直播領(lǐng)域不是特別流行,但是在推流服務(wù),也就是主播->服務(wù)器這個方向上,RTMP則居于主導(dǎo)地位,目前國內(nèi)的視頻云服務(wù)都是以RTMP為主要推流協(xié)議。
5.如何實現(xiàn)畫質(zhì)和流量的平衡?
影響畫質(zhì)的主要因素是三個:分辨率、幀率和碼率。
分辨率:目前RTMP SDK支持的三種分辨率均為9:16的常規(guī)分辨率:360480,540960,720*1280。
幀率:FPS <=10 會明顯感覺到卡頓,但也并不是越高越好,一般推薦是20FPS即可達(dá)到很流暢的效果。
碼率:編碼器每秒編出的數(shù)據(jù)大小,單位是kbps,比如800kbps代表編碼器每秒產(chǎn)生800kb(或100KB)的數(shù)據(jù)。
好的畫質(zhì)是分辨率、幀率和碼率三者之間的平衡:
碼率不是越大越好
如果不做碼率大小上的限制,那么分辨率越高,畫質(zhì)越細(xì)膩;幀率越高,視頻也越流暢,但相應(yīng)的碼率也會很大,因為每秒鐘需要用更多的數(shù)據(jù)來承載較高的清晰度和流暢度。
幀率不要超過24
如果限定一個碼率,比如800kbps,那么幀率越高,編碼器就必須加大對單幀畫面的壓縮比,也就是通過降低畫質(zhì)來承載足夠多的幀數(shù)。如果視頻源來自攝像頭,24FPS已經(jīng)是肉眼極限,所以一般20幀的FPS就已經(jīng)可以達(dá)到很好的用戶體驗了。
有些玩過3D游戲的朋友可能會說,游戲的幀率越高越流暢。這里要注意一定不要混淆場景:游戲追求高幀率的目的是為了盡可能讓3D模型渲染出來的運動效果更加接近真實運動軌跡,所以幀率越高越好。 但對攝像頭而言,它要采集的目標(biāo)是真實世界的物體,真實世界本來就沒有刷新率的說法,所以這個理論不適用。
分辨率不盲目攀高
如果限定一個碼率,比如800kbps,那么分辨率越高就會讓編碼器越 “為難" ,可以想象,它必須拆東墻補西墻,通過減少色彩信息或者引入馬賽克這種“魚目混珠”的手段來承載足夠多的像素點。所以,同樣的是2G的一個電影文件,1080p畫質(zhì)的版本可能不如720p畫質(zhì)的版本看起來更清晰。
如果您之前沒有太多音視頻編碼的實戰(zhàn)經(jīng)驗,我們比較建議您使用demo里的設(shè)置參數(shù),我們在DEMO中提供了720p、540p 以及 360p 三種畫質(zhì)選擇以及相應(yīng)的配置。
- 如何降低延遲并減少畫面卡頓?
這里說的延遲是主播 -> 觀眾的時間延遲,而卡頓指的是出現(xiàn)500ms以上的播放停滯。
如果是在完美的網(wǎng)絡(luò)環(huán)境下,可以做到超低延遲下沒有卡頓,但現(xiàn)實是國內(nèi)的網(wǎng)絡(luò)環(huán)境并不完美,數(shù)據(jù)在經(jīng)過互聯(lián)網(wǎng)傳輸時必然會有抖動和丟包,從而對播放端的流暢播放產(chǎn)生影響。
直播間列表
創(chuàng)建房間(增)
當(dāng)一個主播開始直播前需要先創(chuàng)建一個直播間,這就等于是在直播間列表中增加一條新的數(shù)據(jù)。
關(guān)閉房間(刪)
當(dāng)一個直播結(jié)束后,App要通知后臺把當(dāng)前直播間狀態(tài)修改為“直播結(jié)束”,或者干脆將其從列表中刪除。
修改狀態(tài)(改)
當(dāng)有新的觀眾加入時,意味著某個直播間的觀眾數(shù)要+1;
當(dāng)有觀眾給主播點贊,意味著某個直播間的點贊數(shù)要+1;
當(dāng)有一條視頻流意外斷流時,會收到來自騰訊云的通知,意味著某個直播間的狀態(tài)要進(jìn)行修正;
當(dāng)監(jiān)管人員發(fā)現(xiàn)某一直播間內(nèi)容涉及違規(guī)行為時,需要對其禁播,意味著某個直播間的狀態(tài)要改為已禁播。
列表查詢(查)
每一個打開App的觀眾,都會到直播后臺查詢一下當(dāng)前的直播間列表,所以直播后臺要提供列表拉取的相關(guān)接口供 App 使用。并且,如果您的App裝機量不俗,那么這個接口要能承受一定的并發(fā)訪問壓力才行。
創(chuàng)建房間
終端 App 在發(fā)起直播前首先會通過一條協(xié)議向服務(wù)器請求創(chuàng)建一個直播間:
請求(App->Server)
最關(guān)鍵的信息就是自己的賬號ID了,同時,最好再附上直播的標(biāo)題、地理位置、直播封面URL等等信息,直播后臺會用這些信息創(chuàng)建一個直播間。
響應(yīng)(Server->App)
服務(wù)器的回包信息包含兩種情況:一情況是允許直播,則可以把推流URL等信息返回給App;另一種情況是給予拒絕并返回錯誤原因。