M3U8文件是指UTF-8編碼格式的M3U文件。M3U文件是記錄了一個索引純文本文件,打開它時播放軟件並非播放它,而是根據它的索引找到對應的音視頻文件的網絡地址進行在線播放。緩存
M3U8是一種常見的流媒體格式,主要以文件列表的形式存在,既支持直播又支持點播,尤爲在Android、iOS等平臺最爲經常使用。服務器
下面是CCTV6直播播放地址:http://ivi.bupt.edu.cn/hls/cctv6hd.m3u8的M3U8的文件列表:網絡
#EXTM3U #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:35232 #EXT-X-TARGETDURATION:10 #EXTINF:10.000, cctv6hd-1549272376000.ts #EXTINF:10.000, cctv6hd-1549272386000.ts #EXTINF:10.000, cctv6hd-1549272396000.ts #EXTINF:10.000, cctv6hd-1549272406000.ts #EXTINF:10.000, cctv6hd-1549272416000.ts #EXTINF:10.000, cctv6hd-1549272426000.ts
下面咱們來分別說明一下相關的幾個字段:性能
關於客戶端播放M3U8的標準還有更多的講究,下面咱們來介紹一些:優化
在上面,咱們提到了,一些上面例子沒有出現的一些標籤字段,下面咱們針對一些額外的標籤作一些補充說明:ui
HLS(全稱:Http Live Streaming)是由Apple公司定義的用於實時流傳輸的協議,HLS基於HTTP協議實現,傳輸內容包括兩部分,一是M3U8描述文件,二是TS媒體文件。編碼
HLS的優點爲:自適應碼率流播(adaptive streaming)。效果就是客戶端會根據網絡情況自動選擇不一樣碼率的視頻流,條件容許的狀況下使用高碼率,網絡繁忙的時候使用低碼率,而且可以自動在兩者之間隨意切換。這對移動設備網絡情況不穩定的狀況下保障流暢播放很是有幫助。實現方法是服務器端提供多碼率視頻流,而且在列表文件中註明,播放器根據播放進度和下載速度進行自動調整。url
爲何要用 TS 而不是 MP4?這是由於兩個 TS 片斷能夠無縫拼接,播放器能連續播放,而 MP4 文件因爲編碼方式的緣由,兩段 MP4 不能無縫拼接,播放器連續播放兩個 MP4 文件會出現破音和畫面間斷,影響用戶體驗。並且若是要在一段長達一小時的視頻中跳轉,若是使用單個 MP4 格式的視頻文件,而且也是用 HTTP 協議,那麼須要代理服務器支持 HTTP range request 獲取大文件中的一部分。這樣的話,對於代理服務器的性能來講要求較高。而 HTTP Live Streaming 則只須要根據列表文件中的時間軸找出對應的 TS 片斷下載便可,不須要 range request,對代理服務器的要求小不少。全部代理服務器都支持小文件的高效緩存。spa
將MP4文件轉換成HLS(M3U8)命令行:命令行
ffmpeg -re -i 好漢歌.mp4 -c copy -f hls -bsf:v h264_mp4toannexb output.m3u8
能夠看到生成的M3U8及相應的ts文件:
查看一下生成的M3U8文件:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:19 #EXTINF:10.000000, output19.ts #EXTINF:10.000000, output20.ts #EXTINF:9.280000, output21.ts #EXTINF:4.120000, output22.ts #EXTINF:2.440000, output23.ts #EXT-X-ENDLIST
細心的人可能發現一個問題,就是生成的m3u8文件裏只有最後的五個片斷的信息。這是由於ffmpeg 默認的list size 爲5,因此只得到最後的5個片斷。爲了解決這個問題,須要指定參數-hls_list_size 0,這樣就能包含全部的片斷。
下面是優化後的命令行:
ffmpeg -re -i 好漢歌.mp4 -c copy -f hls -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
這時,咱們能夠看到從output0.ts到output23.ts的文件列表了。
可能有人會發現,不管是優化以前的命令行,仍是優化後的命令行都有一個參數-bsf:v h264_mp4toannexb,這個參數的做用是將MP4中的H.264數據轉換成爲H.264 AnnexB標準的編碼,AnnexB標準的編碼常見於實時傳輸流中。若是源文件爲FLV、TS等能夠做爲直播傳輸流的視頻,則不須要這個參數。
下面咱們逐一介紹下使用FFmpeg生成HLS時還能夠配置的其餘參數。
start_number 參數用於設置M3U8列表中的第一片的序列數。
下面的例子中,咱們使用start_number參數設置M3U8中的第一片序列書爲100,命令行以下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -start_number 100 -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
輸出的M3U8內容以下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:100 #EXTINF:3.000000, output100.ts #EXTINF:3.000000, output101.ts #EXTINF:3.000000, output102.ts #EXTINF:3.000000, output103.ts #EXTINF:3.000000, output104.ts #EXTINF:3.000000, output105.ts #EXTINF:3.000000, output106.ts #EXTINF:1.000000, output107.ts #EXT-X-ENDLIST
從輸出能夠看出,切片的第一片編號是100,上面的命令行參數的-start_number參數已生效。
hls_time參數用於設置M3U8列表中切片的duration。
下面的例子中,咱們使用hls_time參數設置M3U8的TS文件的每一片時長爲9秒左右。命令行以下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_time 9 -hls_list_size 0 -bsf:v h264_mp4toannexb output.m3u8
而後查看輸出的M3U8內容以下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:9 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:9.000000, output0.ts #EXTINF:9.000000, output1.ts #EXTINF:4.000000, output2.ts #EXT-X-ENDLIST
能夠看到TS的文件每一片的時常都是9秒左右,hls_time參數生效。
( 注意:hls_time設置後效果不必定準確,會受到關鍵幀大小及其餘因素影響。)
若是須要相對很是準確的切片,能夠添加hls_flags的子參數split_by_time來保證生成的切片可以與hls_time設置的切片時長差很少。
( 注意:split_by_time參數必須與hls_time配合使用,而且使用split_by_time參數有可能會影響首畫面體驗,例如花屏或者首畫面顯示慢的問題,由於視頻的第一幀不必定是關鍵幀。)
hls_list_size參數用於爲M3U8列表中的TS切片的個數。其中設置爲0的時候,將包含全部。
這個命令,咱們在第3節優化MP4轉HLS文件的命令行時使用到了。
下面的例子中,咱們使用hls_list_size參數設置只保留2片TS切片。命令行以下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_list_size 2 -bsf:v h264_mp4toannexb output.m3u8
查看輸出的M3U8內容以下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:6 #EXTINF:3.000000, output6.ts #EXTINF:1.000000, output7.ts #EXT-X-ENDLIST
從輸出的M3U8內容能夠看出,在M3U8文件中只保留了2片TS的文件信息,能夠看出hls_list_size設置生效了。
hls_base_url 參數用於爲M3U8列表的文件路徑設置前置基本路徑參數,由於在FFmpeg中生成M3U8時寫入的TS切片路徑默認爲M3U8生成的路徑相同,可是實際上TS所存儲的路徑既能夠爲本地絕對路徑,也能夠爲相對路徑,還能夠爲網絡路徑,所以使用hls_base_url參數能夠達到該效果,命令行以下:
ffmpeg -re -i huijia.mp4 -c copy -f hls -hls_base_url /Users/renhui/Desktop/test/ -bsf:v h264_mp4toannexb output.m3u8
查看輸出的M3U8內容以下:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:3 #EXT-X-MEDIA-SEQUENCE:3 #EXTINF:3.000000, /Users/renhui/Desktop/test/output3.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output4.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output5.ts #EXTINF:3.000000, /Users/renhui/Desktop/test/output6.ts #EXTINF:1.000000, /Users/renhui/Desktop/test/output7.ts #EXT-X-ENDLIST
能夠看到,TS的路徑變爲絕對路徑了,使用ffplay output.m3u8播放,看到播放是可以正常播放的。這樣就能夠說明hls_base_url生效了。