流媒體協議是網絡對視頻的傳輸協議。緩存
基本概念服務器
視頻技術的名詞網絡
名詞系列一:AVI、MPEG、RMVB、MP四、MOV負載均衡
名詞系列二:H.26一、H.26二、H.26三、H.26四、H.265。重點是H.264編碼
名詞系列三:MPEG-一、MPEG-二、MPEG-四、MPEG-7。spa
視頻:一連串的圖片。3d
幀:一張圖片就是一幀。視頻
幀率:就是每秒由多少張圖片blog
像素:一個像素一個RGB,每一個8位。一張圖片由好多個像素組成。圖片
每秒種的視頻有多大?
30 幀 × 1024 × 768 × 24 = 566,231,040Bits = 70,778,880Bytes
每分鐘的視頻有多大?4,246,732,800Bytes,已是 4 個 G 了。
編碼:用盡可能少的Bit 保存視頻,是一個壓縮的過程。
利用視頻和圖片的一些特色進行壓縮:空間冗餘、時間冗餘、視覺冗餘、編碼冗餘。
本質上就是用更少的能量傳遞更多的信息。這和香農的信息論有些類似。
視頻編碼的兩大流派
ITU 的VCEG
ISO 的MPEG
ITU-T 與 MPEG 聯合制定的 H.264/MPEG-4 AVC
通過編碼以後,原來的一幀幀圖片轉爲二進制數據,將這些二進制數據放到文件裏,按照必定的格式保存起來,就是名詞系列一。
接流:服務器從主播客戶端的那裏接收視頻流
轉碼:從一個編碼格式轉爲另外一個編碼格式。
拉流:觀衆客戶端從服務器上拉取視頻流
解碼:觀衆的客戶端將二進制的視頻流,轉爲一幀幀圖片,組成視頻。
網絡直播,數據流的傳輸過程
咱們如今以一個網絡直播的例子,來講一下視頻是如何從主播的鏡頭上傳到網絡上,又是如何從網絡上到每一個粉絲的電腦屏幕上的。
一、主播的攝像頭將視頻採集下來,用視頻編碼協議編碼,轉成二進制的字節流,經過HTTP協議將它們打包發送出去。
二、服務器這端有一樣的視頻編碼協議,從TCP協議中解析出數據包,作一個緩存或者轉碼,就是從一個視頻編碼格式轉爲另外一中格式。由於客戶端使用的播放設備千差萬別。
三、客戶端這邊從服務端請求視頻流。這個過程很考驗服務器,服務器要同時爲巨大數量的客戶端服務。這時須要一個視頻分發的網絡,將視頻預先加載到裏客戶端較近的服務器上。
假如全國人都在觀看國慶閱兵,遼寧觀衆看到的視頻是從遼寧區域的服務器上拉取的視頻流。廣州的觀衆看的是廣州區域服務器上的視頻流。
四、觀衆的電腦或顯示器從網絡上拉取視頻流以後,仍是二進制的字節,要進行解碼才能看。
整個直播的過程像下圖這樣:
視頻分解、傳輸過程
編碼:視頻轉爲二進制的具體操做,爲減小視頻圖像的大小,將視頻序列分爲三種幀。
I 幀,關鍵幀,是完整圖片,須要本幀數據完成解碼。
P 幀,前向預測編碼幀,它表示的是一個差異,這一幀和前一個關鍵幀的差異。
B 幀,雙向預測內插編碼幀。表示本幀與先後幀的差異。要解碼B幀,須要前一幀的畫面,和後面一幀的畫面,經過先後畫面的數據和本幀的疊加,獲得最終的畫面。
在傳輸時,爲方便空間上的編碼,將每幀分爲好多片,每片分爲好多宏塊,每一個宏塊又分爲好多小塊。
分紅這些小塊是不能直接發出去的,否則就亂了,在客戶端想復原圖片就是不可能的了。那要如何保證這一點呢?
將一個視頻分紅好多幀,一個幀有好多片,還有宏塊,子塊。這些子塊構成一個序列,這時須要有一個能將這些子塊構成序列的辦法。保證它們能夠經過TCP協議傳輸到網絡另外一端,而且能復原成一個視頻。這個辦法就是包裝幀片的 網絡提取層單元(NALU)。
每一個NALU 由:起始標識符,NALU頭,和Payload組成的。
NALU頭裏面,主要是內容類型NAL Type。
SPS,是序列參數集,包括一個圖像序列的全部信息,如圖像尺寸,視頻格式等。
PPS,是圖像參數集,包括一個圖像的全部分片的全部相關信息,包括圖像類型、序列號等。
要從視頻流中解碼出視頻,這兩個參數是必須的。爲保證容錯性,每一個I 幀前面,都會傳一遍這兩個參數。
整個視頻的格式是這樣的。一個視頻能夠分紅好多幀,一個幀能夠分紅好多片,每一片都放到一個NALU 裏面,NALU 之間都是經過特殊的起始標識符分隔,在每一個I 幀的第一片前面,要插入單獨保存SPS 和PPS 的NALU,最終造成一個長長的NALU 序列。
推流 :把數據流打包傳輸到對端
如何將二進制的流打包成網絡包發送出去,這裏須要RTMP 協議。
RTMP 協議是一個實時信息傳輸協議,Adobe 公司提出,用來解決多媒體數據傳輸流的多路複用,和分包問題的協議。它創建在TCP協議之上,它主要保證兩個事情,一個是版本號,一個是時間戳。
RTMP協議也是須要相似於TCP 同樣的鏈接。就是在接收實時信息時先得了解一下發送和接收方的狀況。總不能兩眼一抹黑的上來就發消息吧。
要傳輸實時消息,要事先肯定些什麼呢?看看RTMP協議是怎麼作的,只須要發送六條消息,就搞定了。以下圖所示:
一、首先客戶端發送 C0,表示本身的版本號,不用等對方回覆,直接再發C1,代表本身的時間戳。
二、服務端收到C0 後,才能返回S0,代表本身的版本號,若是不匹配就斷開鏈接。發送完S0 後,服務端繼續發S1,代表本身的時間戳。
三、客戶端收到S1 後,回送給服務端一個ack,代表本身接收到服務端的時間戳了。
四、一樣,服務端收到C1 後,回送給客戶端一個ack,代表本身收到客戶端的時間戳了。
到此,握手完成!
握手完成只是創建好鏈接,雙方還須要傳遞一些控制信息,例如Chunk 塊的大小,窗口大小等。
真正傳輸數據時還要建立一個Stream,而後經過這個Stream 來推流(publish),就是將NALU 放在Message裏發送,這個Message也稱爲RTMP Packet 包。Message 的格式像下面這樣。
將大的消息變爲小的塊再發送,能夠在低帶寬的狀況下,減小網絡擁塞。
整個數據流的傳輸過程就像下面這樣:
下面是觀衆客戶端的拉流過程:
分發網絡
下面說一下服務端的分發網絡,它們解決了大量觀衆給服務器形成壓力的問題。
分發網絡分爲中心和邊緣兩層。邊緣層服務器部署在全國各地,以及橫跨各大運營商裏,和用戶距離很近。中心是流媒體服務集羣,負責內容的轉發。
智能負載均衡系統,根據用戶的地理位置信息,就近選擇邊緣服務器,爲用戶提供推/ 拉流服務。
這套機制還會涉及DNS、HTTPDNS、CDN 等等技術。