天天看點

crtmpserver系列(一):流媒體概述

流媒體

概述

所謂流媒體按照字面意思了解就是像流一樣的媒體,看起來像是廢話。流媒展現在司空見慣,是以一般人大概不會有疑問。事實上在流媒體還沒有出現的時候,基本上通過網絡播放電影就不太現實。通過網絡播放電影的時候必須先将整個檔案下載下傳到電腦上然後才能播放,是以一般都要緩沖很久,這也是為什麼最開始迅雷等下載下傳工具流行的原因,其實大多數都是用來下電影了。

流媒體最大的特點即是能夠做到邊下載下傳邊播放,而不需要預先将整個檔案全部下載下傳完成之後才能播放,這樣極大的改善了使用者體驗,也提高了實時性,使得網絡直播成為可能。

那麼流媒體是如何做到邊下載下傳邊播放的呢,我們要了解流媒體系統的組成。

流媒體系統的組成

一個完整的流媒體系統由這些部分組成,信号采集,編碼,傳輸,解碼,輸出。

信号采集:我們所說的流媒體系統都是要在計算機系統上面進行處理的,而系統中最主要的元素是音頻和視訊,從實體上面來說音頻實際上是一種通過實體震動形成的機械波,音頻采集即是将這種實體波轉換為電信号進而轉換成二進制的音頻資料,一般采集得到的原始音頻資料是PCM資料。視訊是什麼,視訊實際上是順序呈現出來的一幅幅連續的靜止圖像,是以視訊實際上是由一幅幅靜止的圖像組成,視訊的采集就是連續不斷的采集這些靜止的圖像的過程,這些一幅幅的圖像一般被稱為幀。那麼這些被稱為幀的靜止圖像又是怎麼被采集的呢,實際上圖像的表現形式并不是像聲音一樣的波,國中的實體我們就學過成像,我們之是以能夠看到圖像,是因為照射在物體上的光反射到我們的眼睛進入視網膜,傳導到視神經最後被我們大腦感覺。是以圖像的采集是對光信号的采集與轉換,将光信号轉換為二進制的圖像幀的過程,一般我們得到的原始圖像資料格式是YUV格式。

編碼:什麼是編碼,為什麼要編碼。假設我們的網絡容量是無限的,傳輸速度也是無限大的,這當然是不需要編碼的。而實際上并不是,我們采集到的原始音視訊資料量是很大的,是以我們需要想辦法,将采集到的原始的音視訊二進制資料量盡量變小,友善在網絡上進行傳輸,同時又需要在還原(解碼)的時候盡量接近原始音視訊(損失,編碼也有分為有損和無損)。我們有時候稱編碼也叫壓縮編碼,其實壓縮這個概念類似我們平時的壓縮檔案的原理一樣,舉個簡單的例子,例如有一個文本檔案其内容是00000000000000000000000000000000000000000000000000 這麼一串字元串,實際就是50個0字元,我們完全可以用最簡單的描述來壓縮,例如我們壓縮之後檔案内容變成50’0’表示這裡有50個0字元。在還原的時候這裡直接用50個0字元填充即可,這樣是不是會節約大量的空間呢,如果不是50個0而是一萬個0字元呢,這樣經過壓縮之後的壓縮比會更大,也就是說重複的備援資料越多,壓縮效率越高。當然實際的壓縮算法肯定沒這麼簡單,說這麼個簡單的例子隻是為了說明原理而已。視訊的編碼算法有很多種,而且要複雜很多,每一種算法的運作效率,壓縮比,損失率都不一樣。而原理都是一樣的,在最常見的概念中,有幀内壓縮和幀間壓縮。

什麼是幀内壓縮呢,假設一副圖像的背景是純紅色,前面站個人(拍證件照的場景)。在編碼的時候一副圖像被分成很多小塊(宏塊),這樣由于背景中會有很多相鄰的小塊都是純紅色,很多純紅色的小塊都可以根據其周圍的小塊推斷出來,而不需要單獨編碼,這就是幀内壓縮,這種壓縮是在一個幀内部進行的,跟其前後的圖像沒有關系。

那麼幀間壓縮又是什麼,如果一個視訊中相鄰的2副圖像,背景都是純紅色,背景中有一個球在圖像1中的位置是A點。在圖像2中的位置是B點。實際上如果把圖像1和圖像2疊在一起會發現他們除了球的位置不一樣之外,其他的部分是一樣的,也就是說這兩幅相鄰的圖像有很大一部分是相同的。在編碼第2副圖像的時候完全可以隻編碼其與上一副圖像的不同部分。如果圖像1我們需要完全編碼,圖像1被稱為關鍵幀(一般稱為I幀),而圖像2在還原的時候需要參考圖像1,是以稱為參考幀(一般稱為P幀)。如果沒有關鍵幀,那麼參考幀是無法還原的。當然在編碼的時候,一幀不僅可以參考其上一幀,還可以參考其下一幀(雙向預測的幀間壓縮),例如一個球從左滾到右,這種運動是可以做預測的。這種目前幀的編碼參考其相鄰圖像的算法就是幀間壓縮算法。

