現今,許多影音媒體網站皆能看到 M3U8 檔案,
以及許多副檔名為 .ts 的分段媒體,
本篇將介紹其基本概念,並說明如何下載成 mp4 檔 😆。
HLS 簡介
Apple Inc. 於 2009 年時提出了 HTTP Live Streaming (HLS),
恰如其名,HLS 是一基於 HTTP(S) 的 串流媒體協議。
[註]:當然,串流傳輸的方式不止這種 (e.g., DASH, RTMP, RTP/RTSP, Range Request)。
HLS 的原理是 將媒體分割成多個 副檔名為 .ts 的小檔案 (通常不超過 10s),
並用一個 索引檔 (index file) 記錄這些小檔案的順序與位址,即 — .M3U8 檔。
[註]:HLS 並非 real-time delivery system
M3U8
.M3U8 是一種 UTF-8 編碼的 M3U 擴充,簡單來說:
就是一種 播放列表 (playlist)
一個簡易的 .M3U8 檔範例:
#EXT-X-VERSION:3
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:10.0,
https://media.example.com/segment1.ts
#EXTINF:9.5,
https://media.example.com/segment2.ts
#EXT-X-ENDLIST
客戶端 (Client) 透過某 URL 取得 .M3U8 後,
便能依進度對其中的 小媒體 .ts 發送請求 😆。
(全部的 .ts 合起來,就是完整的影片囉)
FFMPEG
有了以上基本知識,便能開始下載囉!
其基本概念就是:
- 獲取 .m3u8 檔
- 依照 .m3u8,依序取得其中的 .ts
- 將多個 .ts 合併為單一媒體
放心,實際上真正需要動手的只有第一步驟,
第二與第三步驟,霸道的 FFmpeg 幫我們做好了!
下載 FFmpeg
首先,先著手安裝 FFmpeg 吧!
使用 Mac 的朋友,可以使用 Homebrew 一鍵完成:
brew install ffmpeg
若您是 Windows 平台,則可以去 官網 下載,
當然,若您想直接作為可執行檔使用,不想另外自行編譯,
請選擇 Windows Package 的 Windows Builds:
接著,下載對映架構的 靜態編譯 (Static Build):
下載完成後,便解壓縮到一個喜歡的地方吧 😃,
這裡以 C 槽的 Program Files 為例,並命名目錄為 ffmpeg:
欸~ 先別急著關閉視窗!請先複製底下 bin 資料夾的路徑,例如:
C:\Program Files\ffmpeg\bin
設置 PATH
為了便於使用,接下來要設置環境變數 $PATH,
使用 Mac 的朋友什麼都不用做,Homebrew 幫你鏈結完成了 😆。
而使用 Windows 的話,則在『本機』點擊右鍵,進入『內容』,
接著『進階系統設定』->『環境變數』-> 找到(或新增) Path 變數,
將剛剛複製的 bin 路徑貼上,即可保存離開:
檢查版本
安裝與設置已經大功告成囉,打開一個『新的』終端機測試看看吧!
使用 Mac 的朋友,可以叫 siri 幫你開 😂:
使用 Windows 的話,則搜尋 cmd,打開命令提示字元:
接著輸入:
ffmpeg -version
若出現以下類似畫面便代表成功囉!
若出現「找不到命令」,排除您 $Path 設置錯誤,
則通常是新環境變數尚未生效,最簡單的解法就是重新啟動囉!
下載 M3U8
環境設置完成後,就開始尋找 .m3u8 播放清單吧,
這部分可利用 Browser 的 開發者工具 輕易達成!
隨便開啟一個分頁後,按 F12 或 ctrl+shift+i 招喚他吧!
接下來,前往你想下載的影片網站吧 (請先確認該網站是採用 hls 😂)!
進入 開發者工具的 網路 (Network) 分頁後,輸入 m3u8 過濾掉垃圾:
點擊右鍵,複製該網址,開啟終端機,輸入以下指令 🧙♂️:
ffmpeg -protocol_whitelist "file,http,https,tcp,tls" \
-i "將m3u8網址貼上到這邊" \
-c copy "你想儲存的檔案路徑/test.mp4"
以 Windows 路徑為例 (Windows 換行符需更換為 ^
):
ffmpeg -protocol_whitelist "file,http,https,tcp,tls" ^
-i "https://xxx.xxx/m3u8" ^
-c copy "C:\Users\Jason\Desktop\test.mp4"
一般影片即可下載完成!
[註]:-i 參數意指 input; -c 參數意指 codec
Troubleshooting
然而,也是有可能下指令後出現錯誤 (假設路徑設置正確),
這通常是因為 .M3U8 或 底下的 .ts 有受到防護,
可能是 HTTP 的 Referer 也或者是 CSRF Token…等。
以下提供兩種解決方案:
儲存 m3u8 為本地文件
首先,找個地方建立一個『xxx.m3u8』文字檔案:
(若有 txt 要記得去掉喔 😄)
將開發者工具的『回應內容』直接複製貼上後存檔:
最後,將 -i 參數 (input) 的對象,改為該檔案路徑,例如:
ffmpeg -protocol_whitelist "file,http,https,tcp,tls" \
-i "C:\Users\Jason\Desktop\test.m3u8" \
-c copy "C:\Users\Jason\Desktop\test.mp4"
註:Windows 系統需將 換行符 (\
) 更換為 ^
此種做法較簡單但不可靠,適用於:
Server 未對 .ts 做進一步防護。
設置 HTTP 表頭
許多網站會透過 User-Agent, Origin, Referer, 甚至 Cookie 等表頭進行簡易的存取認證,
此時可透過 FFMPEG 的 -user_agent 及 -headers 等參數偽造 HTTP 表頭。
首先,透過「開發者工具」->「網路」找到目標 m3u8 檔,並將其連結填入 -i 參數中,
先別急著關閉視窗!去找到請求表/檔頭區塊:
分別將 User-Agent 填入 -user_agent 參數,其他「可疑」表頭填入 -headers 參數:
其中,-headers 的參數值格式建議為 (僅適用於 macOS, Linux 等作業系統):
$'表頭1: 值\r\n表頭2: 值\r\n'
例如:
ffmpeg -protocol_whitelist "file,http,https,tcp,tls" \
-user_agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0" \
-headers $'Origin: origin表頭值\r\nReferer: referer表頭值\r\nCookie: cookie值\r\n' \
-i "http://xxx.yyy/zzz.mp4/index.m3u8" \
-c copy "/Users/Jason/Desktop/example.mp4"
通常透過此法即可下載絕大多數的 m3u8 影音,
若不成功,就得想辦法獲取 Token, 網站授權…等 😄。
然而,Windows 作業系統的 命令提示字元 並不支援 $' '
字串,使用此法將會造成錯誤!
解決方式很多,例如使用「適用於 Linux 的 Windows 子系統」,
或透過其他語言處理表頭字串再執行 FFMPEG。
以 Python 為例:
from subprocess import call
call(["ffmpeg",
"-protocol_whitelist", proWhitelist,
"-user_agent", userAgent,
"-headers", headers,
"-i", url,
"-c", codec,
outputUrl])
以 Java 為例:
ProcessBuilder processBuilder = new ProcessBuilder("ffmpeg",
"-v", v,
"-protocol_whitelist", protocol_whitelist,
"-user_agent", user_agent,
"-headers", headers,
"-i", i,
"-c", c,
output_url);
Process p = processBuilder.start();
在《M3U8 串流影音 — 概念 與 下載》中有 24 則留言
大大我最後顯示No such file or directory怎麼辦呢
檢查存檔路徑是否設置正確
請問某網站出現 Server returned 403 Forbidden (access denied)
這有解嗎? 我用最後的方法
另外 以上語法貌似是在MAC下的格式 CMD下有點不同
這是因為 Windows 沒有 $’ ‘ 字串喔!
因此 HTTP 表頭並未設定成功
可透過 C 或 Java…等處理表頭字串
並代為執行 ffmpeg 😃
感謝您的回覆 (但已經超出我腦袋範圍了 哈哈哈)
我有時間再來寫個 windows 小工具 😂
所以勝哥有tool 了嗎:D,
還是windows 有什麼方法可以解決access denied這個問題
windows 可以使用 IDM 下載工具喔 😄
call([“ffmpeg”,
“-protocol_whitelist”, proWhitelist,
“-user_agent”, userAgent,
“-headers”, headers,
“-i”, url,
“-c”, codec,
outputUrl])
請問以上的 (“-c”, codec, ) codec 要填什麼才對呢? 這裡的codec是什麼意思呢?
可以直接填入 copy 即可喔!
codec 是指 編碼器與解碼器 (encoder and decoder)
個別的TS檔網址出現403 forbidden 是因為也有檢查cookie嗎? 還是TS有寫入保護?
都有可能喔!
因此在不清楚 Server 的配置下,只能進行測試囉
請問一下,用儲存本地檔案的方式cmd跑完後顯示:
Error when loading first segment ‘http://xxx.ts’
C:\Users\Tofu\Desktop\test.m3u8: Invalid data found when processing input
是哪裡有錯誤呢??
能提供指令的部分嗎
把ffmpeg加到Path之後,
windows檢查ffmpeg有沒有安裝成功那裡,要用系統管理員身份執行cmd,不然Windows會擋下來,然後裝傻跟你說不知道ffmpeg是什麼….
根据您的方法成功提取视频了!十分简单易懂的教程,真的十分感谢^_^
請問如果Unable to open key file 類似這種訊息 要如何處理呢?
有用過VDH試過同個網站 好像抱錯ERROR ABORTED
[http @ 0000000000481c00] HTTP error 503 Service Temporarily Unavailable
http://8maple.ru/wp-content/plugins/ck-video/analy/mobile.php?url=7B63BA6A9686BCB9A771_filescdn.m3u8
: Server returned 5XX Server Error reply
請問大大這是什麼錯誤
C:\ffmpeg\bin>ffmpeg -protocol_whitelist “file,http,https,tcp,tls” ^
More? -i “https://hls.hydrax.net/7UA17cpVS9ThW81tleYuEzjTD8TjVz9PWtX4EaAxLSOxLUsqLaO/0/2f7064ca5dc2f4060b146d57a149cb17.m3u8” ^
More? -c copy “xxx.mp4”
ffmpeg version N-93825-gc967128952 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 8.3.1 (GCC) 20190414
configuration: –enable-gpl –enable-version3 –enable-sdl2 –enable-fontconfig –enable-gnutls –enable-iconv –enable-libass –enable-libdav1d –enable-libbluray –enable-libfreetype –enable-libmp3lame –enable-libopencore-amrnb –enable-libopencore-amrwb –enable-libopenjpeg –enable-libopus –enable-libshine –enable-libsnappy –enable-libsoxr –enable-libtheora –enable-libtwolame –enable-libvpx –enable-libwavpack –enable-libwebp –enable-libx264 –enable-libx265 –enable-libxml2 –enable-libzimg –enable-lzma –enable-zlib –enable-gmp –enable-libvidstab –enable-libvorbis –enable-libvo-amrwbenc –enable-libmysofa –enable-libspeex –enable-libxvid –enable-libaom –enable-libmfx –enable-amf –enable-ffnvcodec –enable-cuvid –enable-d3d11va –enable-nvenc –enable-nvdec –enable-dxva2 –enable-avisynth –enable-libopenmpt
libavutil 56. 26.101 / 56. 26.101
libavcodec 58. 52.101 / 58. 52.101
libavformat 58. 27.103 / 58. 27.103
libavdevice 58. 7.100 / 58. 7.100
libavfilter 7. 50.100 / 7. 50.100
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
[https @ 000002a70fe3a0c0] HTTP error 404 Not Found
https://hls.hydrax.net/7UA17cpVS9ThW81tleYuEzjTD8TjVz9PWtX4EaAxLSOxLUsqLaO/0/2f7064ca5dc2f4060b146d57a149cb17.m3u8: Server returned 404 Not Found
C:\ffmpeg\bin>
[https @ 000002a70fe3a0c0] HTTP error 404 Not Found ? ? ?
Please help
身為Linux的用戶一定要給你大大的讚,太詳細了
也很好除錯,感謝大大提供,如果大大也是熱愛寫程式的人可以與我聯絡討論哦
如果找不到m3u8網址怎麼辦?
不好意思,請問我在環境變數的使用者變數中只有看到TEMP而沒有其他的,但系統變數中有PATH,請問我是要在下方的系統變數的PATH中新增嗎?感謝你~
Mac上显示错误:
Option user_agent not found.
怎么解决呢
想請教你如果是分割過的 mp4 如何合併呢