M3U8下載及播放

本文講述的是iOS相關(guān)的下載實(shí)現(xiàn)方式。

大綱

1.前言

  • M3U8簡介

2. M3U8文件格式

  • 擴(kuò)展M3U指令

  • 頂級(jí)M3U8和二級(jí)M3U8

3.M3U8下載播放思路

4.下載

  • M3U8解析

  • 分片下載

  • 合成本地m3u8文件

5.播放

前言

M3U是一種播放多媒體列表的文件格式,它的設(shè)計(jì)初衷是為了播放音頻文件,比如MP3,但是越來越多的軟件現(xiàn)在用來播放視頻文件列表,M3U也可以指定在線流媒體音頻源。很多播放器和軟件都支持M3U文件格式。
M3U文件是一種純文本文件,可以指定一個(gè)或多個(gè)多媒體文件的位置,其文件擴(kuò)展名是“M3U”或者“m3u”。
M3U文件具有多個(gè)條目,每個(gè)條目的格式可以是以下幾種格式之一:

  • 一個(gè)絕對(duì)路徑;比如:C:\My Music\Heavysets.mp3
  • 一個(gè)相對(duì)路徑(相對(duì)于M3U文件的路徑);比如:Heavysets.mp3
  • 一個(gè)URL M3U文件也有注釋,注釋行以"#"字符開頭,在擴(kuò)展M3U文件中,"#"還引入了擴(kuò)展M3U指令

M3U8是Unicode版本的M3U,用UTF-8編碼。"M3U"和"M3U8"文件都是蘋果公司使用的HTTP Live Streaming格式的基礎(chǔ),這種格式可以在iPhone和Macbook等設(shè)備播放。

M3U8文件格式

M3U8文件

擴(kuò)展M3U指令

打開的M3u8內(nèi)容如下所示,每個(gè)字段的含義如下

EXTM3U //必需,表示一個(gè)擴(kuò)展的m3u文件 - 【判斷格式的標(biāo)準(zhǔn)】
EXT-X-VERSION:3 //hls的協(xié)議版本號(hào),暗示媒體流的兼容性
EXT-X-MEDIA-SEQUENCE:xx //首個(gè)分段的sequence number
EXT-X-ALLOW-CACHE:NO //是否緩存
EXT-X-TARGETDURATION:5 //每個(gè)視頻分段最大的時(shí)長(單位秒)
EXT-X-DISCONTINUITY //表示換編碼
EXTINF //duration每個(gè)切片的時(shí)長 title指定的文件目錄【屬性duration,title】
EXT-X-ENDLIST//表明m3u8文件的結(jié)束。live m3u8沒有該tag。
EXT-X-KEY //定義加密方式和key文件的url,用于取得16bytes的key文件解碼ts文件【屬性:METHOD URL】

頂級(jí)m3u8 和二級(jí)M3U8

M3U8分頂級(jí)M3U8和二級(jí)M3U8, 頂級(jí)M3U8主要是做多碼率適配的, 二級(jí)M3U8才是真正的切片文件,

客戶端默認(rèn)會(huì)首先選擇碼率最高的請(qǐng)求,如果發(fā)現(xiàn)碼率達(dá)不到,會(huì)請(qǐng)求郊低碼率的流。(通常用于直播)

一個(gè)實(shí)際使用中的頂級(jí)M3U8文件如下:


#EXTM3U

#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=358400

11.m3u8

#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=972800

22.m3u8

上面頂級(jí)M3U8文件中又定義了 11.m3u8 和 22.m3u8 兩個(gè)二級(jí)文件,客戶端會(huì)選擇其中一個(gè)獲取其內(nèi)容。

二級(jí)M3U8文件內(nèi)容如下:


#EXTM3U

#EXT-X-VERSION:1

#EXT-X-TARGETDURATION:10

#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:3,

1-4.ts

#EXTINF:8,

1-6.ts

#EXTINF:8,

1-8.ts

#EXTINF:8,

1-10.ts

#EXTINF:8,

1-12.ts

#EXTINF:8,

1-14.ts

#EXTINF:8,

1-16.ts

#EXTINF:9,

1-18.ts

#EXTINF:6,

1-20.ts

#EXTINF:8,

1-22.ts

#EXTINF:9,

1-24.ts

#EXTINF:3,

1-26.ts

#EXT-X-ENDLIST

