2022年3月27日 星期日

FFmpeg : 下載 .m3u8 播放清單的串流影片

2022年3月27日 星期日

 之前下載網路的影片大多是用 youtube-dl,不過,這幾天在某個以前能輕鬆下載的網站中,卻一直吃閉門羹。研究了幾天,稍有一點眉目。

該網站原來是由播放器載入 .m3u8 的串流播放清單,以前播放清單中放的是影片片段的網址,檔名是用 .ts 來當結尾。這次看到的 .m3u8 有兩個特別之處:一個是裡面又放別的 .m3u8 播放清單;另一種則是裡面不是放 .ts 的網址,居然是 .png 或是 .jpg。

.m3u8 檔案中放 .m3u8 這沒什麼,頂多是程序上多卡一道。但是放 .png 或是 .jpg 就妙了!而且如果將網所指的下載回來,開啟後,還真的是圖片,只差呈現的是一片白而已。利用網站的影片播放器可以播放影片,但是利用 youtube-dl 或是 ffmpeg 試著下載影片,就會出現下載到的是圖片,不是影片的警告訊息,當然影片也就下載不了。

好奇心驅使下,利用 HxD Hex Editor 開啟下載回來的 .png :

.png 影片片段檔案的內容

看到檔案的文件內容,有兩處令人覺得有趣:

  • FFmpeg Service01
  • IDAT

查了一下「IDAT」是 PNG 檔案中會用到的,而 FFmpeg 則是我用來處理影片的工具。於是將這個檔案的前 41 bytes (上圖反白的部份)刪除後,另存檔名為 xxx.png.ts。再用 VLC Player 來播播放,哇!看得到影片了吔!

依樣畫葫蘆,將另外四個小片段都刪掉前 41 bytes,並另存為 xxx.ts,仿原來的 .m3u8 製作了一個有新路徑的播放清單,可以用 ffplay 來播放,也可以利用 ffmpeg 將五個小片段合成一個 mp4 影片檔。

另一部影片的 .m3u8 播放清單中則都是 .jpg ,用 HxD Hex Editor 開啟下載回來的 .jpg 檔案:

.jpg 影片片段檔的內容

這個 .jpg 檔案的內容跟前面的 .png 長得滿像的,來比較一下:

.png 影片片段檔的內容

如果將上圖 .png 檔反白的部份刪除,它的檔頭跟 .jpg 就幾乎一樣了。所以我將下載回來的 .jpg 影片片段檔的檔名字尾加上了「.ts」,用 VLC Player 就可以直接播放了。哈!看起來,這支影片片段檔案的格式、編碼沒有問題,只要讓 FFmpeg 能接受叫「.jpg」的檔名就可以,所以要幫它加上底下的參數:


-allowed_extensions ALL 


完整的指令如下:


ffmpeg -allowed_extensions ALL -i https://xx.xx.xx.xx/index.m3u8 -c copy test.mp4


而串流播放清單中使用 .png 的影片處理起來就比較麻煩,我先解決如何用 FFmpeg 來直接下載串流檔案、去掉會誤導為 PNG 圖片的前 41 bytes。假設串流檔案叫 sample.png,使用底下的指令:


ffmpeg -f data  -protocol_whitelist "subfile,file,http,https,tcp,tls" -start 41 -i subfile:https://xx.xx.xx.xx/sample.png -map 0 -c copy -f data  sample.png.ts


輸入旳參數,去掉前 41 bytes 的關鍵:

  • -start 41 -i subfile:

如果出現 protocol whitelist 關鍵字的錯誤訊息,就再加上:

  • -protocol_whitelist "subfile,file,http,https,tcp,tls"

為了保持原來的編碼,輸入和輸出都加上:

  • -f data

輸出的編碼用 copy 的:

  • -c copy

下載並處理串流檔案的指令搞定了,剩下就是利用 PHP 去分析 index.m3u8 ,產生每一個串流檔案的處理指令,並通通放到一個批次檔裡,這樣就可以一口氣將有檔案下載回來。順便也製作一個帶有 .ts 新檔名的播放清單,方便串流檔案下載回來後,再以 FFmpeg 來合併成 .mp4 影片檔。

目前利用上述的方法,以 FFmpeg 來下載被動過手腳的影片是可行,有空再來研究一下,是不是還有更簡便的方式或工具。

相關文章


沒有留言:

張貼留言

 
雄::gsyan © 2009. Design by Pocket