傳輸:經過采集,編碼我們現在已經獲得了音視訊資料幀,但是一般觀看視訊的一定不是在采集編碼的現場,否則就不需要傳輸了,傳輸的過程就是将編碼後的音視訊資料通過網絡(網際網路,或者有線電視網等,我們隻讨論網際網路)傳輸到希望觀看的觀衆那裡。資料從一個地方傳遞到另一個地方這個過程就是傳輸。傳輸過程中最重要的當然是流媒體協定了,為什麼還需要流媒體協定?在流媒體播放的時候會有一些播放邏輯,例如,播放,暫停,跳轉,停止,快進,快退。另外在編碼之後的資料從一端傳遞到另一端,另一端需要将編碼之後的資料還原成編碼之前的原始資料才能播放。如何還原?必須得知道之前編碼是使用什麼算法編碼的,在還原的時候才能采用相應的解碼算法進行還原。那麼編碼的時候使用的是什麼算法,這個也需要從一端通知到另一端,這個資訊也是在流媒體傳輸協定中會有的。除此之外還會有其他的一些邏輯資訊,例如視訊的幀率,關鍵幀的間隔(GOP Size)等。總結為一句話,編碼過後的音視訊資料通過網絡從一端傳遞到另一端,在另一端對資料還原的時候需要一些資訊,并且需要支援一些播放場景的邏輯,這些都需要在流媒體協定中進行描述。目前最流行的流媒體協定,Adobe公司的RTMP,RTSP,微軟的MMS等。

解碼:經過編碼壓縮的資料必須還原成編碼之前的原始資料才能播放顯示,這個還原過程就是解碼的過程。

輸出:輸出的過程就是播放出來的過程,與采集的時候一樣,實際上這是将采集的原始音視訊資料經過模數轉換轉換成實體信号,視訊信号通過顯示器顯示出來,音頻信号通過音箱放出來。

媒體檔案封裝

我們之前讨論的是媒體的流式播放,其實這個流式主要是指傳輸是流動的,而且視訊幀可以邊傳輸,邊解碼播放。如果我們希望将播放的内容儲存到磁盤上,就必須要有一種檔案格式來組織這些資料,以一定的結構來儲存這些音視訊資料。為什麼不直接将網絡傳輸過來的内容直接寫到一個檔案中儲存呢,如果直接将所有傳輸過來的資料不加任何結構組織直接儲存的話,那麼在播放的時候如何播放?如何知道這些二進制資料哪些是音頻哪些是視訊,如何知道每一幀音視訊資料在檔案中的邊界,如何知道該音視訊的内容是通過什麼編碼算法編碼的,如何知道播放一幀資料之後再隔多長時間播放下一幀資料,如果像有的電影檔案需要多種字幕又如何組織。是以這就必須要有一種檔案格式能夠組織這些音視訊資料并且附加這些播放必須的資訊在檔案中。這就是媒體檔案的封裝。現存有很多種媒體檔案,有的是某個公司的專利,有的是國際标準,例如MP4,MP3,AVI,RMVB等等等等。是以如果要儲存這些流媒體資料到檔案中,則必須通過一定的檔案封裝格式将這些音視訊資料儲存在具有一定格式的媒體檔案中。

傳輸協定

目前使用的最多的流媒體傳輸協定當然是RTMP和RTSP了。微軟的MMS基本在工作中接觸的不多,特别是目前比較火爆的網際網路直播。還有一個需要特别提到的HTML5出來之後,很多以前通過flash用戶端承載RTMP協定的播放方式被以HLS替換了。但是實時性要求比較高的直播還是需要通過RTMP或者RTSP協定。HLS嚴格來說,其實我感覺都不能叫流媒體協定,HLS實際上基本可以認為是一個TS檔案的播放清單,沒有流媒體協定中的那些邏輯功能,播放,暫停,停止。應該說HLS僅僅是特定情況下出來的,主要是針對跨平台的浏覽器進行直播。我們所看到的HLS大部分都是通過移動裝置,PC機器上的浏覽器來播放的。

需要指出的是,在與蘋果的HLS争奪市場的過程中,同時出現了多種類似的技術,都是用的HTTP協定,一般我們稱為HTTP漸進式下載下傳。例如微軟的Live Smooth Streaming 中文名稱為直播平滑流,這種技術需要微軟IIS7及以上版本的web伺服器和Silverlight用戶端支援。另外一種是開源的技術好像并不是某個公司出品,叫Http Pseudo-Streaming 中文名是僞流。目前隻看到一個基于Apache伺服器的插件H264 Streaming Module for Apache,用戶端貌似也是使用Flash Player。還有一種叫HTTP Dynamic Streaming 中文稱做HTTP動态流,是Adobe公司的技術方案,其服務端需要Flash Media Server支援,用戶端則是Flash Player。其實作在的Flash Media Server 也已經支援HLS了。蘋果的HLS就不說了現在很多伺服器以及開源代碼都支援HLS,用戶端呢隻要支援HTML5的浏覽器基本也都支援HLS,現在的HLS已經是主流。最後要說的是新出現的一種技術标準,MPEG-DASH目的為了統一這些技術方案,還在标準化中,如果真的标準化,也有可能取代HLS,畢竟HLS還沒有稱為正式标準,隻是蘋果公司送出了個草案。

RTMP協定的發展得益于flash播放器的廣泛傳播,而RTSP協定則得益于其協定的開源。本系列要講解的crtmpserver就是基于RTMP協定的開源流媒體伺服器,開發語言為C++。等同的産品還有Red5 語言為Java也是開源。另外一個比較有影響力是wowza屬于閉源産品。此外RTMPDump項目是用的比較多的RTMP用戶端開源項目,其中的librtmp庫使用的很廣泛,C語言編寫。另外OpenRTMFP是基于p2p技術的RTMP。