M3U8 串流影音 — 概念 與 下載

現今,許多影音媒體網站皆能看到 M3U8 檔案,
以及許多副檔名為 .ts 的分段媒體,
本篇將介紹其基本概念,並說明如何下載成 mp4 檔 😆。
 
go-car
 


 

HLS 簡介

Apple Inc. 於 2009 年時提出了 HTTP Live Streaming (HLS),
恰如其名,HLS 是一基於 HTTP(S) 的 串流媒體協議。
[註]:當然,串流傳輸的方式不止這種 (e.g., DASH, RTMP, RTP/RTSP, Range Request)。
 
HLS 的原理是 將媒體切成多個小片段;常見格式是 MPEG-TS(.ts),也可為 fragmented MP4(常見 .m4s) (通常不超過 10s),
並用一個 索引檔 (index file) 記錄這些小檔案的順序與位址,即 — .M3U8 檔
 
HLS
[註]: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 後,
便能依進度對其中的 媒體片段 發送請求 😆。
(全部片段依播放清單順序組合,就是完整的影片囉)
 


 

FFMPEG

有了以上基本知識,便能開始下載囉!
其基本概念就是:

  1. 獲取 .m3u8 檔
  2. 依照 .m3u8,依序取得其中的 .ts
  3. 將多個 .ts 合併為單一媒體

 
放心,實際上真正需要動手的只有第一步驟,
第二與第三步驟,霸道的 FFmpeg 幫我們做好了!
ffmpeg-logo-1-1024x585
 


 

下載 FFmpeg

首先,先著手安裝 FFmpeg 吧!
使用 Mac 的朋友,可以使用 Homebrew 一鍵完成:

brew install ffmpeg

 
若您是 Windows 平台,則可以去 官網 下載,
當然,若您想直接作為可執行檔使用,不想另外自行編譯,
請選擇 Windows Package 的 Windows Builds:
ffmpeg-win
 
接著,下載對映架構的 靜態編譯 (Static Build):
ffmpeg-static-build
 
下載完成後,便解壓縮到一個喜歡的地方吧 😃,
這裡以 C 槽的 Program Files 為例,並命名目錄為 ffmpeg:
ffmpeg-win-path
 
欸~ 先別急著關閉視窗!請先複製底下 bin 資料夾的路徑,例如:

C:Program Filesffmpegbin

 


 

設置 PATH

為了便於使用,接下來要設置環境變數 $PATH
使用 Mac 的朋友什麼都不用做,Homebrew 幫你鏈結完成了 😆。
 
而使用 Windows 的話,則在『本機』點擊右鍵,進入『內容』,
接著『進階系統設定』->『環境變數』-> 找到(或新增) Path 變數,
將剛剛複製的 bin 路徑貼上,即可保存離開:
win-path-setting
 


 

檢查版本

安裝與設置已經大功告成囉,打開一個『新的』終端機測試看看吧!
使用 Mac 的朋友,可以叫 siri 幫你開 😂:
siri-terminal
 
使用 Windows 的話,則搜尋 cmd,打開命令提示字元:
win-cmd
 
接著輸入:

ffmpeg -version

若出現以下類似畫面便代表成功囉!
ffmpeg-v
 
 
若出現「找不到命令」,排除您 $Path 設置錯誤,
則通常是新環境變數尚未生效,最簡單的解法就是重新啟動囉!
 


 

保存自己或獲授權的 HLS 內容

先講清楚:看到 .m3u8 網址,不等於取得下載、重製或散布的授權。這裡的 FFmpeg 範例只適用於自己製作、明確獲授權,或服務本身提供下載權利的未加密內容。

HLS 播放清單可以是 Media Playlist,也可以是 Master Playlist;後者會列出不同解析度、位元率、音訊或字幕版本。片段未必是 .ts,也可能是 fMP4 的 .m4s;讓 FFmpeg 讀取播放清單即可,毋須自行把片段串接。

ffmpeg -i "https://example.com/authorized/playlist.m3u8" -c copy output.mp4

-c copy 不重新編碼,速度快且不傷畫質;前提是選定串流與輸出容器相容。若需要轉碼,應依自己的內容與目標播放環境另行選擇 codec。

加密、DRM 與存取控制

HLS 可以使用加密,也常搭配登入、權杖、Cookie 或 DRM 保護內容。這些機制是授權邊界,不是「下載失敗時要偽造的表頭」。遇到受保護內容,正確做法是使用提供者的官方離線功能、取得內容權利人的授權,或向平台確認可保存的方式;不要嘗試繞過 DRM、帳號權限、Token 或其他存取控制。

自己做 HLS 時的測試方式

若你正在開發或部署自己的串流服務,最好的測試素材就是自己產出的 playlist。用瀏覽器開發者工具確認播放清單、Variant Stream、字幕與錯誤回應,再用 FFmpeg 驗證未加密版本是否可被正確封裝;這比從陌生影音網站複製請求更可重現,也更不容易踩到法律與安全問題。

作者: 鄭中勝
喜愛音樂,但不知為何總在打程式 ? 期許能重新審視、整理自身所學,幫助有需要的人。

在〈M3U8 串流影音 — 概念 與 下載〉中有 24 則留言

  1. 請問某網站出現 Server returned 403 Forbidden (access denied)
    這有解嗎? 我用最後的方法
    另外 以上語法貌似是在MAC下的格式 CMD下有點不同

    1. 這是因為 Windows 沒有 $’ ‘ 字串喔!
      因此 HTTP 表頭並未設定成功
      可透過 C 或 Java…等處理表頭字串
      並代為執行 ffmpeg 😃

          1. 所以勝哥有tool 了嗎:D,
            還是windows 有什麼方法可以解決access denied這個問題

  2. call([“ffmpeg”,
    “-protocol_whitelist”, proWhitelist,
    “-user_agent”, userAgent,
    “-headers”, headers,
    “-i”, url,
    “-c”, codec,
    outputUrl])

    請問以上的 (“-c”, codec, ) codec 要填什麼才對呢? 這裡的codec是什麼意思呢?

    1. 可以直接填入 copy 即可喔!
      codec 是指 編碼器與解碼器 (encoder and decoder)

  3. 個別的TS檔網址出現403 forbidden 是因為也有檢查cookie嗎? 還是TS有寫入保護?

    1. 都有可能喔!
      因此在不清楚 Server 的配置下,只能進行測試囉

  4. 請問一下,用儲存本地檔案的方式cmd跑完後顯示:
    Error when loading first segment ‘http://xxx.ts’
    C:\Users\Tofu\Desktop\test.m3u8: Invalid data found when processing input
    是哪裡有錯誤呢??

  5. 把ffmpeg加到Path之後,
    windows檢查ffmpeg有沒有安裝成功那裡,要用系統管理員身份執行cmd,不然Windows會擋下來,然後裝傻跟你說不知道ffmpeg是什麼….

  6. 根据您的方法成功提取视频了!十分简单易懂的教程,真的十分感谢^_^

  7. 請問如果Unable to open key file 類似這種訊息 要如何處理呢?
    有用過VDH試過同個網站 好像抱錯ERROR ABORTED

  8. 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

  9. 身為Linux的用戶一定要給你大大的讚,太詳細了
    也很好除錯,感謝大大提供,如果大大也是熱愛寫程式的人可以與我聯絡討論哦

  10. 不好意思,請問我在環境變數的使用者變數中只有看到TEMP而沒有其他的,但系統變數中有PATH,請問我是要在下方的系統變數的PATH中新增嗎?感謝你~

發表迴響