MimicM3U8Downloader 拟态M3U8下载器
本帖最后由 steven026 于 2026-8-2 05:13 编辑# MimicM3U8Downloader 拟态M3U8下载器
🚀 **一款可对抗防爬策略的反TLS指纹 M3U8 视频流下载器**
本项目基于 `impit` 库,能够**完美模拟真实浏览器的 TLS 指纹**,绕过人机验证,实现稳定、高速的m3u8分片下载与自动合并
GitHub: <https://github.com/DreamNya/MimicM3U8Downloader>
---
## ✨ 项目特性
* **TLS 指纹混淆**:模拟 Chrome 等主流浏览器的 TLS 握手特征,绕过 Cloudflare 防爬校验
* **多级 M3U8 嵌套解析**:支持 Master Playlist 递归解析,自动提取 BaseURL 并精准锁定最高清晰度视频流
* **动态 AES 解密**:流式解密标准 AES-128 加密分片,支持多密钥自动识别与平滑切换
* **自动处理伪装字节**:下载非标准加密分片时,尝试全自动处理伪装字节(文件头)
* **精准区间下载**: 支持解析并下载指定范围(Range)的分片,满足按需下载需求
* **流式断点续传**:集成分片完整性校验机制,支持中断进度秒传,大幅减少重复磁盘 I/O 损耗
* **多线程高效并发**:采用多线程异步并发请求,最大化利用网络带宽,提升下载吞吐量
* **高性能流式合并**:支持分片内存暂存并实时写入 FFmpeg 管道,跳过中间产物损耗,降低约 50% 磁盘 I/O 开销,有效提升合并效率并延长 SSD 使用寿命。
* **FFmpeg 自动封装**:分片下载完成后自动调用 FFmpeg,实现无损、快速的合并与封装
* **三模一体化运行**
1. **CLI 模式**:直接通过 Node.js 调用下载器
2. **URL Protocol 协议**:支持浏览器或外部网页通过URL Protocol 协议唤醒下载器
3. **HTTP 本地服务**:通过本地服务器 http 请求,一键唤醒下载器
### 预览
!(data/attachment/forum/202607/07/164359kyq2ycp2ihihhc7i.gif)
---
## 📦 安装
本项目有2种安装/使用方式可选,可根据自己实际情况选择
* Node.js模式需要在本地环境中安装Node.js,但可直接运行模块
* 编译模式无需安装Node.js,但编译文件解压后文件体积较大
### Node.js模式
克隆项目
```bash
git clone https://github.com/DreamNya/MimicM3U8Downloader.git
cd MimicM3U8Downloader
npm install
```
### 编译模式
下载编译后的文件
* **GitHub Release(多平台)**
```text
https://github.com/DreamNya/MimicM3U8Downloader/releases
```
* **蓝奏云分流(仅windows)**
```text
https://wwbwh.lanzouw.com/b01d72je4h
密码:496r
```
---
## 🛠️ 前置准备
### Node.js
> 编译模式可跳过
安装 **Node.js v23.6.0 或更高版本**(推荐: Node.js v24+ / latest LTS)
(低版本Node.js请手动添加flag`--experimental-strip-types`或使用`ts-node`)
### FFmpeg
无论是Node.js模式还是编译模式均需安装FFmpeg
请确保本地环境中已经安装 FFmpeg,且正确配置**环境变量**
---
## 📝 配置文件说明
项目包含两个全局配置文件,位于 `config/` 目录。
### 📂 config/server.setting.json
> 请将 `config/server.setting.json` 复制为 `config/server.setting.json` 以正确生效用户配置
本地 http 服务器配置参数
| 参数 | 类型 | 默认值| 说明
| ----------------- | ------- | --------| -------------------------------------------------
| `Port` | string| `12345` | 本地 http 服务监听端口
---
### 📂 config/worker.setting.json
> 请将 `config/worker.setting.json` 复制为 `config/worker.setting.json` 以正确生效用户配置
下载器全局配置参数
| 参数 | 类型 | 默认值 | 说明
| -------------------- | ------- | ---------- | -------------------------------------------------
| `browser` | string| `"chrome"` | 模拟 TLS 指纹浏览器名称 <br> 详见 [<https://apify.github.io/impit/js/types/Browser.html>]
| `proxyUrl` | string| `""` | 代理服务器地址,例如 `http://127.0.0.1:10808`
| `headers` | object| `{}` | 请求头(同时用于请求m3u8文件及分片)<br />(Referer、Cookies 等)
| `range` | string| `""` | 分片选择范围 详见 [(#range设置格式)]
| `concurrency` | number| `16` | 分片并发请求数
| `maxRetries` | number| `3` | 网络请求失败时自动重试次数(403 404时不会重试)
| `timeout` | number| `60000` | 网络请求的超时毫秒<br />(包含请求及连接时间,如果分片过大建议提高超时时间)
| `streamMerge` | boolean | `false` | 流式合并(启用后忽略`noMerge`, `forceMerge`) <br>流式合并模式参数作用 详见 [[下载模式对比](#下载模式对比)] (下同)
| `streamMergeFMP4` | boolean | `false` | 流式合并时输出格式为fMP4<br />(启用后忽略`streamMergeForceMerge`)
| `streamMergeForceMerge` | boolean | `false` | 流式合并断点续传时强制将多个mp4片段合并为1个mp4文件
| `noMerge` | boolean | `false` | 分片下载完毕不自动合并
| `forceMerge` | boolean | `false` | 下分片下载不完整时强制合并
| `enableDelAfterDone` | boolean | `false` | 下载完毕后删除临时文件夹
| `pauseAfterDone` | boolean | `true` | 下载完毕后暂停交互窗口
| `debug` | boolean | `false` | 记录debug中间产物
---
### 🌐 Payload
每次调用下载器时必须传递的参数
| 参数 | 类型 | 是否必须传递 | 说明
| ---------------- | ------- | -------------- | -------------------------------------------------
| `url` | string| 必须 | m3u8 请求地址
| `saveName` | string| 必须 | 视频存储文件名(不包括后缀)<br>(如果文件名不合法则降级为时间戳)
| `workDir` | number| 必须 | 视频存储目录(临时文件也会存储在该目录下)
其余非必须传递参数与下载器全局配置参数规则相同,如果传递则在该次调用中覆盖全局配置中对应的配置
### 📎 配置附录
#### 下载模式对比
| 模式对比 | 缓存后再合并(默认模式) | 流式实时合并 | 流式实时合并(fMP4)
| -------- | ---------------------- | ---------------------- | --------
| **配置项** | `streamMerge: false` | `streamMerge: true`<br/>`streamMergeFMP4: false` | `streamMerge: true`<br>`streamMergeFMP4: true`
| **视频格式** | 标准mp4 | 标准mp4 | fMP4
| **磁盘写入** | 总是 **2 倍** 视频大小 | 正常下载:**1 倍** 视频大小<br>断点续传不合并:**1 倍** 视频大小<br>断点续传后合并:**2 倍** 视频大小 | 总是 **1 倍** 视频大小
| **断点续传** | **支持** | **有限支持*** | **有限支持***
| **内存占用** | 无额外占用 | 最多额外占用<br /> `[并发数 * 分片平均大小]` 内存 | 最多额外占用<br /> `[并发数 * 分片平均大小]` 内存
| **备注** | 无 | 仅**断点续传**时<br />如果`streamMergeForceMerge`<br />为`false`:生成多个独立mp4片段<br />为`true`:将所有片段合并为完整mp4 | 该模式仍在测试中\*\*<br>可能存在未知Bug<br>欢迎在 ISSUE 中反馈
> \* 仅在下载过程中发生网络错误、连接异常等下载流中断时支持断点续传继续下载(此时FFmpeg合并的均为干净数据)
> \- 若发生校验/合并异常则不支持断点续传(说明此时FFmpeg合并数据已被污染)
> \- 受Node.js限制,如果模块被用户强行退出将不支持断点续传(无法通知并等待FFmpeg进行EOL截断)
> \- 如需手动中断下载,请在CLI中按下Ctrl+C,如此模块可以安全退出并保留断点
>
> \** fMP4模式原理涉及元数据校验及重写,非常复杂,可能存在极端边界情况、非预期情况
> \- 详见 (src/core/fMP4.ts)
#### 下载模式工作原理
* 缓存后再合并:流式下载分片 ➔ **流式写入硬盘缓存**➔ 读取所有缓存 ➔ 调用 FFmpeg 合并 ➔ **写入最终视频**
* 流式实时合并:流式下载分片 ➔ **未合并分片暂存内存** ➔ 按顺序推入 FFmpeg 流 ➔ **实时流式合并写入最终视频**
> 默认(传统)模式,先将分片下载到磁盘缓存再进行合并,这样会进行2倍读写I/O
>
> 流式实时合并模式,会将分片下载到内存,然后直接通过管道传递给FFmpeg进行合并且流式写入磁盘,这样则减少了额外的读写I/O
> 流式实时合并最多将[并发数]个分片暂存在内存中(而非所有分片),无需担心内存溢出
> 假设并发数为16、分片平均大小500KB,则最多额外占用16*500KB=8MB内存
#### range设置格式
*以下格式2选1,不可混用
| 范围分类 | 示例格式 | 实际下载范围 / 行为说明
| ---------------- | ---------------------------------------- | ------------------------------------------
| **索引格式** | `"123,128,130"` | 仅下载索引为 123、128、130 的分片(多分片用 `,` 分割)
| (数字索引) | `"120-"` | 下载从第 120 分片开始的所有后续分片
| | `"120-200"` | 下载闭区间 120 ~ 200 之间的所有分片
| | `"-200"` | 下载从开头第 0 分片到第 200 分片的所有分片
| | `"110,120-130,150-180,185"` | 支持复合区间(用`,`分隔): <br> 同时下载 110、120~130、150~180 以及 185 分片
| **时间轴格式** | `"00:00:28-"` | 下载视频 28 秒之后的所有分片
| (时间文本) | `"-00:10:00"` | 下载视频 10 分钟之前的所有分片
| | `"00:00:28-00:10:00"` | 下载视频 28 秒到 10 分钟之间的所有分片
| | `"00:00:28-00:10:00,00:15:00-00:16:00"`| 支持复合时间(用`,`分隔): <br> 下载 28 秒~10 分钟 和 15 分钟~16 分钟内的所有分片
#### 配置优先级
同一配置项存在多个来源时,按以下优先级覆盖(高 → 低):
1. `Payload` 传递的参数
2. `worker.setting.json` 中配置的全局静态参数
3. 下载器默认兜底参数
## 🚀 使用方法
下载器接收的数据格式为:
```text
m3u8mimic://<Base64(JSON Payload)>
```
Payload 格式参考
```json
{
"url": "https://example.com/target.m3u8",
"saveName": "视频保存名称",
"workDir": "D:/m3u8",
"headers": {
"Referer": "https://example.com/",
"Origin": "https://example.com/",
"Cookie": "XXX",
}
}
```
中文Base64编码参考
``` ts
function BTOA(str: string): string {
return btoa(String.fromCodePoint(...new TextEncoder().encode(str)));
}
```
---
### 模式一:CLI 命令行
直接在CLI中通过`--`传递参数
*--headers必须为标准JSON*
* **Node.js模式**
```bash
node src/bin/worker.ts --url "https://example.com/target.m3u8" --saveName "视频保存名称" --workDir "D:/m3u8" --headers "{\"Referer\":\"https://example.com/\",\"Origin\":\"https://example.com/\"}'
```
* **编译模式**
```bash
MimicM3U8Downloader --url "https://example.com/target.m3u8" --saveName "视频保存名称" --workDir "D:/m3u8" --headers "{\"Referer\":\"https://example.com/\",\"Origin\":\"https://example.com/\"}'
```
---
### 模式二:URL Protocol 唤醒
注册 Windows URL Protocol 后,可以直接在浏览器或其他程序中访问`m3u8mimic://`协议链接启动下载器
#### 调用方式
在浏览器或本地直接打开协议链接即可
```text
m3u8mimic://<Base64(JSON Payload)>
```
例如:
```text
m3u8mimic://eyJ1cmwiOiJodHRwczovL2V4YW1wbGUuY29tL3RhcmdldC5tM3U4Iiwic2F2ZU5hbWUiOiLop4bpopHkv53lrZjlkI3np7AiLCJ3b3JrRGlyIjoiRDovbTN1OCIsImhlYWRlcnMiOnsiUmVmZXJlciI6Imh0dHBzOi8vZXhhbXBsZS5jb20ifX0=
```
#### 注册/更新/卸载协议
> 仅需注册一次、无需管理员权限、模块会自动配置调用路径
* **Node.js模式**
注册/更新协议
```bash
npm run registerUrlProtocol
```
卸载协议:
```bash
npm run unregisterUrlProtocol
```
* **编译模式**
注册/更新协议
```bash
MimicM3U8Downloader --register
```
卸载协议:
```bash
MimicM3U8Downloader --unregister
```
---
### 模式三:HTTP 本地服务
适合作为浏览器脚本或其他应用调用
> http本地监听模块与下载模块进程间互相独立,一方关闭不会影响另一方
默认监听(监听端口可通过`config/server.setting.json`修改)
```text
http://127.0.0.1:12345
```
#### 启动服务
* **Node.js模式**
```bash
npm run server
```
* **编译模式**
> 不要传递任何 -- 参数,否则视为CLI命令行模式直接调用下载模块(windows系统中直接双击运行即可)
```bash
MimicM3U8Downloader
```
#### 请求示例(UserScript)
```javascript
GM_xmlhttpRequest({
url: 'http://127.0.0.1:12345',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
data: JSON.stringify({
url: 'https://example.com/target.m3u8',
saveName: '视频保存名称',
workDir: 'D:/m3u8',
headers: {
Referer: location.href,
Origin: location.origin,
},
}),
onload: (xhr) => console.log(xhr),
});
```
#### 请求示例(curl)
```bash
curl -X POST "http://127.0.0.1:12345" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/target.m3u8",
"saveName": "视频保存名称",
"workDir": "D:/m3u8",
"headers": {
"Referer": "https://example.com",
"Origin": "https://example.com",
}
}'
```
---
## 💻 开发
本项目在部分设计方面参考了`N_m3u8DL-CLI`项目
### SEA单文件编译
本项目依赖TypeScript / ESM架构 / C++编译库,开发环境采用 Node.js,仅 SEA 编译环境使用 Bun
手动SEA编译方法(单平台)
```bash
bun run build
```
GitHub Action(多平台)
```bash
.github\workflows\build.yml
```
### TODO
* [ ] SAMPLE-AES解密 (不含DRM)
* [ ] 解析本地m3u8
* [ ] 前端GUI
---
## 📄 开源协议
本项目基于 **MIT License** 开源
## 更新日志 v0.1.1
- 新增 流式合并
- 优化 分离 segment 职责
- 优化 types.ts jsDoc
- 修复 流式合并 异常时应当终止模块
- 修复 UrlProtocol注册模块 未正常运行
- 新增 GitHub CI/CD 自动Release
> 日后更多更新日志建议直接阅读GitHub Readme
<https://github.com/DreamNya/MimicM3U8Downloader> 虽然看不懂,但是 ggnb 王一之 发表于 2026-7-8 13:52
虽然看不懂,但是 ggnb
实际上就是用TypeScript写的M3U8视频下载器 瑟瑟是第一生产力! 朱焱伟 发表于 2026-7-11 03:01
瑟瑟是第一生产力!
我不是、我没有、别瞎说{:4_87:}
页:
[1]