三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

m3u8下载从零到一:用m3u8_downloader快速保存HLS视频的5步实操指南

m3u8下载从零到一:用m3u8_downloader快速保存HLS视频的5步实操指南

m3u8下载从零到一:用m3u8_downloader快速保存HLS视频的5步实操指南

【免费下载链接】m3u8_downloaderm3u8(HLS流)下载,实现了AES解密、合并、多线程、批量下载项目地址: https://gitcode.com/gh_mirrors/m3/m3u8_downloader

浏览器里只给播放、不给下载的视频,八成走的是 HLS 流媒体协议——视频被切成一堆几百 KB 的小分片,靠一份.m3u8播放列表按顺序播放。想在本地得到完整 mp4,就需要一款 m3u8下载工具:m3u8_downloader 正是为这件事而生,它自动完成 AES 解密、多线程拉取分片、合并与转封装,还能批量排队下载。

先弄明白:m3u8 链接背后藏着什么

一份播放列表,几百个分片

用记事本打开.m3u8文件,你会看到一行行#EXTINF和分片地址。播放器就是照着这份清单,把.ts分片一个接一个拉下来播。所以"下载 m3u8 视频"本质上只有三件事:取清单、按清单拉全部分片、把分片拼起来

AES-128 加密:多出来的一把"钥匙"

不少站点的分片是加密的,播放列表里会额外声明#EXT-X-KEY:METHOD=AES-128,并给出一个 key 文件的地址。m3u8_downloader 会自动去取这把钥匙,在合并阶段边解密边写入。注意:它只认 AES-128 这一种加密方式,遇到其他加密会直接打印"不支持的解密方式"并放弃该任务。

出发前,把三件行李备好

1. 装齐 5 个依赖库

pip install beautifulsoup4 m3u8 pycryptodome requests threadpool

一句话解释各司其职:m3u8负责解析播放列表,pycryptodome提供 AES 解密算法,requests发 HTTP 请求,threadpool管理并发线程。

2. 拿到代码

git clone https://gitcode.com/gh_mirrors/m3/m3u8_downloader

3. 确认 lib/ 目录里躺着 ffmpeg

合并出的中间文件是 flv 容器,最后一步要靠lib/下的 ffmpeg 转封装成 mp4。这里用的是-vcodec copy -acodec copy直通复制,不重新编码,所以转换快得几乎感知不到。仓库已附带 Windows 版ffmpeg.exe和 mac/Linux 版ffmpeg。⚠️ 有个容易踩的坑:源码默认命令是.\lib\ffmpeg(Windows 风格),在 Linux 上跑会找不到文件,需要把源码第 262 行的.\改成./

第一次跑通:5 步就能看到进度条

第 1 步:写输入清单

新建一个 UTF-8 编码的 txt,每行一条,固定格式为视频名称|m3u8链接

Python入门课|https://example.com/course/index.m3u8 机器学习实战|https://example.com/ml/index.m3u8

第 2 步:改顶部 5 个配置项

打开m3u8_downloader.py,文件顶部的配置区就 5 行,一眼能看懂:

配置项默认值含义
m3u8InputFilePathD:/input/m3u8_input.txt清单文件路径
saveRootDirPathD:/output最终 mp4 存放目录
errorM3u8InfoDirPathD:/output/error.txt失败任务记录文件
m3u8TryCountConf10m3u8 与 key 的下载重试次数
processCountConf50同时下载的分片线程数

第 3 步:在终端里跑,别在 IDE 里跑

python m3u8_downloader.py

建议用系统终端直接运行——源码开头就注明:在 PyCharm 这类 IDE 里执行看不到动态刷新的进度条效果。

第 4 步:盯住动态进度条

程序会依次打印 5 个阶段:下载 m3u8 → 获取 key → 下载 ts → 合并 ts → 转 mp4。下载分片时进度条实时刷新,形如345/500 ■■■□□ 69.00% 2.34MiB/s。当方块占满、网速归零,基本就快收工了。

第 5 步:验收输出目录

下载成功后会看到saveRootDirPath/视频名称.mp4。下载过程的中转分片都堆在cache/目录,完成后自动清理,只剩一份log.log记录本次全部操作。视频名称里的\ / : * ? " < > |等字符会被自动替换成空格,避免 Windows 文件命名报错。

出问题别慌,按这 4 个方向排查

  1. 清单没生效:终端第一行提示"文件不存在"?确认路径写对、文件确实是 UTF-8 编码。
  2. m3u8 反复下载失败:程序会重试 10 次,仍失败会把任务以视频名,链接追加进 error.txt。多数情况是链接过期或服务器需要特定 Referer,先用浏览器确认链接还能打开。
  3. 分片合并失败:多半是 ffmpeg 没跑起来。检查lib/目录、确认 Linux 下路径已改成./lib/ffmpeg,也可以把转换命令复制到终端手动执行看报错。
  4. 进度长时间不动:去cache/log.log里看对应分片的记录。工具对单个分片是无限重试的,若某个分片一直报错,通常是服务器限流或网络抖动,调小线程数再跑一轮。

进阶:把工具调到适合你的网络

线程数怎么调

processCountConf = 50是作者给的"高速档",但未必适合所有人:

网络环境推荐线程数原因
低速/移动网络10~20避免并发打满带宽反而拖慢
中等带宽20~40速度与稳定兼顾
高速宽带/机房服务器40~60榨干带宽,注意别触发服务器限流

重试与超时策略的两处细节

  • 重试分两档:m3u8 和 key 最多试 10 次(m3u8TryCountConf),而 ts 分片是无限重试直到成功——因为分片数量多、单个体积小,无限重试对最终成功率的收益远高于放弃。
  • 超时也分档:m3u8/key 请求超时 20 秒,分片只给 5 秒。这解释了为什么偶尔能看到单个分片重试:5 秒没响应就判定失败重来。

源码里值得细读的三处设计

  • 多级码流自动跳转getM3u8Info()检测到 variant 流(一个 m3u8 里套着多个码率的子 m3u8)时,会递归找第一条.m3u8子列表,也就是默认选了"第一个档位"。
  • 分片完整性校验:每次响应都会比对Content-Length与实际字节数,短斤少两就抛异常重下,从源头避免拼出花屏视频。
  • AES-128-CBC 解密:key 声明了 IV 就用 IV,没声明就用 key 自身当 IV,完全贴合 HLS 规范,这也是它能通吃大多数加密站点的原因。

下一步你可以试试

  • 批量囤一个课程:把几十节课的 m3u8 链接一次性写进清单,睡前挂上,第二天早上验收整个目录,体验一把"无人工批量下载"。
  • 研究 variant 流选择逻辑:现在默认取第一条子流,如果你希望固定选最高码率,可以改getM3u8Info()里寻找.m3u8的循环,是很不错的练手切入点。

最后照例提醒一句:这套工具请只用于下载你拥有合法访问权限的内容,尊重版权,别碰盗版和非法传播——技术本身没有立场,用在哪才是关键。

【免费下载链接】m3u8_downloaderm3u8(HLS流)下载,实现了AES解密、合并、多线程、批量下载项目地址: https://gitcode.com/gh_mirrors/m3/m3u8_downloader

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

← 返回列表