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