1. 程式人生 > >視訊直播技術詳解之編碼和封裝

視訊直播技術詳解之編碼和封裝

七牛雲於6月底釋出了一個針對視訊直播的實時流網路LiveNet和完整的直播雲解決方案,很多開發者對這個網路和解決方案的細節和使用場景非常感興趣。

結合該實時流網路LiveNet和直播雲解決方案的實踐,我們將用七篇文章,更系統化地介紹當下大熱的視訊直播各環節的關鍵技術,幫助視訊直播創業者們更全面、深入地瞭解視訊直播技術,更好地技術選型。

本系列文章大綱如下:

(一)採集 
(二)處理 
(三)編碼和封裝 
(四)推流和傳輸 
(五)現代播放器原理 
(六)延遲優化 
(七)SDK效能測試模型

在上一期的處理篇中,我們介紹了講解常見視訊處理功能如美顏、視訊水印、濾鏡、連麥等。 本篇是《解密視訊直播技術》系列之三:編碼和封裝。視訊編碼是本系列一個重要的部分,如果把整個流媒體比喻成一個物流系統,那麼編解碼就是其中配貨和裝貨的過程,這個過程非常重要,它的速度和壓縮比對物流系統的意義非常大,影響物流系統的整體速度和成本。同樣,對流媒體傳輸來說,編碼也非常重要,它的編碼效能、編碼速度和編碼壓縮比會直接影響整個流媒體傳輸的使用者體驗和傳輸成本。

視訊編碼的意義

  • 原始視訊資料儲存空間大,一個1080P的7s視訊需要817MB
  • 原始視訊資料傳輸佔用頻寬大,10Mbps的頻寬傳輸上述7s視訊需要11分鐘

而經過H.264編碼壓縮之後,視訊大小隻有708k,10Mbps的頻寬僅僅需要500ms,可以滿足實時傳輸的需求,所以從視訊採集感測器採集來的原始視訊勢必要經過視訊編碼。

基本原理

那為什麼巨大的原始視訊可以編碼成很小的視訊呢?這其中的技術是什麼呢?核心思想就是去除冗餘資訊:

  • 空間冗餘:影象相鄰畫素之間有較強的相關性
  • 時間冗餘:視訊序列的相鄰影象之間內容相似
  • 編碼冗餘:不同畫素值出現的概率不同
  • 視覺冗餘:人的視覺系統對某些細節不敏感
  • 知識冗餘:規律性的結構可由先驗知識和背景知識得到

視訊本質上講是一系列圖片連續快速的播放,最簡單的壓縮方式就是對每一幀圖片進行壓縮,例如比較古老的MJPEG編碼就是這種編碼方式,這種編碼方式只有幀內編碼,利用空間上的取樣預測來編碼。形象的比喻就是把每幀都作為一張圖片,採用JPEG的編碼格式對圖片進行壓縮,這種編碼只考慮了一張圖片內的冗餘資訊壓縮,如圖1,綠色的部分就是當前待編碼的區域,灰色就是尚未編碼的區域,綠色區域可以根據已經編碼的部分進行預測(綠色的左邊,下邊,左下等)。

圖片描述

圖 1

但是幀和幀之間因為時間的相關性,後續開發出了一些比較高階的編碼器可以採用幀間編碼,簡單點說就是通過搜尋演算法選定了幀上的某些區域,然後通過計算當前幀和前後參考幀的向量差進行編碼的一種形式,通過下面兩個圖2連續幀我們可以看到,滑雪的同學是向前位移的,但實際上是雪景在向後位移,P幀通過參考幀(I或其他P幀)就可以進行編碼了,編碼之後的大小非常小,壓縮比非常高。

圖片描述

圖 2

可能有同學對這兩張圖片怎麼來的感興趣,這裡用了FFmpeg的兩行命令來實現,具體FFmpeg的更多內容請看後續章節:

  • 第一行生成帶有移動向量的視訊
  • 第二行把每一幀都輸出成圖片
ffmpeg  -flags2 +export_mvs -i tutu.mp4 -vf codecview=mv=pf+bf+bb tutudebug2.mp4  ffmpeg -i tutudebug2.mp4 'tutunormal-d.bmp'

除了空間冗餘和時間冗餘的壓縮,主要還有編碼壓縮和視覺壓縮,下面是一個編碼器主要的流程圖:

圖片描述
​ 

圖 3

圖片描述

圖 4

圖3、圖4兩個流程,圖3是幀內編碼,圖4是幀間編碼,從圖上看到的主要區別就是第一步不相同,其實這兩個流程也是結合在一起的,我們通常說的I幀和P幀就是分別採用了幀內編碼和幀間編碼。

編碼器的選擇

前面梳理了一下編碼器的原理和基本流程,編碼器經歷了數十年的發展,已經從開始的只支援幀內編碼演進到現如今的H.265和VP9為代表的新一代編碼器,就目前一些常見的編碼器進行分析,帶大家探索一下編碼器的世界。

1) H.264簡介

H.264/AVC專案意圖建立一種視訊標準。與舊標準相比,它能夠在更低頻寬下提供優質視訊(換言之,只有MPEG-2,H.263或MPEG-4第2部分的一半頻寬或更少),也不增加太多設計複雜度使得無法實現或實現成本過高。另一目的是提供足夠的靈活性以在各種應用、網路及系統中使用,包括高、低頻寬,高、低視訊解析度,廣播,DVD儲存,RTP/IP網路,以及ITU-T多媒體電話系統。

H.264/AVC包含了一系列新的特徵,使得它比起以前的編解碼器不但能夠更有效的進行編碼,還能在各種網路環境下的應用中使用。這樣的技術基礎讓H.264成為包括YouTube在內的線上視訊公司採用它作為主要的編解碼器,但是使用它並不是一件很輕鬆的事情,理論上講使用H.264需要交納不菲的專利費用。

專利許可

和MPEG-2第一部分、第二部分,MPEG-4第二部分一樣,使用H.264/AVC的產品製造商和服務提供商需要向他們的產品所使用的專利的持有者支付專利許可費用。這些專利許可的主要來源是一家稱為MPEG-LA LLC的私有組織,該組織和MPEG標準化組織沒有任何關係,但是該組織也管理著MPEG-2第一部分系統、第二部分視訊、MPEG-4第二部分視訊和其它一些技術的專利許可。

其他的專利許可則需要向另一家稱為VIA Licensing的私有組織申請,這家公司另外也管理偏向音訊壓縮的標準如MPEG-2 AAC及MPEG-4 Audio的專利許可。

H.264的開源實現

  • OpenH264
  • x264

OpenH264是思科實現的開源H.264編碼,雖然H.264需要交納不菲的專利費用,但是專利費有一個年度上限,思科把OpenH264實現的年度專利費交滿後,OpenH264事實上就可以免費自由地使用了。

x264是一個採用GPL授權的視訊編碼自由軟體。x264的主要功能在於進行H.264/MPEG-4 AVC的視訊編碼,而不是作為解碼器(decoder)之用。

除去費用問題比較來看:

  • OpenH264CPU的佔用相對x264低很多
  • OpenH264只支援baseline profile,x264支援更多profile

2) HEVC/H.265簡介

高效率視訊編碼(High Efficiency Video Coding,簡稱HEVC)是一種視訊壓縮標準,被視為是ITU-T H.264/MPEG-4 AVC標準的繼任者。2004年開始由ISO/IEC Moving Picture Experts Group(MPEG)和ITU-T Video Coding Experts Group(VCEG)作為ISO/IEC 23008-2 MPEG-H Part 2或稱作ITU-T H.265開始制定。第一版的HEVC/H.265視訊壓縮標準在2013年4月13日被接受為國際電信聯盟(ITU-T)的正式標準。HEVC被認為不僅提升視訊質量,同時也能達到H.264/MPEG-4 AVC兩倍之壓縮率(等同於同樣畫面質量下位元率減少了50%),可支援4K解析度甚至到超高清電視(UHDTV),最高解析度可達到8192×4320(8K解析度)。

H.265的開源實現

  • libde265
  • x265

libde265 HEVC由struktur公司以開源許可證GNU LesserGeneral Public License(LGPL)提供,觀眾可以較慢的網速下欣賞到最高品質的影像。跟以前基於H.264標準的解碼器相比,libde265 HEVC解碼器可以將您的全高清內容帶給多達兩倍的受眾,或者,減少50%流媒體播放所需要的頻寬。高清或者4K/8K超高清流媒體播放,低延遲/低頻寬視訊會議,以及完整的移動裝置覆蓋。具有「擁塞感知」視訊編碼的穩定性,十分適合應用在3/4G和LTE網路。

x265是由MulticoreWare開發,並開源。採用GPL協議,但是資助這個專案的幾個公司組成了聯盟可以在非GPL協議下使用這個軟體。

3) VP8簡介

