m3u8文件內內容
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:12 #EXT-X-MEDIA-SEQUENCE:1 #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.key",IV=0x00000000000000000000000000000001 #EXTINF:11, 00154.ts //ts視頻的路徑一般都是絕對路徑,我這里沒有給出絕對鏈接 #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.key",IV=0x0000000000000000000000000000009B #EXTINF:10, 00155.ts #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.key",IV=0x0000000000000000000000000000009C #EXTINF:11, 00156.ts #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.key",IV=0x0000000000000000000000000000009D #EXTINF:10, 00157.ts
這個是正式的m3u8文件(參看:https://blog.csdn.net/weixin_41624645/article/details/95939510):
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:13 #EXT-X-MEDIA-SEQUENCE:0 //這里是注釋,真實文件里不會有的, //看看你的m3u8文件里有沒有這一行,如果有的話,那么恭喜你這個m3u8文件是加密的,請繼續往下看 //如果沒有這行的話,特別是沒有這個#EXT-X-KEY,那么同樣恭喜你,這個m3u8沒有加密,你直接百度vlc下載合並就行,也可根據本文章進行合並 #EXT-X-KEY:METHOD=AES-128,URI="http://www.example.com/20180125/key.key" #EXTINF:12.5, //下面的這個其實才是視頻真正的地址,你放在瀏覽器地址欄上直接回車是可以直接下載的 //不過這樣的鏈接在m3u8文件里會有很多,建議使用工具下載(迅雷)、ffmpeg、vlc等 //這里還可能出現GBDYO3576000.ts這種情況,其實是把前面的路徑省略了,可根據m3u8文件的路徑自行加上 http://www.example.com/20180125/GBDYO3576000.ts #EXTINF:12.5, http://www.example.com/20180125/GBDYO3576001.ts #EXTINF:12.5, http://www.example.com/20180125/GBDYO3576002.ts
上面這個m3u8文件中有這樣的字段:
#EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.key",IV=0x00000000000000000000000000000001
就證明你這個m3u8內的ts視頻是加密的(意思就是你可以把m3u8內的ts視頻下載,但是因為視頻被加密導致播放器無法播放)
那么我們就需要對ts視頻解密,看上面那個字段的URI的值
URI="E:/CTF/test/key.key"
它的意思就是ts視頻的解密文件鏈接為:
E:/CTF/test/key.key
那我們就把它下載下來。可能這個鏈接不是絕對路徑,那你就去找一下這個網站的路徑,把這個相對路徑加到后面就組成了key.key文件的絕對路徑
下載之后這個時候你就有兩個文件一個是后綴為m3u8文件,里面放置ts視頻絕對路徑。還有一個key.key文件,放置視頻解密所需東西
這個時候你把后綴為m3u8的文件名改為:index.m3u8
這個時候你把key.key的文件名改為:key.m3u8
我們假設你已經把m3u8文件內的所有ts視頻都下載下來了,且ts視頻地址和index.m3u8和key.m3u8文件在同一目錄下
這個時候我們要修改一下m3u8文件內容:
#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:12 #EXT-X-MEDIA-SEQUENCE:1 #EXT-X-PLAYLIST-TYPE:VOD //注意改一下這個URI地址為你電腦上的key.m3u8文件路徑,相對路徑也行 #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.m3u8",IV=0x00000000000000000000000000000001 #EXTINF:11, 00154.ts //注意因為我的ts視頻和index.m3u8文件在同一目錄下,所以我直接寫出ts視頻文件名就行,如果你的視頻和index文件不再一個地方,你給出你本地的絕對地址也行 #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.m3u8",IV=0x0000000000000000000000000000009B #EXTINF:10, 00155.ts #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.m3u8",IV=0x0000000000000000000000000000009C #EXTINF:11, 00156.ts #EXT-X-KEY:METHOD=AES-128,URI="E:/CTF/test/key.m3u8",IV=0x0000000000000000000000000000009D #EXTINF:10, 00157.ts
接下來還需要下載一款工具ffmpeg,下載Static的那個版本就可以,然后配置環境變量Path,在Path后面直接添加你ffmpeg的安裝目錄加上/bin就可以了,安裝完成之后重啟一下,重啟之后打開你index.m3u8所在的文件執行下面命令:
ffmpeg -allowed_extensions ALL -i index.m3u8 -c copy out.mp4
報錯了可執行:
ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,crypto,tcp" -i index.m3u8 -c copy out.mp4
如果這里報錯了,那么打開你的index.m3u8文件,修改URI的路徑為網絡路徑(你下載時的路徑),然后執行
ffmpeg -protocol_whitelist "file,http,crypto,tcp" -i index.m3u8 -c copy out.ts
操作之后合並的視頻就是out.ts
所有index.m3u8的ts視頻都是從00001.ts開始,因為我下載那個總的視頻比較大,所以index.m3u8內的ts小視頻鏈接三百多個,所以我就挑出來了幾個ts鏈接
然后下載了。這個時候你要注意了,因為你只下載了幾個ts視頻,那也就證明index.m3u8內的有些ts視頻你的電腦本地沒有,那么你就要在index.m3u8文件內把這些不存在的刪掉,要不然執行ffmpeg命令會報錯:
[crypto @ 000000000054de40] Unable to open resource: D:\temp\vd201906291\O7rSBp5
l5847008.ts
[hls,applehttp @ 0000000000532c40] Failed to open segment 8 of playlist 0
[hls,applehttp @ 0000000000532c40] Error when loading first segment ‘D:\temp\vd2
01906291\O7rSBp5l5847000.ts’
D:\temp\vd201906291\tsmaster.m3u8: Invalid data found when processing input
最主要的原因就是因為m3u8中本地文件的路徑寫錯了啦,所以會提示無效數據。正確的路徑寫法見上一篇文章。如果還是這個提示,就請檢查一下這些文件是不是都存在啦。
因為有的index.m3u8文件內ts視頻很多,我們手動下載要累死,那么我們可以使用python通過多線程來加速下載
使用下面這個代碼,你需要在python文件同目錄下提供一個index.m3u8文件就可以了
代碼就會根據index.m3u8內的ts視頻絕對鏈接,進行下載
import requests,os,threading def getTsUrl(): ts_url_list = [] # baseUrl = "https://ycalvod.yicai.com/record/live" with open("qwe.m3u8", "r", encoding="utf-8") as f: m3u8Contents = f.readlines() for content in m3u8Contents: if content.endswith("ts\n"): ts_Url = content.replace("\n", "").replace("..", "") ts_url_list.append(ts_Url) # print(ts_Url) return ts_url_list def download_ts_video(download_path, ts_url_list,start,last): # download_path = r"C:\Users\Administrator\Desktop\AiShu\下載視頻\TS視頻" for i in range(start,last): ts_url = ts_url_list[i] try: response = requests.get(ts_url, stream=True, verify=False) except Exception as e: print("異常請求:%s" % e.args) return name = ts_url.split('_')[-1].strip() # 截取ts鏈接的最后一部分,結果為00001.ts ts_path = download_path + "\{}".format(name) with open(ts_path, "wb+") as file: for chunk in response.iter_content(chunk_size=1024): if chunk: file.write(chunk) def main(total,block,total_vedio): # 啟動多線程 start = 0 thread_list = [] # 線程存放列表 for i in range(total): if start + block > total_vedio: t = threading.Thread(target=download_ts_video, args=(download_path,ts_url_list ,start, total_vedio,)) else: t = threading.Thread(target=download_ts_video, args=(download_path,ts_url_list,start , start + block,)) start += block t.setDaemon(True) thread_list.append(t) for t in thread_list: t.start() for t in thread_list: t.join() if __name__ == '__main__': download_path = r"E:/CTF/test" # 視頻保存在本地的地址 total = 20 # 線程總數 ts_url_list = getTsUrl() # 獲取所有ts鏈接 block = int(len(ts_url_list) / total) # 一共有total個線程,那么平均給每一個線程多少個下載任務 if len(ts_url_list) % total != 0: block += 1 main(total,block,len(ts_url_list)) # download_ts_video(download_path, ts_url_list) # print(ts_url_list)
因為最后index.m3u8文件內的鏈接都要改成本地鏈接,一個一個改起來太慢,我使用的是notepad++,這個軟件有個工具替換,可以一次改完
ts鏈接的前面基本上都一樣,你可以把ts視頻絕對鏈接前面一部分選中,把它替換為空,那么文件名就是00001、00002、00003......類型的了
運行結果:
這是個警告,如果你想處理的話,你可以在請求代碼前添加如下代碼即可:
如果想要截圖視頻,可以通過以下命令(參考鏈接為:https://blog.csdn.net/huangxingli/article/details/46663143):
ffmpeg -i ./plutopr.mp4 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 ./cutout1.mp4 -y
合並視頻:先弄一個filelist.txt文件
file 'D:\delphisr\騰訊下載地址解析子串\k0028qzpkdl.321002.1.ts' file 'D:\delphisr\騰訊下載地址解析子串\k0028qzpkdl.321002.2.ts' file 'D:\delphisr\騰訊下載地址解析子串\k0028qzpkdl.321002.3.ts' file 'D:\delphisr\騰訊下載地址解析子串\k0028qzpkdl.321002.4.ts'
然后進入這個目錄執行下面這個命令:
ffmpeg -f concat -safe 0 -i filelist.txt -c copy out.mp4