從瀏覽器下載m3u8串流檔案
現在的影音市場,串流播放已經幾乎完全取代下載檔案的習慣了,所以也很難直接看到完整檔案的下載連結,取而代之的是一堆碎片化的串流檔案。
雖然網路上隨便搜尋也可以找到不少下載工具,不過這邊還是簡單紀錄一下,如果想要自己寫 Javascript 程式去下載該如何處理。
M3U8 檔
一般來說,串流播放的起點通常會下載一個附檔名為.m3u8的檔案,其內容大致上會長這樣:
1 2 3 4 5 6 7 8 9 10 11 12
| #EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:11 #EXT-X-MEDIA-SEQUENCE:1
#EXTINF:xxxx file-00001.ts #EXTINF:xxxx file-00002.ts #EXTINF:xxxx file-00003.ts #EXT-X-ENDLIST
|
將#字號開頭的行數忽略後,會得到
1 2 3
| file-00001.ts file-00002.ts file-00003.ts
|
可以簡單地將其理解為一份串流檔案列表,也就是讓播放器知道接下來要依序下載播放哪些檔案。
有時候這些檔案列表會是使用相對路徑紀錄,像是上述的那樣,這時候要記得使用原本m3u8檔案的下載網址作為相對路徑。
1 2 3 4 5
| m3u8 檔案路徑範例 https://example.com/music/stream.m3u8
ts 檔實際位置 https://example.com/music/file-00001.ts
|
理解檔案格式之後,寫成程式就很簡單了
1 2 3 4 5 6 7 8 9 10 11 12
| const m3u8 = "https://example.com/music/stream.m3u8";
let path = /https:\/\/.+\//.exec(m3u8)[0];
let content = await (await fetch(m3u8)).text();
let arr = content .split("\n") .filter((x) => !x.startsWith("#")) .map((x) => path + x);
|
TS 檔
ts 檔就是一堆攜帶實際內容的二進位檔,這就無法直接打開了。不過有趣的事情是他們幾乎不用做任何處理,直接全部依序打包在一起,並宣告好正確的檔案類型就是完整的檔案了。
1 2 3 4 5 6 7 8
| let bufferList = []; for (let i = 0; i < arr.length; i++) { let buffer = await (await fetch(arr[i])).arrayBuffer(); bufferList.push(buffer); }
let fileBlob = new Blob(bufferList, { type: "audio/mpeg3" });
|
關於 Blob 的 Type 如何宣告:Common MIME types
下載
最後一步,在瀏覽器上觸發下載事件。
原理是生成一個<a><\a>,然後把剛剛打包好的檔案連結放進去並執行點擊
1 2 3 4 5
| let a = document.createElement("a"); a.download = "music.mp3"; a.href = URL.createObjectURL(fileBlob); document.body.appendChild(a); a.click();
|