本文講述的是iOS相關(guān)的下載實現(xiàn)方式剪菱。
大綱
1.前言
- M3U8簡介
2. M3U8文件格式
擴(kuò)展M3U指令
頂級M3U8和二級M3U8
3.M3U8下載播放思路
4.下載
M3U8解析
分片下載
合成本地m3u8文件
5.播放
前言
M3U是一種播放多媒體列表的文件格式栖茉,它的設(shè)計初衷是為了播放音頻文件紊浩,比如MP3窖铡,但是越來越多的軟件現(xiàn)在用來播放視頻文件列表,M3U也可以指定在線流媒體音頻源坊谁。很多播放器和軟件都支持M3U文件格式费彼。
M3U文件是一種純文本文件,可以指定一個或多個多媒體文件的位置口芍,其文件擴(kuò)展名是“M3U”或者“m3u”箍铲。
M3U文件具有多個條目,每個條目的格式可以是以下幾種格式之一:
- 一個絕對路徑鬓椭;比如:C:\My Music\Heavysets.mp3
- 一個相對路徑(相對于M3U文件的路徑)颠猴;比如:Heavysets.mp3
- 一個URL M3U文件也有注釋,注釋行以"#"字符開頭小染,在擴(kuò)展M3U文件中翘瓮,"#"還引入了擴(kuò)展M3U指令
M3U8是Unicode版本的M3U,用UTF-8編碼裤翩。"M3U"和"M3U8"文件都是蘋果公司使用的HTTP Live Streaming格式的基礎(chǔ)资盅,這種格式可以在iPhone和Macbook等設(shè)備播放。
M3U8文件格式
擴(kuò)展M3U指令
打開的M3u8內(nèi)容如下所示,每個字段的含義如下
EXTM3U //必需每庆,表示一個擴(kuò)展的m3u文件 - 【判斷格式的標(biāo)準(zhǔn)】
EXT-X-VERSION:3 //hls的協(xié)議版本號今穿,暗示媒體流的兼容性
EXT-X-MEDIA-SEQUENCE:xx //首個分段的sequence number
EXT-X-ALLOW-CACHE:NO //是否緩存
EXT-X-TARGETDURATION:5 //每個視頻分段最大的時長(單位秒)
EXT-X-DISCONTINUITY //表示換編碼
EXTINF //duration每個切片的時長 title指定的文件目錄【屬性duration,title】
EXT-X-ENDLIST//表明m3u8文件的結(jié)束蓝晒。live m3u8沒有該tag。
EXT-X-KEY //定義加密方式和key文件的url利诺,用于取得16bytes的key文件解碼ts文件【屬性:METHOD URL】
頂級m3u8 和二級M3U8
M3U8分頂級M3U8和二級M3U8, 頂級M3U8主要是做多碼率適配的立倍, 二級M3U8才是真正的切片文件口注,
客戶端默認(rèn)會首先選擇碼率最高的請求,如果發(fā)現(xiàn)碼率達(dá)不到娇斑,會請求郊低碼率的流毫缆。(通常用于直播)
一個實際使用中的頂級M3U8文件如下:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=358400
11.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=201273221265,BANDWIDTH=972800
22.m3u8
上面頂級M3U8文件中又定義了 11.m3u8 和 22.m3u8 兩個二級文件苦丁,客戶端會選擇其中一個獲取其內(nèi)容物臂。
二級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下載播放思路
下載
由M3U8的格式可知蛾狗,M3u8的每個切片地址可以是本地地址仪媒,那么我們?nèi)绻胍獙崿F(xiàn)M3u8文件的下載以及播放,只需要把在線的M3U8里的分片下載下來撇贺,然后在本地生成一個m3u8文件冰抢。
下載M3U8主要步驟:
- M3U8解析
拿到一個M3U8鏈接后解析出M3U8索引文件,解析出每一個TS文件的相關(guān)文件信息(地址翠订、時長)
具體解析過程為:
- 根據(jù)
#EXTM3U
標(biāo)識判斷為是M3u8文件- 根據(jù)
#EXTINF:<duration>,<title>
標(biāo)識解析出所有的TS分片地址以及時長- 將獲取到的數(shù)據(jù)創(chuàng)建對應(yīng)的Model存儲
此處解析需要注意:
- 如果M3U8文件為頂級尽超,需要選擇其中的一個索引文件地址(目前默認(rèn)取得是第一個) 去取二級M3u8文件
- 如果獲取的二級m3u8文件里有
#EXT-X-KEY:
關(guān)鍵字似谁,則代表TS文件是被加密的掠哥;對于加密的ts分片续搀,我們只需要將URI里的key下載、存儲到ts相同目錄下彪杉,并且將URI替換為本地地址即可- 目前M3U8的解析采用了開源三方庫 M3U8Parser
- M3U8分片下載
拿到每一個TS文件的鏈接派近,批量下載到本地目錄下
具體的流程為:
- 創(chuàng)建操作:將TS分片下載操作封裝到一個 NSOperation 對象中洁桌。
- 創(chuàng)建隊列:創(chuàng)建 NSOperationQueue 對象战坤,設(shè)置最大支持的下載個數(shù)
- 將操作加入到隊列中:將 NSOperation 對象添加到 NSOperationQueue 對象中
即每個下載的M3u8文件為一個OperationQueue對象,使用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文件
播放
創(chuàng)建本地Server(GCDWebServer)枢析,將本地的m3u8鏈接交給播放器播放
注:
鳴謝
M3U8格式解析M3U8Parser
M3U8文件下載BNM3u8Cache
-
因每個M3U8里包含了大量的ts分片(一部普通電影通常都在幾百到上千個)刃麸,因為需要對ts分片的下載做并發(fā)控制泊业。剛開是想用AFNetWork里的operation來控制,但是實際情況不起作用饮睬,查看AF的源碼發(fā)現(xiàn)此queue只是callback queue篮奄。因此需要自己去管理調(diào)度下載任務(wù),目前采用的是NSOperationQueue來實現(xiàn)多線程控制 ?