原项目.NET m3u8 downloader 是一个开源的命令行m3u8/HLS/dash下载器,支持普通AES-128-CBC解密,多线程,自定义请求头等。目前在github上有16k星。本文是基于 Rust + Tauri 2 对 N_m3u8DL-CLI(C# / .NET)的复刻实现一个简单易用的 m3u8 多线程下载器,自带可视化配置界面。
前言:为什么要折腾
前阵子逛 GitHub 发现了 N_m3u8DL-CLI 这个老牌 m3u8 下载器------C#/.NET 写的,功能相当能打:多线程下载、AES-128 自动解密、Master List 清晰度选择、ffmpeg 混流,还有一堆命令行参数。但它是 .NET Framework 的,作者自己也说进入维护阶段了,新功能都跑去了跨平台的 N_m3u8DL-RE。
我寻思着:这项目思路清晰、MIT 开源、还带完整文档,不如用 Rust + Tauri 2 把它复刻一遍?
理由:
- 跨平台,移植方便:原版是 .NET Framework,只能在 Windows 上跑;而 Rust + Tauri 天然跨平台(Windows / Linux / macOS),核心逻辑用 Rust 写一遍,以后换平台直接编译就能用,几乎零移植成本,不用再到处找替代工具;
- 好用,比命令行强 :原版是纯命令行,参数一大堆(
--maxThreads --retryCount --headers......),虽然强大但劝退小白;套一层可视化界面,填个链接、点个按钮,进度条、速度、日志一目了然,日常用起来舒服多了; - 顺便还能学习 Tauri 2 的桌面开发,把 C# 那套下载逻辑用现代 Rust 重新写一遍。
说干就干,于是就有了这个项目(就叫它 N_m3u8DL-Tauri)。
- 🌐 作者博客主页:blog.csdn.net/qq8864
- 🌐 项目开源地址:https://gitcode.com/qq8864/m3u8dl-tauri.git

这项目长啥样
一句话:一个自带可视化配置界面的 m3u8 多线程下载器,前端是原生 HTML/CSS/JS(零构建),后端是纯 Rust,两者通过 Tauri 2 的命令桥接。
m3u8dl-tauri/
├── frontend/ # GUI:表单配置 + 进度条 + 彩色日志
├── bin/ffmpeg/ # 内置 ffmpeg(自动探测)
└── src-tauri/
├── src/
│ ├── commands.rs # 命令层
│ └── core/ # 核心逻辑,与 GUI 完全解耦
│ ├── hls.rs # m3u8 解析
│ ├── download.rs # 多线程下载引擎
│ ├── merge.rs # 合并(二进制 / ffmpeg)
│ └── ...
└── tests/ # 端到端集成测试
我最满意的设计是 core/ 和 Tauri 完全解耦------核心逻辑就是个普通 Rust 库,能单独编译、单独测试,GUI 只是它的一个壳。这也让后面的测试变得非常爽。
复刻了哪些核心功能(对照原版)
| 原版功能 | 我的实现 |
|---|---|
| m3u8 链接/文件解析 | hls.rs 逐行状态机,对齐原版 Parser.cs 的逻辑 |
| Master List 多清晰度 | 解析所有 #EXT-X-STREAM-INF,自动选最高带宽 |
| AES-128-CBC 自动解密 | 支持 base64/data/file/http 密钥,默认 IV = 分片序号 |
| 多线程下载 | tokio 信号量并发,线程数可配(默认 8) |
| 分片重试 | 指数退避 + 随机抖动,404/400 快速失败 |
| 断点续传 | 已下载分片自动跳过 |
| 下载限速 | 全局令牌窗口 |
| 下载范围 | 按分片序号或时间段 |
| 自定义 Headers / 代理 | 表单直接填 |
| 自动合并 | 二进制拼接(ts/fMP4)或 ffmpeg 混流 mp4 |
| 完成后清理 | 一键开关 |
原版的一些边界功能(直播录制、优酷/气球云专有解密、外挂音轨)没做,但检测到直播流会明确报错,不会装死。
踩坑记:真·血泪史
写代码的过程比想象中曲折,记录几个印象深刻的坑,给同样踩 Tauri 2 的兄弟们提个醒:
1. 前端静默崩溃:window.TAURI 不存在
第一次跑起来,界面能显示,但点"开始下载"毫无反应 ,日志区一片空白。查了半天,根因是 tauri.conf.json 里没开 withGlobalTauri: true------Tauri 2 默认不注入 window.__TAURI__ 全局对象,我的 app.js 第一行解构就直接抛异常,整个脚本挂了,按钮监听压根没绑定上。修复很简单,但排查过程很抓狂。后来我给前端加了防御性检查,桥接缺失时在日志区显示红色错误提示,再也不怕静默崩溃了。
2. 进度条显示 "NaN GB"、分片 "undefined/undefined"
跑起来之后更离谱:进度条显示 NaN GB、分片 undefined/undefined。原因是我后端 Progress 结构序列化出来是 snake_case(total_segments),前端却按 camelCase(totalSegments)读------全都读到 undefined。加一行 #[serde(rename_all = "camelCase")] 搞定。这种前后端字段名不一致的坑,新手真的容易踩。
3. 错误信息被"轮询竞态"吞掉
任务失败后,前端只显示"任务已结束",具体错误看不到。原因是:任务失败 → 设置错误状态 → 立即从注册表移除,三步一气呵成,而前端每 500ms 轮询一次,大概率完美错过那个短暂存在的错误状态。解决方案是给 AppState 加了归档机制:任务结束后保留最终快照,前端随时还能查到错误信息和完整日志。这个设计后来帮了大忙------用户反馈问题,一眼就能从日志定位。
4. 下载 ffmpeg 的曲折经历
为了验证 ffmpeg 混流路径,我需要一个真实的 ffmpeg.exe。gyan.dev 官方源 14KB/s 龟速、GitHub release 直接连不上、winget 又没装......最后灵机一动走了 npmmirror 的 ffmpeg-static 二进制镜像,5MB/s 秒下。这告诉我们:国内开发者,镜像站就是命。
5. 测试源不给力:不是程序的锅
拿公开测试源 mux.dev 测试,分片下载疯狂重试,一度以为代码有 bug。后来 curl 一测:分片 URL 完全正常(HTTP 200,5MB 大小),但大文件传输只有 3~12KB/s 且频繁断开------纯粹是网络环境到那个服务器太慢。程序的重试机制反而证明了自己在正确工作。顺手优化了默认线程数(16→8)和重试退避(加随机抖动打散重试风暴),慢网下体验好不少。
测试:7 个用例全部通过
既然是复刻,就得用测试证明"真的能用"。我写了 7 个测试,全部通过:
单元测试(4 个):基础解析、AES 默认 IV、Master List、URL 拼接。
端到端集成测试(3 个) ------这是最过瘾的部分,我在测试里起了一个本地迷你 HTTP 服务器,模拟真实下载场景:
- 前 3 个分片用 AES-128 加密、后 3 个明文(还测了 KEY 状态切换),4 线程并发下载 → 解密 → 二进制合并,最后和原始数据逐字节比对;
- 用真实 ffmpeg 生成 3 个 MPEG-TS 分片 → 下载 → ffmpeg concat 混流 mp4(faststart)→ 再用 ffmpeg 反向探测输出文件可正常读取。
测试代码长这样(节选)------本地起服务器喂数据,全链路真跑:
rust
#[tokio::test]
async fn test_e2e_encrypted_download_and_merge() {
// 本地迷你 HTTP 服务提供 加密m3u8 + key + 分片
let (port, server) = start_server(routes);
let ctx = DownloadCtx::new(opts, "e2e".to_string()).unwrap();
let result = m3u8dl_tauri_lib::core::download::run(ctx.clone()).await;
// 输出与原始分片拼接逐字节比对
assert_eq!(got, expect, "输出内容不符(解密或顺序有误)");
}
怎么跑
bash
cd m3u8dl-tauri/src-tauri
cargo run # 启动 GUI
cargo test # 跑全部测试
ffmpeg 放 bin/ffmpeg/ 下会自动探测到,界面会显示"✔ 已找到 ffmpeg";找不到就自动回退为二进制合并,不影响使用。
写在最后
这个项目做下来,最大的收获是把 Tauri 2 的开发套路、前后端桥接、异步并发下载这些知识点全都实战了一遍,而且------所有功能都有测试兜底,重构起来心里有底。原版 N_m3u8DL-CLI 的设计(meta.json 中间产物、分片分组、二进制/ffmpeg 双合并路径)本身就很值得学习,复刻过程相当于把它的设计读薄了一层。
后续如果有时间,想补上直播录制、外挂音轨这些原版功能,或者把 master 清晰度选择做成 GUI 下拉而不是自动选最高。项目已开源在本地,欢迎交流指正。
关于博主:CSDN 猫哥
本文作者是 CSDN 猫哥。博客里记录了 Rust、Tauri、音视频处理相关的实战经验、踩坑笔记和一些小工具分享,欢迎关注交流:
- 🌐 博客主页:blog.csdn.net/qq8864
如果你觉得这篇文章对你有帮助,或者对 m3u8 下载 / Tauri 开发有更好的想法,欢迎到博客留言交流,也可以提出 issue 一起改进这个项目。