将m3u8下载为MP4文件,Python 实现
在线看都某个不错的视频,便想把它下载下来。
看下开发者工具,发现是m3u8格式视频,该视频是不能像其他视频那样一键另存了。

m3u8是HTTP Live Streaming (HLS)的播放列表格式,通常用于视频分段传输。
该文件格式通常为如图所示,具体格式不做说明了,其中视频片段文件为这些 *ts。

要下载视频数据,只需先解析m3u8文件,获取所有的ts片段链接,然后下载这些片段,最后合并成mp4文件即可了。
使用m3u8_To_MP4实现
如果使用第三方依赖:m3u8_To_MP4,可以非常快捷实现:
import m3u8_To_MP4
if __name__ == '__main__':
# 1. Download videos from uri.
m3u8_To_MP4.multithread_download('http://videoserver.com/playlist.m3u8')
# 2. Download videos from existing m3u8 files.
m3u8_To_MP4.multithread_file_download('http://videoserver.com/playlist.m3u8',m3u8_file_path)
# For compatibility, i reserve this api, but i do not recommend to you again.
# m3u8_To_MP4.download('http://videoserver.com/playlist.m3u8')
来自:https://pypi.org/project/m3u8-To-MP4/
使用前提需要安装:python -m pip install m3u8_To_MP4
纯 Python 实现
有时候不想搞太多的第三方依赖,纯 Python 实现实现也没有几行代码,手闲也搞一个。
import argparse
import requests
# 解决Python3 控制台输出InsecureRequestWarning的问题
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def print_used():
print("python3 m3u8_to_mp4.py -i m3u8_file -o save_mp4_file")
print(' example 1:python3 m3u8_to_mp4.py -i http://127.0.0.1:8001/index.m3u8 -o ./1.mp4')
def parse_param():
parser = argparse.ArgumentParser(description="")
parser.add_argument("-i")
parser.add_argument("-o")
args = parser.parse_args()
return args.i, args.o
def main():
_input, _output = parse_param()
if not _input or not _output:
print_used()
exit()
# 获取m3u8文件数据
html = requests.get(_input, verify=False)
m3u8_content = html.content.decode()
src = _input[:_input.rfind("/")+1]
if m3u8_content.find("#EXTM3U") == -1:
print("not a m3u8 file")
exit()
# 解析出ts文件
m3u8_content = m3u8_content.replace("\r\n", "\n").replace("\r", "\n")
lines = list(filter(lambda line: line.endswith(".ts"), m3u8_content.split("\n")))
# 下载ts合并到目标文件去
out_file = open(_output, "wb")
for i in range(len(lines)):
line = lines[i] if lines[i].startswith("http") else src+lines[i]
print("(%d/%d)loading:%s, " % (i+1, len(lines), line))
ts = requests.get(line, verify=False)
out_file.write(ts.content)
if __name__ == "__main__":
main()
有些网站,其ts 数据是加密的。这类型的视频,会在m3u8文件内注明解密密钥地址数据,需要额外处理一下,但这种较少,就不考虑了。
使用方法:
python3 m3u8_to_mp4.py -i https://网站地址/xxx.m3u8 -o ./视频名字.mp4
(全文完)
(欢迎转载本站文章,但请注明作者和出处 编程想法 – Yuccn )