天天看點

音視訊開發之旅(51)-M3U8邊緩存邊播放

目錄

  1. MP4的“問題”
  2. m3u8是什麼
  3. m3u8的好處
  4. 源碼分析
  5. 擴充思考:mp4能不能像m3u8一樣進行分片緩存呐?
  6. 資料
  7. 收獲

一、MP4的“問題”

我們上面兩篇邊緩存邊播放之緩存分片都針對MP4格式進行緩存處理,由于很多視訊都是mp4格式,是以市面上商用的或者開源的播放器和緩存項目都是隻支援MP4. 但是mp4格式有兩個弊端(當然也是有辦法進行優化的)

1.1 moov在mdat後影響秒開率

Mp4格式是一個個Box,其中moov存儲的是metadata資訊,mdat存儲具體音視訊資料資訊。如果無法解析出moov資料,是無法播放該mp4檔案的。而一般情況下ffmpeg生成moov是在mdat寫入完成之後的,即mdat會在moov的前面,用mediaParse來檢視一個mp4視訊的結構如下

音視訊開發之旅(51)-M3U8邊緩存邊播放

這樣就影響使用者體驗(首幀加載時長過長)。

針對這種情況,通用的做法是在服務端做處理。通過ffmpeg指令吧moov移動到mdat前面。

ffmpeg -i in.mp4 -movflags faststart out.mp4
           

再用mediaParse來檢視一個mp4視訊的結構如下

音視訊開發之旅(51)-M3U8邊緩存邊播放

1.2 緩存分片的顆粒太大、檔案空洞占用空間

m3u8 檔案格式詳解

把mp4轉為ts m3u8

//如果視訊是h264
ffmpeg -y -i 11.mp4 -vcodec copy  -vbsf h264_mp4toannexb out.ts

//如果視訊是h265
ffmpeg -y -i 11.mp4 -vcodec copy  -vbsf hevc_mp4toannexb out.ts
           

将ts切成小的ts片

ffmpeg -i out.ts  -c copy -map 0 -f segment -segment_list ts/index.m3u8 -segment_time 15 ts/out-%04d.ts

//-f segment:切片
//-segment_list :輸出切片的m3u8
//-segment_time:每個切片的時間(機關秒)
           
音視訊開發之旅(51)-M3U8邊緩存邊播放

可以看到包含了一個m3u8檔案和多個ts檔案,其中M3U8是描述檔案,ts是媒體檔案。

我們先來看下M3U8檔案

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:16  --> 共16個ts片
#EXTINF:15.520000,        --> 該片的時長
out-0000.ts               --> 該片的名稱
#EXTINF:14.360000,
out-0001.ts
#EXTINF:15.720000,
out-0002.ts
#EXTINF:14.720000,
out-0003.ts
#EXTINF:14.440000,
out-0004.ts
#EXTINF:15.280000,
out-0005.ts
#EXTINF:15.640000,
out-0006.ts
#EXTINF:14.560000,
out-0007.ts
#EXTINF:15.040000,
out-0008.ts
#EXTINF:15.360000,
out-0009.ts
#EXTINF:14.640000,
out-0010.ts
#EXTINF:14.200000,
out-0011.ts
#EXTINF:15.160000,
out-0012.ts
#EXTINF:14.760000,
out-0013.ts
#EXTINF:15.640000,
out-0014.ts
#EXTINF:14.720000,
out-0015.ts
#EXTINF:9.960000,
out-0016.ts
#EXT-X-ENDLIST
           

m3u8檔案是一個播放清單(playlist)索引,記錄了一系列媒體片段資源,順序播放該片段資源,即可完整展示多媒體資源。

ts是視訊流檔案

// ffprobe /Users/yabin/Desktop/tmp/ts/out-0001.ts

 Duration: 00:00:14.36, start: 16.960000, bitrate: 351 kb/s
  Program 1
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
    Stream #0:0[0x100]: Video: hevc (Main) (HEVC / 0x43564548), yuv420p(tv), 590x1280, 25 fps, 25 tbr, 90k tbn, 25 tbc
           

ts檔案是一種視訊切片檔案,可以直接播放

對于點播來說,用戶端隻需按順序下載下傳上述片段資源,依次進行播放即可。而對于直播來說,用戶端需要 定時重新請求 該 m3u8 檔案,看下是否有新的片段資料需要進行下載下傳并播放

 JeffVideoCache 的實作。

主流程和視訊檔案M3U8和TS格式切片,讨論一下?

  • m3u8 檔案格式詳解
  • JeffVideoCache
  • 頭條都在用的邊下邊播方案
  • 網易新聞從0到1的短視訊性能優化之路
  • 七、收獲

    通過本篇的學習時間
    1. 了解了MP4的“問題”(moov和mdat的順序影響解析速度、長視訊緩存整個檔案為機關緩存導緻命中率和複用率不夠高)
    2. 了解M3U8是一種協定,對視訊進行ts切片,可以根據不同網絡切換不同切片的碼率、緩存的大小可以以更小可以的切片為機關等優點
    3. 簡單分析了JeffVideoCache對M3U8的解析和緩存支援。

    感謝你的閱讀

    下一篇我們開始多線程并發的學習實踐,歡迎關注公衆号“音視訊開發之旅”,一起學習成長。

    歡迎交流