VP8是一個開放的視訊壓縮格式,最早由On2 Technologies開發,隨後由Google釋出。同時Google也釋出了VP8編碼的實做庫:libvpx,以BSD授權條款的方式發行,隨後也附加了專利使用權。而在經過一些爭論之後,最終VP8的授權確認為一個開放原始碼授權。

目前支援VP8的網頁瀏覽器有Opera、Firefox和Chrome。

專利許可

2013年三月,Google與MPEG LA及11個專利持有者達成協議,讓Google獲取VP8以及其之前的VPx等編碼所可能侵犯的專利授權,同時Google也可以無償再次授權相關專利給VP8的使用者,此協議同時適用於下一代VPx編碼。至此MPEG LA放棄成立VP8專利集中授權聯盟,VP8的使用者將可確定無償使用此編碼而無須擔心可能的專利侵權授權金的問題。

VP8 的開源實現

  • libvpx

libvpx是VP8的唯一開源實現,由On2 Technologies開發,Google收購後將其開放原始碼,License非常寬鬆可以自由使用。

4) VP9簡介

VP9的開發從2011年第三季開始,目標是在同畫質下,比VP8編碼減少50%的檔案大小,另一個目標則是要在編碼效率上超越HEVC編碼。

2012年12月13日,Chromium瀏覽器加入了VP9編碼的支援。Chrome瀏覽器則是在2013年2月21日開始支援VP9編碼的視訊播放。

Google宣佈會在2013年6月17日完成VP9編碼的制定工作,屆時Chrome瀏覽器將會把VP9編碼預設引導。2014年3月18日,Mozilla在Firefox瀏覽器中加入了VP9的支援。

2015年4月3日,谷歌釋出了libvpx1.4.0增加了對10位和12位的位元深度支援、4:2:2和4:4:4色度抽樣,並VP9多核心編/解碼。

專利許可

VP9是一個開放格式、無權利金的視訊編碼格式。

VP9的開源實現

  • libvpx

libvpx是VP9的唯一開源實現,由Google開發維護,裡面有部分程式碼是VP8和VP9公用的,其餘分別是VP8和VP9的編解碼實現。

VP9和H.264和HEVC比較

圖片描述

HEVC和H.264在不同解析度下的比較

跟H.264/MPEG-4相比,HEVC的平均位元率減低值為:

圖片描述

可見位元速率下降了60%以上。

  • HEVC(H.265)對VP9和H.264在位元速率節省上有較大的優勢,在相同PSNR下分別節省了48.3%和75.8%。
  • H.264在編碼時間上有巨大優勢,對比VP9和HEVC(H.265),HEVC是VP9的6倍,VP9是H.264的將近40倍

5) FFmpeg

談到視訊編碼相關內容就不得不提一個偉大的軟體包——FFmpeg。

FFmpeg是一個自由軟體,可以執行音訊和視訊多種格式的錄影、轉換、流功能,包含了libavcodec——這是一個用於多個專案中音訊和視訊的解碼器庫,以及libavformat——一個音訊與視訊格式轉換庫。

FFmpeg這個單詞中的FF指的是Fast Forward。有些新手寫信給FFmpeg的專案負責人,詢問FF是不是代表Fast Free或者Fast Fourier等意思,FFmpeg的專案負責人回信說:「Just for the record, the original meaning of FF in FFmpeg is Fast Forward.」

這個專案最初是由Fabrice Bellard發起的,而現在是由Michael Niedermayer在進行維護。許多FFmpeg的開發者同時也是MPlayer專案的成員,FFmpeg在MPlayer專案中是被設計為伺服器版本進行開發。

  • 可以瀏覽器輸入下載,目前支援Linux、Mac OS、Windows三個主流的平臺,也可以自己編譯到Android或者iOS平臺。
  • 如果是Mac OS,可以通過brew安裝

brew install ffmpeg --with-libvpx --with-libvorbis --with-ffplay

我們可以用FFmpeg來做哪些有用有好玩的事情呢?通過一系列小實驗來帶大家領略FFmpeg的神奇和強大。

FFmpeg錄屏

通過一個小例子看一下怎麼在Mac OS下面使用FFmpeg進行錄屏:

輸入:

ffmpeg -f avfoundation -list_devices true -i ""

輸出:

[AVFoundation input device @ 0x7fbec0c10940] AVFoundation video devices: [AVFoundation input device @ 0x7fbec0c10940] [0] FaceTime HD Camera [AVFoundation input device @ 0x7fbec0c10940] [1] Capture screen 0 [AVFoundation input device @ 0x7fbec0c10940] [2] Capture screen 1 [AVFoundation input device @ 0x7fbec0c10940] AVFoundation audio devices: [AVFoundation input device @ 0x7fbec0c10940] [0] Built-in Microphone

給出了當前裝置支援的所有輸入裝置的列表和編號,我本地有兩塊顯示器,所以1和2都是我螢幕,可以選擇一塊進行錄屏。

檢視當前的H.264編解碼器:

輸入:

ffmpeg -codecs | grep 264

輸出:

DEV.LS h264                 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (decoders: h264 h264_vda ) (encoders: libx264 libx264rgb )

檢視當前的VP8編解碼器:

輸入:

ffmpeg -codecs | grep vp8

輸出:

DEV.L. vp8                  On2 VP8 (decoders: vp8 libvpx ) (encoders: libvpx )

可以選擇用vp8或者h264做編碼器

ffmpeg -r 30 -f avfoundation -i 1 -vcodec vp8 -quality realtime screen2.webm # -quality realtime 用來優化編碼器,如果不加在我的 Air 上幀率只能達到 2

or

ffmpeg -r 30 -f avfoundation -i 1 -vcodec h264 screen.mp4

然後用ffplay播放就可以了

ffplay screen.mp4

or

ffplay screen2.webp

FFmpeg視訊轉換成gif

有一個特別有用的需求,在網上發現了一個特別有趣的視訊想把她轉換成一個動態表情,作為一個IT從業者,我第一個想到的不是下載一個轉碼器,也不是去找一個線上轉換網站,直接利用手邊的工具FFmpeg,瞬間就完成了轉碼:

ffmpeg -ss 10 -t 10  -i tutu.mp4  -s 80x60  tutu.gif ## -ss 指從 10s 開始轉碼,-t 指轉換 10s 的視訊 -s

FFmpeg錄製螢幕並直播

可以繼續擴充套件例子1,直播當前螢幕的內容,向大家介紹一下怎麼通過幾行命令搭建一個測試用的直播服務:

Step 2:下載nginx-rtmp映象:

docker pull chakkritte/docker-nginx-rtmp

Step 3:建立nginx html路徑,啟動docker-nginx-rtmp:

mkdir ~/rtmp  docker run -d -p 80:80 -p 1935:1935 -v ~/rtmp:/usr/local/nginx/html chakkritte/docker-nginx-rtmp

Step 4:推送螢幕錄製到nignx-rtmp:

ffmpeg -y -loglevel warning -f avfoundation -i 2 -r 30 -s 480x320 -threads 2 -vcodec libx264  -f flv rtmp://127.0.0.1/live/test

Step 5:用FFplay播放:

ffplay rtmp://127.0.0.1/live/test

總結一下,FFmpeg是個優秀的工具,可以通過它完成很多日常的工作和實驗,但是距離提供真正可用的流媒體服務、直播服務還有非常多的工作要做,這方面可以參考七牛雲釋出的七牛直播雲服務。

封裝

介紹完了視訊編碼後,再來介紹一些封裝。沿用前面的比喻,封裝可以理解為採用哪種貨車去運輸,也就是媒體的容器。

所謂容器,就是把編碼器生成的多媒體內容(視訊,音訊,字幕,章節資訊等)混合封裝在一起的標準。容器使得不同多媒體內容同步播放變得很簡單,而容器的另一個作用就是為多媒體內容提供索引,也就是說如果沒有容器存在的話一部影片你只能從一開始看到最後,不能拖動進度條(當然這種情況下有的播放器會話比較長的時間臨時建立索引),而且如果你不自己去手動另外載入音訊就沒有聲音,下面介紹幾種常見的封裝格式和優缺點:

1)AVI格式(字尾為.avi):它的英文全稱為Audio Video Interleaved,即音訊視訊交錯格式。它於1992年被Microsoft公司推出。這種視訊格式的優點是影象質量好。由於無損AVI可以儲存alpha通道,經常被我們使用。缺點太多,體積過於龐大,而且更加糟糕的是壓縮標準不統一,最普遍的現象就是高版本Windows媒體播放器播放不了採用早期編碼編輯的AVI格式視訊,而低版本Windows媒體播放器又播放不了採用最新編碼編輯的AVI格式視訊,所以我們在進行一些AVI格式的視訊播放時常會出現由於視訊編碼問題而造成的視訊不能播放或即使能夠播放,但存在不能調節播放進度和播放時只有聲音沒有影象等一些莫名其妙的問題。

