摘要:而我們喜歡的這些直播,他們用到的傳輸協(xié)議有一個通用名流媒體傳輸協(xié)議。要認(rèn)識流媒體協(xié)議,就離不開下面的三大系列名詞。
【前五篇】系列文章傳送門:
網(wǎng)絡(luò)協(xié)議 9 - TCP協(xié)議(下):聰明反被聰明誤
網(wǎng)絡(luò)協(xié)議 10 - Socket 編程(上):實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn)
網(wǎng)絡(luò)協(xié)議 11 - Socket 編程(下):眼見為實(shí)耳聽為虛
網(wǎng)絡(luò)協(xié)議 12 - HTTP 協(xié)議:常用而不簡單
網(wǎng)絡(luò)協(xié)議 13 - HTTPS 協(xié)議:加密路上無盡頭
????大家都會關(guān)注“在瀏覽器輸入一個地址,然后回車,會發(fā)生什么”這樣一個問題,但是有沒有想過這樣一個問題:主播開始直播,用戶打開客戶端觀看,這個過程發(fā)生了什么?
????隨著技術(shù)的發(fā)展,直播技術(shù)對人們生活的滲透日益加深。從最開始的游戲直播,到前幾天爆出來的教育直播,甚至現(xiàn)在都有直播招聘。
????而我們喜歡的這些直播,他們用到的傳輸協(xié)議有一個通用名-流媒體傳輸協(xié)議。
????要認(rèn)識流媒體協(xié)議,就離不開下面的三大系列名詞。
三大系列名詞系列一:AVI、MPEG、RMVB、MP4、MOV、FLV、WebM、WMV、ASF、MKV。是不是就 MP4 看著熟悉?
系列二:H.261、H.262、H.263、H.264、H.265。能認(rèn)出來幾個?別著急,重點(diǎn)關(guān)注 H.264。
系列三:MPEG-1、MPEG-2、MPEG-4、MPEG-7。是不是更懵逼了?
????在解釋上面的三大系列名詞之前,咱們先來了解下,視頻究竟是什么?
????博主記得小時(shí)候,經(jīng)常會玩一種叫動感畫冊的東西。一本很小的畫冊上,每一頁都畫了一幅圖,用手快速的翻過每一頁,就能看到一個很短的“動畫片”。
????沒錯,咱們看到的視頻,本質(zhì)上就是一連串快速播放的圖片。
????每一張圖片,我們稱為一幀。只要每秒鐘的數(shù)據(jù)足夠多,也就是播放速度足夠快,人眼就看不出是一張張獨(dú)立的圖片。對于人眼而言,這個播放臨界速度是每秒 30 幀,而這里的 30 也就是我們常說的幀率(FPS)。
????每一張圖片,都是由像素組成,而每個像素又是由 RGB 組成,每個 8 位,共 24 位。
????我們假設(shè)一個視頻中的所有圖片的像素都是 1024*768,可以大概估算下視頻的大小:
每秒鐘大小 = 30 幀 x 1024 x 768 x 24 = 566,231,010 Bits = 70,778,880 Bytes
????按我們上面的估算,一分鐘的視頻大小就是 4,,246,732,800 Bytes,這里已經(jīng)有 4 個 G 了。
????是不是和我們?nèi)粘=佑|到的視頻大小明顯不符?這是因?yàn)槲覀冊趥鬏數(shù)倪^程中,將視頻壓縮了。
????為什么要壓縮視頻?按我們上面的估算,一個一小時(shí)的視頻,就有 240G,這個數(shù)據(jù)量根本沒辦法存儲和傳輸。因此,人們利用編碼技術(shù),給視頻“瘦身”,用盡量少的 Bit 數(shù)保持視頻,同時(shí)要保證播放的時(shí)候,畫面仍然很清晰。實(shí)際上,編碼就是壓縮的過程。
視頻和圖片的壓縮特點(diǎn)我們之所以能夠?qū)σ曨l流中的圖片進(jìn)行壓縮,因?yàn)橐曨l和圖片有下列這些特點(diǎn):
空間冗余:圖像的相鄰像素之間有較強(qiáng)的相關(guān)性,一張圖片相鄰像素往往是漸變的,而不是突變的,沒必要每個像素都完整的保存,可以隔幾個保存一個,中間的用算法計(jì)算出來。
時(shí)間冗余:視頻序列的相鄰圖像之間內(nèi)容相似。一個視頻中連續(xù)出現(xiàn)的圖片也不是突變的,可以根據(jù)已有的圖片進(jìn)行預(yù)測和推斷。
視覺冗余:人的視覺系統(tǒng)對某些細(xì)節(jié)不敏感,因此不會注意到每一個細(xì)節(jié),可以允許丟失一些數(shù)據(jù)。
編碼冗余:不同像素值出現(xiàn)的概率不同,概率高的用的字節(jié)少,概率低的用的字節(jié)多,類似霍夫曼編碼的思路。
????從上面這些特點(diǎn)中可以看出,用于編碼的算法非常復(fù)雜,而且多種多樣。雖然算法多種,但編碼過程實(shí)際上是類似的,如下圖:
視頻編碼的兩大流派????視頻編碼的算法這么多,能不能形成一定的標(biāo)準(zhǔn)呢?當(dāng)然能,這里咱們就來認(rèn)識下視頻編碼的兩大流派。
流派一:ITU(International tELECOMMUNICATIONS Union)的 VCEG(Video Coding Experts Group),這個稱為國際電聯(lián)下的 VCEG。既然是電信,可想而知,他們最初是做視頻編碼,主要側(cè)重傳輸。我們上面的系列名詞二,就是這個組織制定的標(biāo)準(zhǔn)。
流派二:ISO(International Standards Organization)的 MPEG(Moving Picture Experts Group),這個是 ISO 旗下的 MPEG。本來是做視頻存儲的,就像咱們場面常說的 VCD 和 DVD。后來也慢慢側(cè)重視頻傳輸了。系列名詞三就是這個組織制定的標(biāo)準(zhǔn)。
后來,ITU-T(國際電信聯(lián)盟電信標(biāo)準(zhǔn)化部門)與 MPEG 聯(lián)合制定了 H.264/MPEG-4 AVC,這也是我們重點(diǎn)關(guān)注的。
直播數(shù)據(jù)傳輸????視頻經(jīng)過編碼之后,生動活潑的一幀幀圖像就變成了一串串讓人看不懂的二進(jìn)制。這個二進(jìn)制可以放在一個文件里,然后按照一定的格式保存起來,這里的保存格式,就是系列名詞一。
????編碼后的二進(jìn)制文件就可以通過某種網(wǎng)絡(luò)協(xié)議進(jìn)行封裝,放在互聯(lián)網(wǎng)上傳輸,這個時(shí)候就可以進(jìn)行網(wǎng)絡(luò)直播了。
????網(wǎng)絡(luò)協(xié)議將編碼好的視頻流,從主播端推送到服務(wù)器,在服務(wù)器上有個運(yùn)行了同樣協(xié)議的服務(wù)端來接收這些網(wǎng)絡(luò)數(shù)據(jù)包,從而得到里面的視頻流,這個過程稱為接流。
????服務(wù)端接到視頻流之后,可以滴視頻流進(jìn)行一定的處理,比如轉(zhuǎn)碼,也就是從一個編碼格式轉(zhuǎn)成另一種格式,這樣才能適應(yīng)各個觀眾使用的客戶端,保證他們都能看到直播。
????流處理完畢后,就可以等待觀眾的客戶端來請求這些視頻流。觀眾的客戶端請求視頻流的過程稱為拉流。
????如果有非常多的觀眾同時(shí)看一個視頻直播,都從一個服務(wù)器上拉流,壓力就非常大,因此需要一個視頻的分發(fā)網(wǎng)絡(luò),將視頻預(yù)先加載到就近的邊緣節(jié)點(diǎn),這樣大部分觀眾就能通過邊緣節(jié)點(diǎn)拉取視頻,降低服務(wù)器的壓力。
????當(dāng)觀眾將視頻流拉下來后,就需要進(jìn)行解碼,也就是通過上述過程的逆過程,將一串串看不懂的二進(jìn)制轉(zhuǎn)變成一幀幀生動的圖片,在客戶端播放出來。
????整個直播過程,可以用下圖來描述:
????接下來,我們依次來看一下每個過程:
編碼:將豐富多彩的圖片變成二進(jìn)制流????雖然我們說視頻是一張張圖片的序列,但如果每張圖片都完整,就太大了,因而會將視頻序列分成三種幀:
I幀,也稱關(guān)鍵幀。里面是完整的圖片,只需要本幀數(shù)據(jù),就可以完成解碼。
P幀,前向預(yù)測編碼幀。P 幀表示的是這一幀跟之前一個關(guān)鍵幀(或 P 幀)的差別,解碼時(shí)需要用之前緩存的畫面,疊加上和本幀定義的差別,生成最終畫面。
B幀,雙向預(yù)測內(nèi)插編碼幀。B 幀記錄的是本幀與前后幀的差別。要解碼 B 幀,不僅要取得之前的緩存畫面,還要解碼之后的畫面,通過前后畫面的數(shù)據(jù)與本幀數(shù)據(jù)的疊加,取得最終的畫面。
????可以看出,I 幀最完整,B 幀壓縮率最高,而壓縮后幀的序列,應(yīng)該是 IBBP 間隔出現(xiàn)。這就是通過時(shí)序進(jìn)行編碼。
????在一幀中,分成多個片,每個片中分成多個宏塊,每個宏塊分成多個子塊,這樣將一張大圖分解成一個個小塊,可以方便進(jìn)行空間上的編碼。如下圖:
????盡管時(shí)空非常立體的組成了一個序列,但總歸還是要壓縮成一個二進(jìn)制流。這個流是有結(jié)構(gòu)的,是一個個的網(wǎng)絡(luò)提取層單元(NALU,Network Abstraction Layer Unit)。變成這種格式就是為了傳輸,因?yàn)榫W(wǎng)絡(luò)上的傳輸,默認(rèn)的是一個個的包,因而這里也就分成了一個個的單元。
????如上圖,每個 NALU 首先是一個起始標(biāo)識符,用于標(biāo)識 NALU 之間的間隔。然后是 NALU 的頭,里面主要配置了 NALU 的類型。最后的 Payload 里面是 NALU 承載的數(shù)據(jù)。
????在 NALU 頭里面,主要的內(nèi)容是類型 NAL Type,其中:
0x07 表示 SPS,是序列參數(shù)集,包括一個圖像序列的所有信息,如圖像尺寸、視頻格式等。
0x08 表示 PPS,是圖像參數(shù)集,包括一個圖像的所有分片的所有相關(guān)信息,包括圖像類型、序列號等。
????在傳輸視頻流之前,剝削要傳輸者兩類參數(shù),不然就無法解碼。為了保證容錯性,每一個 I 幀之前,都會傳一遍這兩個參數(shù)集合。
????如果 NALU Header 里面的表示類型是 SPS 或 PPS,則 Payload 中就是真正的參數(shù)集的內(nèi)容。
????如果類型是幀,則 Payload 中是真正的視頻數(shù)據(jù)。當(dāng)然也是一幀幀保存的。前面說了,一幀的內(nèi)容還是挺多的,因而每一個 NALU 里面保存的是一片。對于每一片,到底是 I 幀,還是 P 幀,亦或是 B 幀,在片結(jié)構(gòu)里面也有 Header,這里面有個類型用來標(biāo)識幀的類型,然后是片的內(nèi)容。
????這樣,整個格式就出來了。一個視頻,可以拆分成一系列的幀,每一幀拆分成一系列的片,每一片都放在一個 NALU 里面,NALU 之間都是通過特殊的起始標(biāo)識符分隔,在每一個 I 幀的第一片前面,要插入多帶帶保存 SPS 和 PPS 的 NALU,最終形成一個長長的 NALU 序列。
推流:將數(shù)據(jù)流打包傳輸?shù)綄Χ?/b>????形成 NALU 序列后,還需要將這個二進(jìn)制的流打包成網(wǎng)絡(luò)包進(jìn)行發(fā)送。這里我們以 RTMP 協(xié)議為例,進(jìn)入第二個過程,推流。
????RTMP 是基于 TCP 的,因而也需要雙方建立一個 TCP 連接。在有 TCP 的連接的基礎(chǔ)上,還需要建立一個 RTMP 連接,也就是在程序里面,我們調(diào)用 RTMP 類庫的 Connet 函數(shù),顯式創(chuàng)建一個連接。
????RTMP 為什么需要建立一個多帶帶的連接呢?
????因?yàn)橥ㄐ烹p方需要商量一些事情,保證后續(xù)的傳輸能正常進(jìn)行。其實(shí)主要就是兩個事情:
確定版本號。如果客戶端、服務(wù)端的版本號不一致,就不能正常工作;
確定時(shí)間戳。視頻播放中,時(shí)間是很重要的一個元素,后面的數(shù)據(jù)流互通的時(shí)候,經(jīng)常要帶上時(shí)間戳的差值,因而一開始雙方就要知道對方的時(shí)間戳。
????溝通這些事情,需要發(fā)送 6 條消息:
客戶端發(fā)送 C0、C1、C2
服務(wù)端發(fā)送 S0、S1、S2
????首先,客戶端發(fā)送 C0 表示自己的版本號,不必等對方回復(fù),然后發(fā)送 C1 表示自己的時(shí)間戳。
????服務(wù)器只有在收到 C0 的時(shí)候,才會返回 S0,表明自己的版本號,如果版本不匹配,可以斷開連接。
????服務(wù)器發(fā)送完 S0 后,也不用等待,就直接發(fā)送自己的時(shí)間戳 S1。
????客戶端收到 S1 時(shí),發(fā)一個知道了最煩時(shí)間戳的 ACK C2。同理,服務(wù)器收到 C1 的時(shí)候,發(fā)一個知道了對方時(shí)間戳的 ACK S2。
????于是,握手完成。
????握手之后,雙方需要互相傳遞一些控制信息,例如 Chunk 塊的大小、窗口大小等。
????真正傳輸數(shù)據(jù)的時(shí)候,還是需要創(chuàng)建一個流 Stream,然后通過這個 Stream 來推流。
????推流的過程,就是講 NALU 放在 Message 里面發(fā)送,這個也稱為 RTMP Packet 包。其中,Message 的格式就像下圖所示:
????發(fā)送的時(shí)候,去掉 NALU 的起始標(biāo)識符。因?yàn)檫@部分對于 RTMP 協(xié)議來講沒有用。接下來,將 SPS 和 PPS 參數(shù)集封裝成一個 RTMP 包發(fā)送,然后發(fā)送一個個片的 NALU。
????RTMP 在收發(fā)數(shù)據(jù)的時(shí)候并不是以 Message 為單位的,而是把 Message 拆分成 Chunk 發(fā)送,而且必須在一個 Chunk 發(fā)送完成之后,才能開始發(fā)送下一個 Chunk。每個 Chunk 中都帶有 Message ID,表示屬于哪個 Message,接收端也會按照這個 ID 將 Chunk 組裝成 Message。
????前面連接的時(shí)候,設(shè)置 Chunk 塊大小就是指這個 Chunk。將大的消息變?yōu)樾〉膲K再發(fā)送,可以在低帶寬的情況下,減少網(wǎng)絡(luò)擁塞。
????下面用一個分塊的示例,來了解下 RTMP 是如何分塊的。
????假設(shè)一個視頻的消息長度是 307,而 Chunk 大小約定為 128,那么消息就會被拆分為 3 個 Chunk。
????第一個 Chunk 的 Type = 0,表示 Chunk 頭是完整的。頭里面 Timestamp 為 1000,總長度 Length 為 307,類型為 9,是個視頻,Stream ID 為 12346,正文部分承擔(dān) 128 個字節(jié)的 Data。
????第二個 Chunk 也要發(fā)送 128 個字節(jié),但是由于 Chunk 頭和第一個一樣,因此它的 Chunk Type = 3,表示頭和第一個 Chunk 一樣。
????第三個 Chunk 要發(fā)送的 Data 的長度為 51 個字節(jié),Chunk Type 還是用的 3。
????就這樣,數(shù)據(jù)源源不斷的到達(dá)流媒體服務(wù)器,整個過程就像下圖:
????這個時(shí)候,大量觀看直播的觀眾就可以通過 RTMP 協(xié)議從流媒體服務(wù)器上拉取。為了減輕服務(wù)器壓力,我們會使用分發(fā)網(wǎng)絡(luò)。
????分發(fā)網(wǎng)絡(luò)分為中心和邊緣兩層。邊緣層服務(wù)器部署在全國各地及橫跨各大運(yùn)營商里,和用戶距離很近。而中心層是流媒體服務(wù)集群,負(fù)責(zé)內(nèi)容的轉(zhuǎn)發(fā)。
????智能負(fù)載均衡系統(tǒng),根據(jù)用戶的地理位置信息,就近選擇邊緣服務(wù)器,為用戶提供推/拉流服務(wù)。中心層也負(fù)責(zé)轉(zhuǎn)碼服務(wù)。例如,將 RTMP 協(xié)議的碼流轉(zhuǎn)換成 HLS 碼流。
拉流:觀眾的客戶端看到直播視頻????接下來,我們再來看看觀眾通過 RTMP 拉流的過程。
????先讀到的是 H.264 的解碼參數(shù),例如 SPS 和 PPS,然后對收到的 NALU 組成一個個幀,進(jìn)行解碼,交給播放器播放,這樣客戶端就能看到直播視頻了。
小結(jié)視頻名詞比較多,編碼兩大流派達(dá)成了一致,都是通過時(shí)間、空間的各種算法來壓縮數(shù)據(jù);
壓縮好的數(shù)據(jù),為了傳輸而組成一系列的 NALU,按照幀和片依次排列;
排列好的 NALU,在網(wǎng)絡(luò)傳輸?shù)氖牵凑?RTMP 包的格式進(jìn)行包裝,RTMP 的包會拆分成 Chunk 進(jìn)行傳輸;
推送到流媒體集群的視頻流經(jīng)過轉(zhuǎn)碼和分發(fā),可以被客戶端通過 RTMP 協(xié)議拉取,然后組合成 NALU,解碼成視頻格式進(jìn)行播放。
參考:
RTMP 協(xié)議規(guī)范;
劉超 - 趣談網(wǎng)絡(luò)協(xié)議系列課;
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/72758.html
摘要:而我們喜歡的這些直播,他們用到的傳輸協(xié)議有一個通用名流媒體傳輸協(xié)議。要認(rèn)識流媒體協(xié)議,就離不開下面的三大系列名詞。 【前五篇】系列文章傳送門: 網(wǎng)絡(luò)協(xié)議 9 - TCP協(xié)議(下):聰明反被聰明誤 網(wǎng)絡(luò)協(xié)議 10 - Socket 編程(上):實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn) 網(wǎng)絡(luò)協(xié)議 11 - Socket 編程(下):眼見為實(shí)耳聽為虛 網(wǎng)絡(luò)協(xié)議 12 - HTTP 協(xié)議:常用而不簡單 網(wǎng)絡(luò)...
摘要:支持流媒體協(xié)議。流媒體數(shù)據(jù)量大,如果出現(xiàn)回源,壓力會比較大,所以往往采取主動推送的模式,將熱點(diǎn)數(shù)據(jù)主動推送到邊緣節(jié)點(diǎn)。除此之外,流媒體還有個關(guān)鍵的防盜鏈問題。在服務(wù)端,取出過期時(shí)間,和當(dāng)前節(jié)點(diǎn)時(shí)間進(jìn)行比較,確認(rèn)請求是否過期。 【前五篇】系列文章傳送門: 網(wǎng)絡(luò)協(xié)議 13 - HTTPS 協(xié)議:加密路上無盡頭 網(wǎng)絡(luò)協(xié)議 14 - 流媒體協(xié)議:要說愛你不容易 網(wǎng)絡(luò)協(xié)議 15 - P2P 協(xié)...
摘要:支持流媒體協(xié)議。流媒體數(shù)據(jù)量大,如果出現(xiàn)回源,壓力會比較大,所以往往采取主動推送的模式,將熱點(diǎn)數(shù)據(jù)主動推送到邊緣節(jié)點(diǎn)。除此之外,流媒體還有個關(guān)鍵的防盜鏈問題。在服務(wù)端,取出過期時(shí)間,和當(dāng)前節(jié)點(diǎn)時(shí)間進(jìn)行比較,確認(rèn)請求是否過期。 【前五篇】系列文章傳送門: 網(wǎng)絡(luò)協(xié)議 13 - HTTPS 協(xié)議:加密路上無盡頭 網(wǎng)絡(luò)協(xié)議 14 - 流媒體協(xié)議:要說愛你不容易 網(wǎng)絡(luò)協(xié)議 15 - P2P 協(xié)...
閱讀 3603·2021-11-24 10:25
閱讀 2508·2021-11-24 09:38
閱讀 1217·2021-09-08 10:41
閱讀 2903·2021-09-01 10:42
閱讀 2569·2021-07-25 21:37
閱讀 1981·2019-08-30 15:56
閱讀 914·2019-08-30 15:55
閱讀 2749·2019-08-30 15:54