HLS+FMP4方案對H.265+AAC支持要點

​問題背景:

2017年的蘋果WWDC大會上,蘋果宣佈HEVC支持HLS,涉及了iOS、MacOS和tvOS等系統終端。蘋果之所以樂意這個事情,首先HLS就是他們家的,近些年一直把HLS致力於推成Web標準,其次蘋果手握大量H.265的專利,也不想谷歌的AOM對應的VP9標準一家獨大,HLS雖然延時有些大,但不可否認的,目前HLS是跨平臺做的最好的協議。

 

我們之所以想實現下這塊是因爲近年來:

1.視頻監控領域現在攝像頭和NVR對H.265支持的越來越好,很多設備後臺默認配置現在就是H.265,所以設備端(IPC和NVR)支持了,播放端也要跟着支持起來;

2.有實實在在的Web端播放需求,隨着目前設備上雲速度加快,無論是傳統行業還是消費類攝像頭,現在不僅僅在Native App播放,也有很多Web端播放需求。像在Web端分享一條鏈接就能在小程序上直播視頻就很有用,特別是和一些報警聯動起來,的確會方便不少;

3.視頻監控還有一個重要需求就是視頻回放功能,因爲事後查詢很必要,H.265相比較H.264在1080P分辨率下,要節省將近50%的帶寬。同時在畫質不變情況下,相比較H.264碼率也可以將近降低50%左右,所以無論從存儲和帶寬壓力和還是從畫質提升上,HEVC編碼都是非常剛需的。 

綜上,HLS在分發視頻時不僅僅要支持H.264,也要支持HEVC,可以根據請求客戶端類型和設備碼流編碼格式進行匹配分發。

 

智媒黑板報

瞭解更多關於音視頻&IOT,歡迎關注公衆號:智媒黑板報

 


注:

1. HEVC即High Efficency Video Coding是AVC(Advance Video Codeing)的演進版本,其中HEVC又稱爲H.265,而AVC也叫做H.264,這兩個其實是一回事。至於爲啥有兩個別名,簡單來說視頻編碼標準以前主要由兩個國際化標準組織制定,其中H.26X系列,是由國際電信聯盟電信標準化部門ITU-T制定,AVC和HEVC主要是ISO國際標準化組織MPEG制定,從H.264開始,它兩聯合制定過視頻編碼標準,所以具有了兩個名字,但是實際是一回事。對於下一代標準也在去年正式定稿,其中ITU-T稱爲H.266,MPEG則稱爲VCC,感興趣的可以瞭解下視頻編碼的發展歷程。

 


支持原理:

HLS支持H.264已經比較成熟,就是將碼流進行MPEG-TS切片,然後通過HLS協議分發出去,客戶端通過解析m3u8裏面的TS片段對應的URL,然後不斷循環拉TS片段進行播放即可。目前在Web端,移動端支持的都非常好,系統無論是IOS還是Android 基本都可以原生支持播放。

HLS支持HEVC,採用的技術和H.264基本一樣,其中變化點主要是H.265的切片文件封裝格式是Fragmented Mp4簡稱FMP4,其次m3u8裏面的版本採用V7,服務端只要做好適配即可。

給三個鏈接,大家可以抓包學習協議細節:

HEVC HLS with fMP4:

http://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream_fmp4.m3u8

HEVC HLS with TS (not supported by Apple):

http://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream_ts.m3u8

HEVC MPEG-DASH:

http://bitmovin-a.akamaihd.net/content/dataset/multi-codec/hevc/stream.mpd

 

其中FMP4封裝格式是HTML5的Media Source Extensions支持的封裝格式,像B站的flv.js項目核心就是將FLV文件流轉封裝爲FMP4片段,然後通過該接口送給瀏覽器進行解碼播放,同時FMP4也是DASH協議的媒體文件封裝格式,它和MP4封裝格式非常類似,其實就是把大的MP4文件進行切片,每個切片都有它自己的meta數據,這樣就可以單獨播放並且特別適合網絡漸進式傳輸和漸進式播放,同時也方便支持Trick-Play播放。大體結構示意圖如下:

