1. 程式人生 > >音視訊採集封裝到直播推流原理

音視訊採集封裝到直播推流原理

上次好早之前也寫過一篇,隨著工作的深入對這塊知識又鞏固了一遍,算是一個重寫和擴充套件版
舊的總結跳轉,那麼有啥不同呢?
1. 介紹協議的優缺點以及怎麼選擇
2. 會介紹壓縮編碼的原理
3. 測試關注的質量指標

那麼基本框架其實是不變的,都是採集–壓縮編碼–封裝–推流–分發–流媒體協議觀看

把架構圖重新畫了一遍,比上次精細了許多,重寫版就是基於這個框架的深入介紹

這裡寫圖片描述

採集

我們知道計算機都是隻認識二進位制的,所以對於視訊採集,其實就是把實際看到的東西轉為二進位制的格式,採集就是轉為二進位制流的過程。

這部分其實實際測試中關注的是比較少的,因為客戶端針對的都是採集好的原始視訊或音訊流做處理,這裡要知道採集成的格式視訊是YUV,音訊是PCM。

YUV來說,其中“Y”表示明亮度(Luminance或Luma),也就是灰階值;而“U”和“V” 表示的則是色度(Chrominance或Chroma),作用是描述影像色彩及飽和度,用於指定畫素的顏色。

處理

處理的過程主要是美顏和濾鏡了,重點說說美顏,美顏有兩步,一個是磨皮,一個是美白,要想正確美顏,所以還需要加上人臉識別技術和面板識別技術。

這裡要說說題外話,美顏在壓縮編碼前處理可以說是最自然的,缺點也有,不能修改。所以也有一種是通過播放器渲染”美顏”。效果嘛,呵呵。可惜的是我們專案美顏濾鏡就是這樣做的,個人還是不敢苟同的,這樣做缺點非常明顯,畫質不忍直視,還要十分拖累幀數,優點嘛,修改和實現非常簡單,成本也低

在針對原始流的處理,除了濾鏡美顏外,還可以自定義打logo,修改畫面內容。

壓縮編碼

首先,要知道的是,一個視訊是由一個個畫面組成的,多個畫面連續運動便構成了動畫,也就是視訊,一個個畫面我們稱為幀(筆者想起小時候玩的小玩具,一個小本本,裡面有很多相似的圖畫,然後像翻書那樣快速翻過,形成了動畫)。
原始視訊流是很大的,需要壓縮,那麼最簡單的辦法就是”推測”,根據前一幀推測後一幀後者幾幀,那麼就不用儲存這麼多資料了。
所以壓縮編碼就是把採集到的資料分成有關聯的一幀幀,那麼N個幀合在一起就是一個組,我們叫GOP(group of picture)。這個組裡面的幀,我們劃分成I/B/P幀,我們把I幀叫做關鍵幀,B/P幀叫做參考幀,其中B叫雙向參考幀,P叫向前參考幀,沒有I幀B/P幀也沒法播放,因為B/P幀是參考I幀的變化而成的。

壓縮編碼到底怎麼壓縮的?

壓縮編碼的作用是去掉冗餘資訊,主要有以下幾個方向,當然冗餘不止這幾個哈:

空間冗餘

時間冗餘

視覺冗餘

編碼冗餘

空間冗餘:

比如下面這幅筆者正在用的桌布,可以發現有的顏色區域非常類似甚至一樣,這樣這些重複的區域就是空間冗餘了,空間冗餘是屬於幀內壓縮的,是指在一個影象內的壓縮。

這裡寫圖片描述

時間冗餘:

根據時間關係產生的冗餘,根據前一幀和變化量可以推測出後一幀的冗餘,比如下面的圖(網上搜的一幅圖),動作是比較規律的,不同的只是變化(可以想成開發中動畫的定義,先定義一個影象,然後呼叫api讓它旋轉、放大、移動和透明),那麼這就是時間冗餘。

這裡寫圖片描述

視覺冗餘:

這個百度百科挺詳細的,我摘取一段下來:

在多媒體技術的應用領域中,人的眼睛是影象資訊的接收端。視覺冗餘是相對於人眼的視覺特性而言的,人類的視覺系統並不能對影象畫面的任何變化都能感覺到,通常情況下具有以下特點:
對亮度的變化敏感,對色度的變化相對不敏感。
對靜止影象敏感,對運動影象相對不敏感。
對影象的水平線條和豎直線條敏感,對斜線相對不敏感。
對整體結構敏感,對內部細節相對不敏感。
對低頻訊號敏感,對高頻訊號相對不敏感(如:對邊沿或者突變附近的細節不敏感)。
……
因此,包含在色度訊號、運動影象、影象高頻訊號中的一些資料,相對於人眼而言,並不能對增加影象的清晰度作出貢獻,被人眼視為多餘的,這就是視覺冗餘。

也就是說視覺冗餘就是排除掉人類視覺不敏感的地方,達到壓縮的目的。

但是,你不排除有的人就是對這些細節很在意啊,比如每次測試不出來的東西,一發到外網,總有人反饋,一看,顏色不對啦,多了一根線啦,真是折磨人呢!

編碼冗餘:

因為不同編碼方式或者不同的圖片壓縮後產生的二進位制長度是不一致的,指在編碼過程中每個畫素使用的位元位大於實際的資訊熵(其實就是計劃和實際不匹配產生的餘量咯),那麼就產生了冗餘,這和影象和編碼方式有區別的,編碼冗餘也叫資訊熵冗餘。

關係?

還是有關係的,GOP分組,I幀是關鍵幀,是空間冗餘,B/P幀是參考幀,是時間冗餘,然後繼續編碼,去除視覺冗餘和編碼冗餘等,最後這一過程就完成了。

常用編碼格式

這裡需要對比一下常用的編碼標準了,深入的原理不會涉及(不是演算法層了,接觸太多反而沒必要),但是你要知道優缺點呢!

\ h.264 h.265 vp8/9
優點 用的最多,編碼最快,支援最好 畫質相同位元速率最低,省空間 google發起的,免費的
缺點 沒有h.265省空間 專利很貴,對效能要求較高,相容沒有264好 中規中矩,用的人不多
\ aac mp3
優點 音質好、儲存小,已經越來越多地方使用了 流傳廣
缺點 價效比低,但是免費音樂傳播還是靠mp3啊

那麼綜上,目前專案的編碼格式定位最主流的h.264 + aac的編碼方案,主要是為了:

  • 移動端要考慮相容性,硬解一般都支援h.264
  • 要考慮效能,h.265資源消耗比較大,而且為了體驗良好需要快速編碼並儲存資源

封裝

然後到封裝了,封裝其實就是打包啊,壓縮編碼後h.264和aac,要怎麼結合在一起呢,就是封裝呀,舉個例子,一個醬油瓶,裡面裝的醬油,醬油就是壓縮編碼後的成品,裝到瓶子裡就是封裝,然後打上”cloudhuan牌醬油”,就是打上meatadata資訊。封裝除了是包裝外,還可以打上時間戳,避免音畫不同步呢。

推流

推流協議的話其實就兩個,基於tcp的rtmp和udp的webRTC和私有協議

rtmp是adobe的私有協議,已經不再維護,推流需要封裝成flv。

優點:主流,cdn都支援,用的最多,實現簡單,創業公司用這個成本最低

缺點:基於tcp的,tcp有超時重傳的機制,意味著弱網下,穩定性可能會出問題

webRTC視訊會議用得比較多,google出品(對,又是google,一個偉大的公司)

優點:開源的,基於udp意味著直播的時候可以對弱網指定一些丟包策略。

缺點:cdn支援不良

基於udp的私有協議,大公司一般會自己實現了,缺點同樣是cdn支援不好,然後要有一定技術才能去開發。

接收流媒體

流媒體協議用的最多了就三個,一般都是支援的:

rtmp和http-flv:

都是flv的格式,延遲都是2~4s,實時性都差不多,卻別在於http是儲存flv在客戶端的,而rtmp是儲存在伺服器端的,都不支援web播放

hls:

唯一一個支援h5播放的流媒體協議,延遲4~10s,格式是ts + m3u8,觀看的時候先把一組.ts視訊下載,然後通過m3u8的索引去觀看,因為要先下載一段(N個ts檔案+一個m3u8檔案),所以延遲和段數有關,實時性不會太好。
這裡寫圖片描述

總結

最後複習一下

原理流程:
採集–>處理–>壓縮編碼–>封裝–>推流–>分發–>流媒體觀看

h264和h265比較、rtmp、http-flv、hls的異同點、幀內壓縮和幀間壓縮以及GOP的概念