M3u8下載播放思路

iOS播放m3u8文件過程.jpg

下載


由M3U8的格式可知,M3u8的每個(gè)切片地址可以是本地地址,那么我們?nèi)绻胍獙?shí)現(xiàn)M3u8文件的下載以及播放,只需要把在線的M3U8里的分片下載下來,然后在本地生成一個(gè)m3u8文件。

下載M3U8主要步驟:

- M3U8解析

拿到一個(gè)M3U8鏈接后解析出M3U8索引文件,解析出每一個(gè)TS文件的相關(guān)文件信息(地址、時(shí)長)
具體解析過程為:

  • 根據(jù)#EXTM3U標(biāo)識(shí)判斷為是M3u8文件
  • 根據(jù)#EXTINF:<duration>,<title> 標(biāo)識(shí)解析出所有的TS分片地址以及時(shí)長
  • 將獲取到的數(shù)據(jù)創(chuàng)建對(duì)應(yīng)的Model存儲(chǔ)

此處解析需要注意:

  • 如果M3U8文件為頂級(jí),需要選擇其中的一個(gè)索引文件地址(目前默認(rèn)取得是第一個(gè)) 去取二級(jí)M3u8文件
  • 如果獲取的二級(jí)m3u8文件里有#EXT-X-KEY:關(guān)鍵字,則代表TS文件是被加密的;對(duì)于加密的ts分片,我們只需要將URI里的key下載、存儲(chǔ)到ts相同目錄下,并且將URI替換為本地地址即可
  • 目前M3U8的解析采用了開源三方庫 M3U8Parser

- M3U8分片下載

拿到每一個(gè)TS文件的鏈接,批量下載到本地目錄下
具體的流程為:

  • 創(chuàng)建操作:將TS分片下載操作封裝到一個(gè) NSOperation 對(duì)象中。
  • 創(chuàng)建隊(duì)列:創(chuàng)建 NSOperationQueue 對(duì)象,設(shè)置最大支持的下載個(gè)數(shù)
  • 將操作加入到隊(duì)列中:將 NSOperation 對(duì)象添加到 NSOperationQueue 對(duì)象中

即每個(gè)下載的M3u8文件為一個(gè)OperationQueue對(duì)象,使用OperationQueue來管理調(diào)度ts的分片下載任務(wù)[1]

- 合成本地M3U8文件

主要包括:

  • 將ts的鏈接替換為本地server地址

  • 如果有加密,將加密的URI替換為本地下載key的本地server地址

替換后的文件格式:


#EXTM3U

#EXT-X-VERSION:3

#EXT-X-TARGETDURATION:2

#EXT-X-MEDIA-SEQUENCE:0

#EXT-X-KEY:METHOD=AES-128,URI="http://127.0.0.1:8080/f3e67540b5e946c7b313b4575283eefd/key"

#EXTINF:1.000000,

http://127.0.0.1:8080/f3e67540b5e946c7b313b4575283eefd/0.ts

#EXTINF:1.000000,

http://127.0.0.1:8080/f3e67540b5e946c7b313b4575283eefd/1.ts

#EXTINF:1.000000,

http://127.0.0.1:8080/f3e67540b5e946c7b313b4575283eefd/2.ts

#EXTINF:1.000000,

http://127.0.0.1:8080/f3e67540b5e946c7b313b4575283eefd/3.ts

#EXTINF:1.000000,

…

至此,M3U8相關(guān)的本地文件下載就已經(jīng)完成了,下載后的ts分片以及M3U8文件

M3U8本地沙盒文件.png

播放

創(chuàng)建本地Server(GCDWebServer),將本地的m3u8鏈接交給播放器播放

注:


查看m3u8鏈接內(nèi)容工具

鳴謝
M3U8格式解析M3U8Parser
M3U8文件下載BNM3u8Cache


  1. 因每個(gè)M3U8里包含了大量的ts分片(一部普通電影通常都在幾百到上千個(gè)),因?yàn)樾枰獙?duì)ts分片的下載做并發(fā)控制。剛開是想用AFNetWork里的operation來控制,但是實(shí)際情況不起作用,查看AF的源碼發(fā)現(xiàn)此queue只是callback queue。因此需要自己去管理調(diào)度下載任務(wù),目前采用的是NSOperationQueue來實(shí)現(xiàn)多線程控制 ?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容