用MP4 Reader解析了一個FMP4文件:

 

 


支持要點:

1. 服務端支持HEVC和H.264相比有啥不同?

主要在拉到設備端原始碼流後,對NALU TYPE的判斷有不同。 

其中收到H.264判斷方法如下:

int nalu_type = buf[0] & 0x1F;

其中nalu_type爲5則表示IDR幀,6表示SEI、7表示SPS、8表示PPS;

對HEVC的NALU類型判斷:

int nalu_type = (buf[0] & 0x7E)>>1;

//or

int nalu_type = (buf[0] >> 1) & 0x3F;

其中nalu_type19代表IDR幀,32位VPS、33位SPS、34爲PPS、39爲SEI;

網上這塊內容非常多,可以找來學習看下,不再贅述。

 


2. 基於Ffmpeg對MPEG-TS和FMP4的切片需要注意哪些?

封裝這塊直接基於Ffmpeg進行即可,簡單快捷,沒有必要自己完整實現這個。其中適配兩種封裝格式比較簡單,不清楚FFMPEG接口的可以參考下面鏈接進行學習,遇到需要兼容的問題是:

音頻部分:兼容MPEG-TS的ADTS和FMP4的ASC音視頻規格參數

音頻我們採用的AAC格式,對於FLV、MP4、FMP4和Mov封裝格式,封裝音頻AAC時需要去掉ADTS頭形成MPEG-4 Audio Specific Configuration bitstream,對於MPEG-TS封裝格式則需要加上ADTS頭,這是在音頻方面需要兼容的。

由於我們採用了FFmpeg進行打包和封裝MPEG-TS和FMP4片段,則藉助FFMPEG的Bitstream Filters即BSF機制即可。

音頻我們去掉ADTS頭形成ASC,一般就是將讀出來的AvPacket進行過濾器進行轉化下即可:

 

示例代碼:

AVBitStreamFilterContext*m_pAacbsf = = av_bitstream_filter_init("aac_adtstoasc");

視頻部分:

無論是H.264還是H.265,封裝格式都有兩種:AnnexB( Annex B of the ITU-T H.264 specification)和AVCC/HVCC格式,其中前者就是在每幀如SPS PPS IDR前面加上StartCode即00 00 00 01 或者00 00 01作爲視頻幀之間的分界符,後者則沒有StartCode,是將SPS、PPS和IDR幀封裝成Container(比如FLV的TAG,MP4的Box),再在前面加上該視頻幀的長度即可,一般長度用四字節表示。

視頻部分一般我們能拿到裸流,所以分別按照不同封裝格式的要求進行封裝即可。如果是MPEG-TS到FMP4的轉化則可以繼續使用FFMPEG的BSF機制進行碼流過濾:


注:

FFMPEG的 Bitstream Filters作用:

1.比特流濾波器對編碼後的數據進行操作(壓縮碼流)。

2.不進行解碼操作,但是支持比特流級別的修改。


3. M3U8要進行升級變化?

這塊我們只做了最簡單的適配和兼容,其中變化很小,其它字段如果你要用可以參考HLS協議規範自行添加。

HLS+FMP4 H.265切片的對應m3u8直播文件

有些媒體格式需要一個 format-specific sequence 來初始化一個 parser, 在 Media Segment 被 parse 之前. 這個字段叫做 Media Initialization Section, 通過 EXT-X-MAP tag 來指定,對於FMP4的初始化Init.mp4的下載鏈接則在這裏指定。

 

HLS+TS H.264切片的對應m3u8回放文件

HLS+FMP4 H.265切片的對應m3u8回放文件 

 


4. 當前客戶端支持情況怎麼樣?

在蘋果產品家族,支持HLS+Fmp4方案,至少應該在 iOS 11, tvOS 11 及 macOS 10.13以後系統進行測試,安卓我們也進行了測試,其中在安卓8以上手機部分機型支持。總體而言,用系統自帶瀏覽器和微信上測試,IOS基本沒有啥問題,播放很順暢,對協議和媒體的兼容性也較好,但是安卓支持的不是很好,例如一些時間戳稍微有問題就不能播放或者黑屏。

 


