Python爬取m3u8格式视频并解密ts文件合并转为mp4格式 |
您所在的位置:网站首页 › ts视频如何转为mp4 › Python爬取m3u8格式视频并解密ts文件合并转为mp4格式 |
一. m3u8是什么格式 m3u8是苹果公司推出的视频播放标准,是m3u的一种,只是编码格式采用的是UTF-8。 m3u8准确来说是一种索引文件,使用m3u8文件实际上是通过它来解析对应的放在服务器上的视频网络地址,从而实现在线播放。使用m3u8格式文件主要因为可以实现多码率视频的适配,视频网站可以根据用户的网络带宽情况,自动为客户端匹配一个合适的码率文件进行播放,从而保证视频的流畅度。 它将视频切割成一小段一小段的ts格式的视频文件,然后存在服务器中(现在为了减少I/o访问次数,一般存在服务器的内存中),通过m3u8解析出来路径,然后去请求。 二. 如何处理经过AES-128加密的ts文件 示例链接:https://cdn.letv-cdn.com/2018/12/05/JOCeEEUuoteFrjCg/playlist.m3u8 输入这个链接并不会跳转到源播放地址,而是下载一个.m3u8格式的文件,文件内容一般长这样: #EXTM3U #EXT-X-TARGETDURATION:12 #EXT-X-MEDIA-SEQUENCE:0 #EXT-X-KEY:METHOD=AES-128,URI="https:/*******/**********/hlskey?info=C77821E76077257C9C33DC5901307461&t=1602634262&key=81E7CD7DD2D96CEF9F2B1B18AC2707C9",IV=0xC77821E76077257C9C33DC5901307461 #EXT-X-VERSION:4 #EXTINF:6.756756, out000.ts #EXTINF:10.427089, out001.ts #EXTINF:3.378378, out002.ts #EXTINF:1.126133, ............. out.....ts #EXT-X-ENDLIST将文件中的url中的playlist.m3u8 替换为 out000.ts会下载一个.ts文件,这个ts文件就是视频的一个片段,整个视频由若干个小片段构成,没有经过加密的文件下载后直接可以播放,但经过AES-128加密后的文件下载后会无法播放 我们主要研究的是经过加密的ts文件,并解密它。我们去把 index.m3u8 替换成 key.key,即可获取到加密的密钥,这个密钥 key 将会是我们后续解码文件的关键,没了它下载得到的文件是没有意义的。 因为需要解码 AES-128 这种加密方式需要用到特殊的模块 AES,所以我们要去安装 Crypto,按照如下的方法导入类来使用。可以通过 pip install Crypto 安装 Crypto库,如果发生了 ImportError,显示没有 Crypro 库,那么就去 site-packages 里面看看文件名是不是 crypto,改成 Crypto 应该就没问题了。 下载后的ts文件我们可以使用win自带的 copy /b '下载的文件目录路径'/*.ts ' '合并后的文件目录路径'/new.mp4 来合并ts文件,之后再使用 del *.ts 命令来删除所有的.ts文件,在python中我们可以使用os.system()命令来处理cmd命令 具体代码如下:包括未加密和加密两种处理方式 import requests import os from Crypto.Cipher import AES def m3u8(url): base_url = url[:url.rfind('/')+1]#如果需要拼接url,则启用 , +1 把 / 加上 headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'} rs = requests.get(url,headers=headers).text list_content = rs.split('\n') player_list = [] #如果没有merge文件夹则新建merge文件夹,用于存放ts文件 if not os.path.exists('merge'): os.system('mkdir merge') key = '' for index,line in enumerate(list_content): # 判断视频是否经过AES-128加密 if "#EXT-X-KEY" in line: method_pos = line.find("METHOD") comma_pos = line.find(",") method = line[method_pos:comma_pos].split('=')[1]#获取加密方式 print("Decode Method:", method) uri_pos = line.find("URI") quotation_mark_pos = line.rfind('"') key_path = line[uri_pos:quotation_mark_pos].split('"')[1] key_url = key_path res = requests.get(key_url) key = res.content #获取加密密钥 print("key:", key) #以下拼接方式可能会根据自己的需求进行改动 if '#EXTINF' in line: # href = '' # 如果加密,直接提取每一级的.ts文件链接地址 if 'http' in list_content[index + 1]: href = list_content[index + 1] player_list.append(href) # 如果没有加密,构造出url链接 elif('ad0.ts' not in list_content[index + 1]): href = base_url + list_content[index+1] player_list.append(href) if(len(key)): print('此视频经过加密') print(player_list)#打印ts地址列表 for i,j in enumerate(player_list): cryptor = AES.new(key, AES.MODE_CBC, key) res = requests.get(j,headers=headers) with open('merge/' + str(i+1) + '.ts','wb') as file: file.write(cryptor.decrypt(res.content))#将解密后的视频写入文件 print('正在写入第{}个文件'.format(i+1)) else: print('此视频未加密') print(player_list)#打印ts地址列表 for i,j in enumerate(player_list): res = requests.get(j,headers=headers) with open('merge/' + str(i+1) + '.ts','wb') as file: file.write(res.content) print('正在写入第{}个文件'.format(i+1)) print('下载完成') #当全写下载完之后合并文件并删除所有.ts文件 def merge_ts(): path = os.getcwd() + '\merge'#获取视频存放路径 merge_cmd = 'copy /b ' + path + '\*.ts ' + path + '\\new.mp4' del_cmd = 'del ' + path + '\*.ts' os.system(merge_cmd)#执行合并命令 os.system(del_cmd)#执行删除命令 print('合并完成') if __name__ == '__main__': url = 'https://cdn.letv-cdn.com/2018/12/05/JOCeEEUuoteFrjCg/playlist.m3u8' #下载视频 m3u8(url) #合并视频 merge_ts()
|
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |