M3U8Grab:免费 M3U8/HLS 流下载器(Windows/macOS/Linux 三端)

把一整条 m3u8 流——每一个清晰度、每一条音频轨、每一条字幕——下载到一个完全自洽的本地文件夹。配套 ZWServe,一条命令起的本地 CORS 服务器,无需额外配置即可把结果丢进任何支持 HLS 的播放器(如 ZWPlayer)播放。

下载(预编译,免安装):

M3U8Grab(下载器):

ZWServe(本地播放服务器):

免费 · 开源单文件 · 无广告 · 免登录 · 全程不上传


痛点:m3u8 流没法直接另存为

现在主流视频网站都用 HLS 方式分发内容——一个 .m3u8 播放列表,背后指向成百上千个 .ts 小分片。播放器边看边拉。这对在线观看很好,但带来几个问题:

  • 你没法"右键 → 保存"把视频存下来。
  • 源一旦下线,视频就永远没了。
  • 没法离线观看、归档,也没法按自己的节奏学习字幕内容。
  • 普通下载工具往往只抓单个清晰度,还悄悄丢掉了字幕轨和音频轨。

M3U8Grab 解决这个问题。它把整棵 HLS 树完整镜像下来——master 播放列表、每个码率变体、每条音频轨、每条字幕轨、每个解密密钥——然后把所有引用改写成本地路径。最终得到一个不再依赖原始服务器的自洽文件夹;用配套的 ZWServe 在本地起一个服务,就能在任何支持 HLS 的播放器里播放。

M3U8Grab 如何处理分片与加密流(m3u8 抓取原理)

给它一个 master .m3u8 地址,它会:

  1. 发现 所有被引用的播放列表(变体、音频、字幕)并下载。
  2. 改写 每一个 URI="..." 和分片引用为本地相对路径(相对 该播放列表自身所在目录,保证引用不错位)。
  3. 并发下载 全部分片/密钥/字幕,最后告诉你应该打开哪个文件来播放。

输出完全自洽——每个引用都指向本地文件,不再依赖原始服务器。播放时用 ZWServe(见下文)通过 HTTP 把这个文件夹提供出来,再把 master 播放列表地址粘进播放器即可,无需连接原始源站。

加密 m3u8(AES-128)? 对于标准的 #EXT-X-KEY AES-128 加密(非 DRM),M3U8Grab 会获取播放列表引用的密钥文件,并把其 URI 改写为本地路径。加密的分片按原样存储;符合标准的播放器会在播放时用本地可用的密钥解密。DRM 保护的流(Widevine、PlayReady、FairPlay)不在支持范围内,因为其密钥无法作为普通文件获取。

已经有这么多 m3u8 下载器,为什么还要做 M3U8Grab?

大多数 m3u8 下载工具的设计目标是产出单个输出文件(通常是 MP4):选取一个分辨率,合并或转封装分片,再丢弃其余内容。这适合"事后观看"的场景,但会移除播放测试与开发所需的全部信息。

M3U8Grab 采用不同的方式:按服务器下发的结构镜像 HLS,不合并、不转封装,使下载得到的目录在本地提供时能复现原始流的行为。保留的内容包括:

  • 全部码率变体——master 播放列表和每个变体都保留,可测试自适应码率(ABR)切换,而非仅一个固定分辨率。
  • 全部音频轨——主音轨、音频描述轨、多语言轨保留在各自的播放列表中,与原始结构一致。
  • 全部字幕轨——VTT/WebVTT 文件下载下来并保持与播放列表的引用关系,可验证多语言字幕行为。
  • #EXT-X-KEY 引用的密钥文件——对于 AES-128 加密(非 DRM)的流,密钥文件会被获取,其 URI 改写为本地路径,使符合标准的播放器能在播放时解密分片。(此方式适用于标准 EXT-X-KEY AES-128;Widevine/PlayReady/FairPlay 等 DRM 保护的流不在范围内,因为其密钥无法作为普通文件获取。)
  • 原始播放列表结构——master 播放列表 + 变体播放列表 + 分片,每个引用改写为本地相对路径,不合并为单个容器。

最终得到的是一个自洽的 HLS 树,通过 HTTP 提供时行为与直播流一致。适用于:针对真实流做播放器回归测试、离线复现播放或 CORS 问题、验证多轨与字幕处理,或构建不依赖源服务器在线的可复现测试夹具。M3U8Grab 不合并成 MP4;完整的原始结构被保留,以便测试。

核心特性

