Python爬虫入门教程 51-100 Python3爬虫通过m3u8文件下载ts视频-Python爬虫6操作
程序员文章站
2022-04-14 18:27:06
什么是m3u8文件 M3U8文件是指UTF 8编码格式的 。 是记录了一个 , 打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。 原视频数据分割为很多个TS流,每个TS流的地址记录在m3u8文件列表中 比如我这里有一个m3u8文件,文件内容如下 EXTM3U ......
什么是m3u8文件
m3u8文件是指utf-8编码格式的m3u文件
。m3u文件
是记录了一个索引纯文本文件
,
打开它时播放软件并不是播放它,而是根据它的索引找到对应的音视频文件的网络地址进行在线播放。
原视频数据分割为很多个ts流,每个ts流的地址记录在m3u8文件列表中
比如我这里有一个m3u8文件,文件内容如下
#extm3u #ext-x-version:3 #ext-x-media-sequence:0 #ext-x-allow-cache:yes #ext-x-targetduration:15 #extinf:6.916667, out000.ts #extinf:10.416667, out001.ts #extinf:10.416667, out002.ts #extinf:1.375000, out003.ts #extinf:1.541667, out004.ts #extinf:7.666667, out005.ts #extinf:10.416667,
ts 文件一般怎么处理
- 只有m3u8文件,需要下载ts文件
- 有ts文件,但因为被加密无法播放,需要解码
- ts文件能正常播放,但太多而小,需要合并
本篇文章处理第1和第2条内容,加密部分跳过。
上面我提供的ts文件中并没有加密,也就是没有关键字key
,下载ts文件之后直接合并即可
ts文件路径获取
由于上面的m3u8文件中所有的ts文件都是相对地址,所以需要依据中获取到的链接
{'url': 'https://videos5.jsyunbf.com/2019/02/07/iqx7y3p1dleahiv7/playlist.m3u8', 'ext': 'dplay', 'msg': 'ok', 'playertype': none}
其中前面的部分是ts的播放地址的前缀地址
# https://videos5.jsyunbf.com/2019/02/07/iqx7y3p1dleahiv7/out005.ts import datetime import requests # m3u8是本地的文件路径 def get_ts_urls(m3u8_path,base_url): urls = [] with open(m3u8_path,"r") as file: lines = file.readlines() for line in lines: if line.endswith(".ts\n"): urls.append(base_url+line.strip("\n")) return urls
ts文件下载
所有的路径读取完毕之后,需要对ts文件进行下载,文件的下载办法很多
def download(ts_urls,download_path): for i in range(len(ts_urls)): ts_url = ts_urls[i] file_name = ts_url.split("/")[-1] print("开始下载 %s" %file_name) start = datetime.datetime.now().replace(microsecond=0) try: response = requests.get(ts_url,stream=true,verify=false) except exception as e: print("异常请求:%s"%e.args) return ts_path = download_path+"/{0}.ts".format(i) with open(ts_path,"wb+") as file: for chunk in response.iter_content(chunk_size=1024): if chunk: file.write(chunk) end = datetime.datetime.now().replace(microsecond=0) print("耗时:%s"%(end-start))
下载过程显示,表示下载成功,剩下的就是拼网速的时候了。
下载完毕,是一大堆ts文件,记住,只要一个可以看,就可以合并了
合并ts文件
使用copy命令
如果不清楚,就去百度即可
copy/b d:\newpython\doutu\sao\ts_files\*.ts d:\fnew.ts
代码合并
import os from os import path def file_walker(path): file_list = [] for root, dirs, files in os.walk(path): # 生成器 for fn in files: p = str(root+'/'+fn) file_list.append(p) print(file_list) return file_list def combine(ts_path, combine_path, file_name): file_list = file_walker(ts_path) file_path = combine_path + file_name + '.ts' with open(file_path, 'wb+') as fw: for i in range(len(file_list)): fw.write(open(file_list[i], 'rb').read()) if __name__ == '__main__': #urls = get_ts_urls("playlist.m3u8","https://videos5.jsyunbf.com/2019/02/07/iqx7y3p1dleahiv7/") #download(urls,"./tsfiles") combine("./ts_files","d:/ts","haha")
最终合并之后,形成一个ts文件,当然你还可以用软件把视频转换成mp4格式
也可以利用ffmpeg可以直接实现m3u8 转mp4
愉快的下载下来看vip视频吧
备注部分
m3u8文件中的 m3u8标签与属性说明
#extm3u 每个m3u文件第一行必须是这个tag,请标示作用 #ext-x-version:3 该属性可以没有 #ext-x-media-sequence:140651513 每一个media uri在playlist中只有唯一的序号,相邻之间序号+1, 一个media uri并不是必须要包含的,如果没有,默认为0 #ext-x-targetduration 指定最大的媒体段时间长(秒)。所以#extinf中指定的时间长度必须小于或是等于这 个最大值。这个tag在整个playlist文件中只能出现一 次(在嵌套的情况下,一般有 真正ts url的m3u8才会出现该tag) #ext-x-playlist-type 提供关于playlist的可变性的信息,这个对整个playlist文件有效,是可选的,格式 如下:#ext-x-playlist-type::如果是vod,则服务器不能改变playlist 文件; 如果是event,则服务器不能改变或是删除playlist文件中的任何部分,但是可以向该 文件中增加新的一行内容。 #extinf duration指定每个媒体段(ts)的持续时间(秒),仅对其后面的uri有效,title是 下载资源的url #ext-x-key 表示怎么对media segments进行解码。其作用范围是下次该tag出现前的所有media uri,属性为none 或者 aes-128。none表示 uri以及iv(initialization vector)属性必须不存在, aes-128(advanced encryptionstandard)表示uri 必须存在,iv可以不存在。 #ext-x-program-date-time 将一个绝对时间或是日期和一个媒体段中的第一个sample相关联,只对下一个meida uri有效,格式如#ext-x-program-date-time: for example: #ext-x-program-datetime:2010-02-19t14:54:23.031+08:00 #ext-x-allow-cache 是否允许做cache,这个可以在playlist文件中任意地方出现,并且最多出现一次,作 用效果是所有的媒体段。格式如下:#ext-x-allow-cache: #ext-x-endlist 表示playlist的末尾了,它可以在playlist中任意位置出现,但是只能出现一个,格 式如下:#ext-x-endlist
上一篇: 最短路算法分析
下一篇: python-分叉树枝