Python 神器:一键下载 M3U8 并转换为 MP4
Python 神器:一键下载 M3U8 并转换为 MP4
M3U8 是一种常见的媒体播放文件格式,通常用于视频流的播放,例如通过 HTTP Live Streaming (HLS) 协议传输的视频流。本文将介绍如何使用 Python 下载 M3U8 文件中的所有视频片段,并将它们合并为一个 MP4 文件。
一、前期准备
1. 安装依赖
我们需要使用几个 Python 库来实现下载和合并 M3U8 文件中的视频片段。最主要的库包括 m3u8
(用于解析 M3U8 文件)和 ffmpeg
(用于视频合并和转码)。同时,我们还需要 requests
库来下载 M3U8 文件中的 TS 视频片段。
首先,安装依赖库:
pip install m3u8 requests
安装 ffmpeg(用于视频处理):
- 对于 Windows 用户,可以从 FFmpeg官网 下载并安装。
对于 MacOS 用户,可以使用 Homebrew 安装:
brew install ffmpeg
对于 Linux 用户,可以使用 apt-get 安装:
sudo apt install ffmpeg
二、M3U8 下载与转换实现
1. 下载 M3U8 文件并解析
M3U8 文件实际上包含了视频的索引信息,指示了所有的 .ts
文件(视频片段)的位置。我们可以用 m3u8
库来解析 M3U8 文件,获取其中的视频片段 URL。
import m3u8
import os
import requests
def download_m3u8(m3u8_url, download_folder):
"""
下载并解析 M3U8 文件
:param m3u8_url: M3U8 文件 URL
:param download_folder: 下载的文件保存目录
:return: 视频片段 URL 列表
"""
# 解析 M3U8 文件
playlist = m3u8.load(m3u8_url)
ts_urls = []
# 遍历 M3U8 中的每个片段 URL
for segment in playlist.segments:
ts_urls.append(segment.uri)
# 下载视频片段
if not os.path.exists(download_folder):
os.makedirs(download_folder)
ts_files = []
for idx, ts_url in enumerate(ts_urls):
ts_filename = os.path.join(download_folder, f"segment{idx + 1}.ts")
ts_files.append(ts_filename)
print(f"正在下载:{ts_url}")
response = requests.get(ts_url, stream=True)
with open(ts_filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print("所有视频片段下载完成!")
return ts_files
# 示例用法
m3u8_url = "https://example.com/video.m3u8"
download_folder = "downloaded_video"
ts_files = download_m3u8(m3u8_url, download_folder)
2. 合并 TS 文件并转换为 MP4
下载所有的 .ts
文件后,我们可以使用 ffmpeg
来将这些视频片段合并成一个 MP4 文件。
import subprocess
def ts_to_mp4(ts_files, output_file):
"""
使用 ffmpeg 将多个 TS 文件合并并转换为 MP4
:param ts_files: TS 文件路径列表
:param output_file: 输出的 MP4 文件路径
"""
# 生成合并文件的文本
merge_file = "merge_list.txt"
with open(merge_file, "w") as f:
for ts_file in ts_files:
f.write(f"file '{ts_file}'\n")
# 使用 ffmpeg 合并 TS 文件
command = f"ffmpeg -f concat -safe 0 -i {merge_file} -c copy {output_file}"
print(f"正在合并视频文件到 {output_file}...")
subprocess.run(command, shell=True)
# 删除临时合并文件列表
os.remove(merge_file)
print(f"视频已成功合并为: {output_file}")
# 示例用法
output_file = "output_video.mp4"
ts_to_mp4(ts_files, output_file)
3. 完整代码实现
将上述代码整合,得到一个完整的脚本,用于下载 M3U8 文件中的视频片段,并合并为 MP4 文件。
import m3u8
import os
import requests
import subprocess
def download_m3u8(m3u8_url, download_folder):
playlist = m3u8.load(m3u8_url)
ts_urls = []
for segment in playlist.segments:
ts_urls.append(segment.uri)
if not os.path.exists(download_folder):
os.makedirs(download_folder)
ts_files = []
for idx, ts_url in enumerate(ts_urls):
ts_filename = os.path.join(download_folder, f"segment{idx + 1}.ts")
ts_files.append(ts_filename)
print(f"正在下载:{ts_url}")
response = requests.get(ts_url, stream=True)
with open(ts_filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
print("所有视频片段下载完成!")
return ts_files
def ts_to_mp4(ts_files, output_file):
merge_file = "merge_list.txt"
with open(merge_file, "w") as f:
for ts_file in ts_files:
f.write(f"file '{ts_file}'\n")
command = f"ffmpeg -f concat -safe 0 -i {merge_file} -c copy {output_file}"
print(f"正在合并视频文件到 {output_file}...")
subprocess.run(command, shell=True)
os.remove(merge_file)
print(f"视频已成功合并为: {output_file}")
if __name__ == "__main__":
m3u8_url = "https://example.com/video.m3u8" # M3U8 文件 URL
download_folder = "downloaded_video" # 下载文件夹
output_file = "output_video.mp4" # 输出 MP4 文件
ts_files = download_m3u8(m3u8_url, download_folder)
ts_to_mp4(ts_files, output_file)
四、效果展示
- 输入:M3U8 文件 URL,如
https://example.com/video.m3u8
。 - 输出:一个 MP4 文件,包含合并后的完整视频。
五、注意事项
- M3U8 文件的格式:M3U8 文件中可以有不同的质量版本,可能需要选择合适的版本来下载。
- 视频大小:M3U8 通常是大视频流的分割文件,下载时需要稳定的网络连接。
- ffmpeg 配置:确保
ffmpeg
已正确安装并在系统环境变量中。
六、总结
通过本文的教程,你可以轻松实现一键下载 M3U8 文件中的所有视频片段,并将它们合并为一个 MP4 文件。这个工具适用于需要下载和处理 HLS 流的场景,操作简便且高效。
评论已关闭