特性 说明
完整镜像 master + 全部码率 + 全部音频轨 + 全部字幕轨 + 密钥,一个都不丢。
可离线播放 所有引用改写为本地路径,文件夹完全自洽。
跨域支持 不受浏览器 CORS 限制,资源即使与 master 不同 host 也能抓取(映射到 external/<host>/...)。
断点续传 重跑时自动跳过已存在且非空的文件,只补缺。
原子写入 每个分片先写到 .part 临时文件,完整后才改名,杜绝半截文件。
失败重试 单文件最多 5 次重试,指数退避(0.5s/1s/1.5s/2s/2.5s)。
高并发 默认 16 个 worker,可用 -workers 调整。
零依赖 预编译二进制自包含,无需任何运行时环境——下载即用。
文件名清洗 自动剔除 Windows 非法字符,同一文件夹在三大平台都能用。

三端使用说明

先下载对应系统的二进制,然后:

Windows

双击不弹交互界面,请在保存 .exe 的目录里打开 PowerShell命令提示符

# 下载到一个名为 myvideo 的文件夹
.\m3u8grab-win.exe -url "https://example.com/vod/master.m3u8" -out "myvideo"

macOS(Apple Silicon)

chmod +x m3u8grab-macos
./m3u8grab-macos -url "https://example.com/vod/master.m3u8" -out "myvideo"

首次运行 macOS 可能拦截未签名二进制。右键 → 打开 → 确认;或先执行一次 xattr -d com.apple.quarantine m3u8grab-macos

Linux

chmod +x m3u8grab-linux
./m3u8grab-linux -url "https://example.com/vod/master.m3u8" -out "myvideo"

命令行参数

参数 默认值 说明
-url (必填) master m3u8 地址(支持 http/https,支持跨域引用)
-out (必填) 本地输出目录(不存在会自动创建)
-workers 16 并发下载数
-force false 强制重新下载,忽略已存在的本地文件
-insecure false 跳过 TLS 证书校验(仅用于自签名 / 内网 CDN)
-H "K: V" 自定义请求头(可重复)。设置 Referer/Origin/User-Agent 以匹配服务端的来源/Referer 校验。
-h 显示使用说明

常用示例

# 自定义地址 + 输出目录,并提高并发
./m3u8grab-win.exe -url "https://.../master.m3u8" -out "media/v" -workers 32

# 中断后继续——直接重跑即可,已下载的分片会自动跳过
./m3u8grab-win.exe -url "https://.../master.m3u8" -out "media/v"

# 强制全量重新下载
./m3u8grab-win.exe -url "https://.../master.m3u8" -out "media/v" -force

# 自签名证书的内网流
./m3u8grab-win.exe -url "https://internal-cdn/master.m3u8" -out "media/v" -insecure

# 匹配服务端的来源/Referer 校验(-H 可重复使用)
./m3u8grab-win.exe -url "https://.../master.m3u8" -out "media/v" \
  -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36" \
  -H "Referer: https://example.com/" \
  -H "Origin: https://example.com"

输出目录结构

运行后会得到一个镜像了整条流的文件夹:

myvideo/
├── master.m3u8            ← 播放入口,打开这个
├── manifest0/             ← 视频 270p  (index.m3u8 + index*.ts)
├── manifest1/             ← 视频 360p
├── manifest2/             ← 视频 480p
├── manifest3/             ← 视频 720p
├── manifest4/             ← 视频 1080p
├── manifest5/             ← 音频 64k Main
├── manifest6/             ← 音频 128k Main
├── manifest9/             ← 字幕 en  (captions.en.m3u8 + *.webvtt)
├── manifest10/            ← 字幕 sv
└── external/<host>/...    ← 跨域资源(如有)

跨 host 的资源会落到 external/<host>/...,其播放列表引用也会改写为指向该本地路径。

播放:用 ZWServe 起服务 + ZWPlayer 打开

你已经下载了一个完整、自洽的 HLS 文件夹。怎么看? 分两步:先用 ZWServe 通过 HTTP 把文件夹提供出来,再把地址粘进 ZWPlayer 这款免费、免安装的在线播放器。

为什么需要服务器?HLS 播放器(如 ZWPlayer)通过 fetch/XHR 拉取 m3u8 播放列表和 .ts 分片,用 file:// 协议直接打开根本不工作;而且在线播放器跑在 zwplayer.com 域,访问你本机的内容属于跨域请求,必须服务器显式返回 CORS 头才放行。ZWServe 两件事都办了:既通过 HTTP 提供文件,又对每个响应注入宽松的 CORS 头。

1. 用 ZWServe 起本地服务

下载对应平台的 ZWServe(链接见顶部),然后在刚才运行 M3U8Grab 的目录里:

# Windows(PowerShell)—— 以当前目录为根,默认监听 8000
.\zwserv-win.exe

# 指定端口
.\zwserv-win.exe -port 9000

# macOS / Linux
chmod +x zwserv-macos && ./zwserv-macos
chmod +x zwserv-linux && ./zwserv-linux

# 指定要服务的目录
.\zwserv-win.exe -port 8000 -dir ./media/myvideo

启动时会打印所有本地网卡的可粘贴地址,例如:

ZWServe — from zwplayer.com (local CORS web server)
-------------------------------------------------
ZWServe — minimal CORS local web server
---------------------------------------------------------
serving : /home/me/media/ed_hd
port    : 8000
cache   : off (no-store — every refresh fetches the latest)

Serving at:
  http://192.168.1.20:8000/
  http://localhost:8000/

Tip: serving m3u8? Append your path, e.g. http://localhost:8000/master.m3u8

复制那条以 /master.m3u8 结尾的链接——这就是你的播放地址。

ZWServe 参数:

参数 默认值 说明
-port 8000 监听的 TCP 端口
-dir . 要服务的目录(默认:当前目录)

2. 把链接粘进 ZWPlayer 播放

打开 ZWPlayer,把 http://localhost:8000/master.m3u8 这个地址粘进播放器的 URL 输入框。因为 ZWServe 返回了 CORS 头,在线播放器就能跨域访问你本机的文件夹——而文件都在你机器上,全程不上传给第三方。

ZWPlayer 原生支持 HLS(m3u8)、DASH、MP4、MKV、MOV、WebM 等格式,M3U8Grab 产出的内容它都能播。

3. 内嵌字幕自动加载

这正是 M3U8Grab 要"改写引用"而不是保留原始 URL 的关键原因:m3u8 里的字幕轨现在指向本地 .webvtt 文件。当你在 ZWPlayer 中打开这个文件夹时:

  • 流里包含的每一种字幕语言(en、sv、ru、ja、ar……)都会自动挂载为可选择的字幕轨。
  • 在播放器的字幕菜单里切换即可,无需手动加载文件。
  • 因为字幕在本地,所以离线时也能用。

4. 预加载外部字幕与翻译

想要流里没有的字幕,或者要翻译?

  • 预加载外部字幕:播放时加载你自己的 VTT / SRT / BCC / JSON 字幕文件,支持多轨同时加载,方便双语对照。
  • 字幕翻译:内置面板支持实时把字幕翻译成 13 种语言,作为副字幕叠加显示——无需提前制作翻译好的文件。
  • 字幕搜索:跨全部字幕行搜索,命中即跳转,并支持逐句循环播放,非常适合语言学习。

🛠️ 想可视化地制作或精修字幕?试试免费的在线字幕编辑器——时间轴对齐、导出 VTT/SRT,成果可直接载入播放器。

进一步:接入 WordPress

如果你在 WordPress 站点发布视频,ZWPlayer WordPress 插件把以上全部能力——多字幕、翻译、播放列表、防盗播水印、章节——封装成古腾堡区块或简码,零代码集成。

常见问题

这样下载合法吗?

请只下载你有权访问的内容(自有媒体、已授权内容、或明确公开的流)。M3U8Grab 是一个工具;尊重版权与服务条款是你的责任。

为什么需要 ZWServe?不能直接打开 m3u8 文件吗?

不能。HLS 播放器是通过 HTTP(fetch/XHR)加载播放列表和分片的,file:// 地址下根本无法工作。而且播放器跑在网页上(如 zwplayer.com),访问你本机属于跨域请求,需要 CORS 头才放行。ZWServe 就是一个零配置的服务器,两件事都办了:既通过 HTTP 提供文件,又对每个响应注入宽松的 CORS 头。

会转成 MP4 吗?

不会——它保留原始 HLS 结构(分片 + 播放列表),这样才能完整保留所有码率、音频轨和字幕。用 ZWServe 起服务后,任何支持 HLS 的播放器(如 ZWPlayer)都能直接播放。如果你确实需要单个 MP4 文件,那是另外的封装/转码步骤。

下载中断了,要重来吗?

不用。原命令重跑即可。已下载、非空的文件会被跳过,只补缺失的部分。

某个清晰度失败了,能只重试它吗?

能——同上,重跑就会补齐缺失项。

被杀毒软件 / macOS 拦截了。

因为这些二进制没有签名,部分系统会拦截。macOS:右键 → 打开 → 确认,或执行 xattr -d com.apple.quarantine <文件>;Windows:在 SmartScreen 里点"更多信息" → “仍要运行”。

总结

M3U8Grab 把脆弱的、只能在线看的 m3u8,变成一个永久、自洽的本地文件夹——保留每一个清晰度、每一条音频轨和字幕。ZWServe 再用一条命令把这个文件夹暴露成一个带 CORS 的本地地址,直接粘进 ZWPlayer 就能播放,自动挂载多语言字幕,外加翻译与搜索能力。两者搭配,也是开发者测试 HLS 流和 CORS 行为的理想测试床。

下载你那个系统的二进制,找一条你有权保存的流,现在就试试。

M3U8Grab(下载器):🪟 Windows · 🍎 macOS · 🐧 Linux

ZWServe(播放服务器):🪟 Windows · 🍎 macOS · 🐧 Linux