5. H.264是否可以採用HLS+FMP4方案?

就切片和封裝格式而言,FMP4可以封裝H.265當然也可以封裝H.264,但是兼容性的問題主要是有些原生瀏覽器客戶端不能支持HLS+FMP4方案(包括解析HLS協議和解封裝FMP4),所以對於H.264我們依然採用老方案即HLS+MPEG-TS,對於H.265我們才採用HLS+FMP4.

 


6. 對於音視頻編碼要求和一些HLS的M3U8,還有什麼具體要求?

可能有些音視頻在播放過程中存在一定的問題,這時需要進一步參考HLS規範,看對一些細節方面的要求,可以參考下面鏈接。

https://developer.apple.com/documentation/http_live_streaming/hls_authoring_specification_for_apple_devices#//apple_ref/doc/uid/TP40016596-CH4-SW1

比較重要的幾條:

HEVC的Profile,Level和Tier必須小於或等於Main10的Profile,Level 5.0,High Tier;

HEVC 的幀率必須控制在60fps以內,實際我們一般就是30fps或者25fps;

HEVC的分辨率,我們設備端設置的爲720P或者1080P;

 


測試情況:

下面是一些我們的測試截圖:左圖iPhone8手機IOS13.3微信端測試,右圖Vivo安卓8.1自帶瀏覽器測試,同時我們在IOS12小程序和安卓10上測試也是可以的。

  


最後總結:

這篇文章主要講了HLS協議如果要支持對HEVC進行FMP4切片,大概會遇到哪些問題,已經這些問題的基本思路,同時給出了最簡單的實現效果。在調試過程中還要解決音視頻時間戳問題導致的黑屏、花屏和音畫不同步等問題。這些問題不屬於HLS的範疇,所以沒進行進一步詳細描述,同時也有些HLS的新字段沒啓用,這點要根據場景和需求來開發。

 


參考鏈接:

1.https://developer.apple.com/streaming/

2. https://www.jianshu.com/p/1bfe4470349b

3. https://tools.ietf.org/html/rfc8216

4.https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#page-7

5. https://developer.apple.com/videos/play/wwdc2016/504/

6. https://blog.csdn.net/leixiaohua1020/article/details/39802913

7.http://www.ffmpeg.org/ffmpeg-bitstream-filters.html

 

 


往期文章回顧:

譯:構建音視頻直播應用需要考慮的12件事

流媒體傳輸協議:RTMP、HLS和RTSP介紹

基於HLS-TS&RTMP-FLV的微信小程序點直播方案

一圖看懂音視頻核心技術棧(框架、工具和場景))

國產開源流媒體SRS4.0對視頻監控GB28181的支持

從方塊效應&呼吸效應看編碼量化參數對流控的作用

家庭消費類攝像頭選擇攻略和隱私保護小建議

音視頻封裝小總結(PS TS 和FLV)

SDP在RTSP、國標GB28181、WebRTC中的實踐

視頻監控攝像頭的互聯網化實踐思路

在HTML5上開發音視頻應用的五種思路

週末活動回顧:視頻質量主觀評價、實時RTC和AV1

音視頻封裝:MP4結構概述和分析工具

音視頻解封裝:MP4核心Box詳解及H264&AAC打包方案

音視頻基礎知識-時間戳的理解

音視頻封裝格式:AAC音頻基礎和ADTS打包方案詳解

從人類的第一次直播聊聊視頻監控行業

音視頻壓縮:H264碼流層次結構和NALU詳解

音視頻傳輸:RTP協議詳解和H.264打包方案

音視頻常見問題分析和解決:延時和抖動


個人轉載內容至朋友圈和羣聊天,無需特別申請版權許可。

引用轉載該訂閱號文章,註明文章來源即可。

記得右下角點“在看”,還可以關注該訂閱號,防止遺漏推送哦

 


今天就說這麼多,祝您工作順利!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章