0.前言
m3u8是一種很常見的網頁視頻播放器的視頻源,比如說中國大學MOOC中課程就是使用了該種視頻格式。
隨便打開一門課程,就可以發現在網絡請求中存在一個m3u8的文件,在preview中預覽,它並不像我們想象中是亂碼的視頻流。
里面是一個列表,有一堆ts結尾的文件名,每個下面還跟了一個EXTINF的字段,好像是時間,在我們播放視頻時,網絡請求中會不斷出現請求ts的內容。
隨便打開一個ts文件,它的內容卻是如圖視頻流一般亂碼的。
說到這里,你可能有猜測了,m3u8並不是視頻流的文件,而有可能是組織ts文件的規范,EXTINF代表播放每多少秒去請求下一片ts流。
這種邊看邊加載的方法無疑可以減少我們的網絡負荷。
要用爬蟲爬取這類視頻的方法也很簡單,我們只需要獲得m3u8文件,就可以得到視頻的ts地址了,將所有ts請求下來之后進行合並,就可以得到視頻文件了。
不過要提的一點是,很多視頻網站會對他們的ts進行加密,我們下載下來合並之后可能視頻能看,但是播放器放着放着就卡住了,然后之后黑屏畫面。
1.編碼部分
我們先根據m3u8來判斷一下創建咋樣一個代表M3U8視頻對象的類。
我們首先需要定義一個list,來存放這個m3u8視頻下所有的ts文件,也就是后面說到的TS類。
這里提一點,m3u8里面的ts的路徑一般對路徑,會和m3u8在同一文件夾,我們代碼中也是這么認為了,但是難免有些網站會單獨存放m3u8和ts文件,如果遇到這種情況,修改一下代碼即可。
有了ts的名稱,我們還需要URL的前綴,也就是圖中紫色划線部分,也就是basepath。
此外,我們還需要一個TS對象。
這個對象中存儲TS文件名稱以及時間EXTINF。
定義完實體類,就需要編寫下載視頻的過程了。
首先需要請求到m3u8的文件,此處使用Java的HttpURLConnection來請求獲取,其它語言類似,只需要請求到文件即可。
請求到了m3u8的文本內容,我們還需要解析它 ,從中得到ts的名稱。
得到了M3U8視頻對象之后,我們就可以遍歷請求它的list中TS對象的名稱屬性來下載ts文件了。
這么多ts文件如果我們在單線程中遍歷請求,會很耗費時間,Java給我們提供了Stream,其中parallel可以讓我們並發去遍歷集合,效率會提升不少。
依舊是使用HttpURLConnection來做請求,不過最好本次設置超時時間。
這樣就可以請求到所有ts文件了。
最后要做的就是合並這些ts文件成為一個MP4文件。
對於未加密的正常ts文件,我們只需要按照編號順序直接拼接即可。
這樣就算是完成了M3U8視頻抓取了。
2.打包使用
下載地址:https://github.com/CasterWx/resources/releases/tag/1.0.1
在命令行中java -jar m3u8-down.jar [m3u8地址]
,會顯示報錯信息。
也可以直接m3u8-down.jar [m3u8地址]
,不會顯示保存信息,會在后台執行。
最終會在同目錄下生成一個output.mp4的文件,temp文件可以刪除。