2)DV-AVI格式(字尾為.avi):DV的英文全稱是Digital Video Format,是由索尼、松下、JVC等多家廠商聯合提出的一種家用數字視訊格式。數字攝像機就是使用這種格式記錄視訊資料的。它可以通過電腦的IEEE 1394埠傳輸視訊資料到電腦,也可以將電腦中編輯好的的視訊資料回錄到數碼攝像機中。這種視訊格式的副檔名也是AVI。電視臺採用錄影帶記錄模擬訊號,通過EDIUS由IEEE 1394埠採集卡從錄影帶中採集出來的視訊就是這種格式。

3)QuickTime File Format格式(字尾為.mov):美國Apple公司開發的一種視訊格式,預設的播放器是蘋果的QuickTime。具有較高的壓縮比率和較完美的視訊清晰度等特點,並可以儲存alpha通道。

4)MPEG格式(檔案字尾可以是.mpg、.mpeg、.mpe、.dat、.vob、.asf、.3gp、.mp4等):它的英文全稱為Moving Picture Experts Group,即運動影象專家組格式,該專家組建於1988年,專門負責為CD建立視訊和音訊標準,而成員都是為視訊、音訊及系統領域的技術專家。MPEG檔案格式是運動影象壓縮演算法的國際標準。MPEG格式目前有三個壓縮標準,分別是MPEG-1、MPEG-2、和MPEG-4。MPEG-1、MPEG-2目前已經使用較少,著重介紹MPEG-4,其制定於1998年,MPEG-4是為了播放流式媒體的高質量視訊而專門設計的,以求使用最少的資料獲得最佳的影象質量。目前MPEG-4最有吸引力的地方在於它能夠儲存接近於DVD畫質的小體積視訊檔案。

5)WMV格式(字尾為.wmv、.asf):它的英文全稱為Windows Media Video,也是微軟推出的一種採用獨立編碼方式並且可以直接在網上實時觀看視訊節目的檔案壓縮格式。WMV格式的主要優點包括:本地或網路回放,豐富的流間關係以及擴充套件性等。WMV格式需要在網站上播放,需要安裝Windows Media Player(簡稱WMP),很不方便,現在已經幾乎沒有網站採用了。

6)Real Video格式(字尾為.rm、.rmvb):Real Networks公司所制定的音訊視訊壓縮規範稱為Real Media。使用者可以使用RealPlayer根據不同的網路傳輸速率制定出不同的壓縮比率,從而實現在低速率的網路上進行影像資料實時傳送和播放。RMVB格式:這是一種由RM視訊格式升級延伸出的新視訊格式,當然效能上有很大的提升。RMVB視訊也是有著較明顯的優勢,一部大小為700 MB左右的DVD影片,如果將其轉錄成同樣品質的RMVB格式,其個頭最多也就400 MB左右。大家可能注意到了,以前在網路上下載電影和視訊的時候,經常接觸到RMVB格式,但是隨著時代的發展這種格式被越來越多的更優秀的格式替代,著名的人人影視字幕組在2013年已經宣佈不再壓制RMVB格式視訊。

7)Flash Video格式(字尾為.flv):由Adobe Flash延伸出來的的一種流行網路視訊封裝格式。隨著視訊網站的豐富,這個格式已經非常普及。

8)Matroska格式(字尾為.mkv):是一種新的多媒體封裝格式,這個封裝格式可把多種不同編碼的視訊及16條或以上不同格式的音訊和語言不同的字幕封裝到一個Matroska Media檔內。它也是其中一種開放原始碼的多媒體封裝格式。Matroska同時還可以提供非常好的互動功能,而且比MPEG的方便、強大。

9)MPEG2-TS格式(字尾為.ts)(Transport Stream「傳輸流」;又稱MTS、TS)是一種傳輸和儲存包含音效、視訊與通訊協議各種資料的標準格式,用於數字電視廣播系統,如DVB、ATSC、IPTV等。MPEG2-TS定義於MPEG-2第一部分,系統(即原來之ISO/IEC標準13818-1或ITU-T Rec. H.222.0)。Media Player Classic、VLC多媒體播放器等軟體可以直接播放MPEG-TS檔案。

目前,我們在流媒體傳輸,尤其是直播中主要採用的就是FLV和MPEG2-TS格式,分別用於RTMP/HTTP-FLV和HLS協議。

在下一篇連載中,我們將詳細介紹推流和傳輸,敬請期待!