m3u8视频下载器开发文档

lizhi0710
2026-06-01 / 0 评论 / 13 阅读

M3U8 下载器 - 开发文档

一、项目概述

1.1 项目名称

M3U8 Downloader(暂定名)

1.2 项目简介

基于 N_m3u8DL-RE 开源项目的桌面便携版 m3u8 视频下载工具,提供图形化界面,让用户无需命令行即可轻松下载 HLS 流媒体视频。

1.3 技术栈

类别技术选型说明
编程语言Python 3.10+开发效率高,生态丰富
GUI 框架PyQt5成熟的跨平台 GUI 框架,界面美观
打包工具PyInstaller打包为独立可执行的便携版 exe
核心依赖N_m3u8DL-RE开源 m3u8 下载引擎
辅助工具FFmpeg视频处理、合并、转码

1.4 项目结构

m3u8down/
├── N_m3u8DL-RE/          # N_m3u8DL-RE 核心文件(已存在)
│   ├── N_m3u8DL-RE.exe   # 主程序
│   ├── ffmpeg.exe        # FFmpeg
│   ├── ffplay.exe        # FFplay
│   ├── ffprobe.exe       # FFprobe
│   └── *.dll             # FFmpeg 依赖库
├── src/                  # 源代码目录(待创建)
│   ├── main.py           # 程序入口
│   ├── ui/               # 界面相关
│   │   ├── main_window.py      # 主窗口
│   │   ├── task_item.py        # 任务列表项组件
│   │   ├── dialogs.py          # 对话框(设置、新建任务等)
│   │   └── resources.qrc       # 资源文件
│   ├── core/             # 核心逻辑
│   │   ├── downloader.py       # 下载引擎(调用 N_m3u8DL-RE)
│   │   ├── task_manager.py     # 任务管理器
│   │   ├── config.py           # 配置管理
│   │   ├── database.py         # 本地数据库操作
│   │   ├── file_manager.py     # 文件管理(移动、清理)
│   │   └── utils.py            # 工具函数
│   └── assets/           # 静态资源
│       ├── icons/              # 图标
│       └── styles/             # 样式表
├── tmp/                  # 临时文件目录(运行时自动创建)
├── data/                 # 数据目录
│   ├── downloads.db      # SQLite 数据库(已完成任务)
│   └── tasks.json        # 运行中任务状态
├── config/               # 配置目录
│   └── config.json       # 用户配置
├── build/                # 构建输出
├── dist/                 # 打包输出
├── requirements.txt      # Python 依赖
├── build.spec            # PyInstaller 配置
└── README.md             # 项目说明

二、功能设计

2.1 核心功能

2.1.0 首次启动 - 保存路径设置

  • 启动软件后,首先弹出路径选择对话框
  • 用户通过下拉菜单选择可用盘符(自动检测系统所有可用盘符)
  • 程序自动在所选盘符下创建 hc 文件夹(如 D:\hc\
  • 如果 hc 文件夹已存在则直接使用
  • 保存路径配置后,后续启动不再弹出(可在设置中修改)
  • 临时文件统一存储在软件根目录的 tmp 文件夹

首次启动对话框示例:

┌──────────────────────────────────────────────┐
│  欢迎使用 M3U8 下载器                      [×] │
├──────────────────────────────────────────────┤
│                                              │
│  请选择下载文件的保存位置:                    │
│                                              │
│  保存盘符: [D:\ ▼]                           │
│                                              │
│  保存路径: D:\hc\                            │
│  临时目录: <软件根目录>\tmp\                  │
│                                              │
│  ☑ 以后不再提示(可在设置中修改)              │
│                                              │
│              [退出]     [确定]                │
└──────────────────────────────────────────────┘

2.1.1 新建下载任务

  • 输入 m3u8 URL 或本地 m3u8 文件路径
  • 任务去重机制:通过 URL 哈希值判断是否已存在相同任务

    • 若已存在,弹出提示:"该链接已存在于下载列表中"
    • 在界面右下角显示轻量提醒通知(3 秒后自动消失)
  • 解析 URL,显示可用的视频/音频/字幕轨道
  • 选择画质、音轨、字幕
  • 设置保存路径、文件名
  • 高级选项(线程数、重试次数、代理等)

2.1.2 任务管理

  • 任务列表展示(类似迅雷/IDM 等下载工具)
  • 任务状态:等待中、下载中、已暂停、已完成、失败
  • 支持操作:开始、暂停、继续、删除、重试
  • 显示进度条、下载速度、已下载大小、剩余时间
  • 并发控制:系统默认最大 3 个任务同时下载,多余任务进入等待队列

2.1.3 文件保存规则

  • 下载完成后,文件按照以下规则保存:

    <盘符>\hc\<下载链接的哈希值>\<下载完成的时秒分>.mp4

    示例:D:\hc\a1b2c3d4\143025.mp4

  • 链接哈希值:对下载 URL 进行哈希计算(如 MD5 前 8 位),确保唯一性
  • 时秒分命名:使用下载完成的时间(时+秒+分,6 位数字),避免重名
  • 下载完成后,将文件信息写入本地数据库
  • 下载完成后,自动清理临时目录中的对应文件夹和文件

2.1.4 任务状态持久化

  • 正在下载的任务:实时写入运行目录的 tasks.json 文件
  • 程序意外关闭后,重启可恢复未完成的任务状态
  • 已完成的任务信息存储在本地数据库中

2.1.4.1 异常恢复机制

  • 软件启动时执行以下操作:

    1. 清理残留进程:检测并终止所有 N_m3u8DL-RE 相关进程
    2. 清空临时目录:删除 tmp 文件夹内所有内容(避免残留损坏文件)
    3. 读取任务状态:从 tasks.json 加载未完成的任务列表
    4. 自动恢复下载:将加载的任务重新加入下载队列,按并发限制依次启动
  • 恢复的任务保持原有进度信息(实际进度需重新下载)

2.1.5 本地数据库

  • 使用 SQLite 轻量级数据库存储已完成任务记录
  • 数据库文件位置:<软件根目录>\data\downloads.db
  • 存储字段:

    • id: 任务唯一标识
    • url: 下载链接
    • url_hash: 链接哈希值
    • file_path: 最终保存路径
    • file_name: 文件名(时秒分.mp4)
    • file_size: 文件大小
    • download_time: 下载完成时间
    • status: 状态(已完成)

2.1.6 下载控制

  • 限速设置
  • 下载完成后操作(删除临时文件、混流等)

2.1.4 设置中心

  • 通用设置:下载目录、临时目录、线程数
  • 网络设置:代理、请求头、超时时间
  • 下载设置:重试次数、并发数、限速
  • 高级设置:解密 Key、自定义参数

2.2 界面布局

┌─────────────────────────────────────────────────────────────┐
│  菜单栏  [文件] [任务] [工具] [帮助]                          │
├─────────────────────────────────────────────────────────────┤
│  工具栏  [新建] [开始] [暂停] [删除] [设置]                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  任务列表                                            │   │
│  │  ┌───┬──────────┬────────┬────────┬──────┬────────┐ │   │
│  │  │   │ 文件名    │ 大小   │ 进度   │ 速度 │ 状态   │ │   │
│  │  ├───┼──────────┼────────┼────────┼──────┼────────┤ │   │
│  │  │▓▓ │ video.mp4 │ 100MB │ ████░░ │ 5MB/s│ 下载中 │ │   │
│  │  │▓▓ │ audio.mp3 │ 50MB  │ ██████ │ 3MB/s│ 下载中 │ │   │
│  │  │   │ doc.pdf   │ 10MB  │ ░░░░░░ │ 0    │ 等待中 │ │   │
│  │  └───┴──────────┴────────┴────────┴──────┴────────┘ │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                             ┌───────────┐ │
│                                             │ 提醒通知框 │ │
│                                             │ 链接已存在 │ │
│                                             └───────────┘ │
├─────────────────────────────────────────────────────────────┤
│  状态栏  任务数: 3 | 下载中: 2 | 总速度: 8MB/s | 磁盘剩余: XX │
└─────────────────────────────────────────────────────────────┘

2.3 新建任务对话框

┌──────────────────────────────────────────────┐
│  新建下载任务                              [×] │
├──────────────────────────────────────────────┤
│  URL/文件路径:                                │
│  ┌──────────────────────────────────────┐    │
│  │ https://example.com/video.m3u8       │    │
│  └──────────────────────────────────────┘    │
│                                              │
│  保存目录: [C:\Downloads\]        [浏览...]   │
│  文件名:   [video]                           │
│                                              │
│  ─── 轨道选择 ───                             │
│  视频: [1080p ▼]  音频: [中文 ▼]  字幕: [无 ▼]│
│                                              │
│  ─── 高级选项 ───                             │
│  ☑ 下载完成后合并                             │
│  线程数: [8]    重试次数: [3]                 │
│  代理: [无 ▼]                                 │
│                                              │
│              [取消]     [确定]                │
└──────────────────────────────────────────────┘

三、技术实现

3.1 N_m3u8DL-RE 调用方式

通过子进程调用 N_m3u8DL-RE.exe,解析其命令行输出获取进度信息。

核心命令构建示例:

# 基础命令
cmd = [
    "N_m3u8DL-RE.exe",
    m3u8_url,
    "--save-dir", save_dir,
    "--save-name", file_name,
    "--thread-count", str(thread_count),
    "--download-retry-count", str(retry_count),
]

# 可选参数
if proxy:
    cmd.extend(["--custom-proxy", proxy])
if headers:
    for h in headers:
        cmd.extend(["-H", h])
if select_video:
    cmd.extend(["-sv", select_video])

进度解析:

N_m3u8DL-RE 输出格式示例:

Parsing URL: https://example.com/video.m3u8
Found 3 video tracks, 2 audio tracks, 1 subtitle track
Downloading: 45.2% (125/277)  Speed: 5.2MB/s  ETA: 00:02:30

通过正则表达式解析进度、速度、ETA 等信息。

3.2 任务管理器设计

class TaskStatus(Enum):
    WAITING = "waiting"
    DOWNLOADING = "downloading"
    PAUSED = "paused"
    COMPLETED = "completed"
    FAILED = "failed"

class DownloadTask:
    id: str                    # 任务唯一标识
    url: str                   # 下载链接
    save_dir: str              # 保存目录
    save_name: str             # 文件名
    status: TaskStatus         # 状态
    progress: float            # 进度 0-100
    speed: str                 # 速度
    eta: str                   # 剩余时间
    total_size: str            # 总大小
    downloaded_size: str       # 已下载大小
    process: subprocess.Popen  # 子进程对象
    options: dict              # 下载选项

3.3 配置管理

使用 JSON 文件存储用户配置:

{
    "first_run": false,
    "save_dir": "D:\\hc",
    "tmp_dir": "<软件根目录>\\tmp",
    "thread_count": 8,
    "retry_count": 3,
    "timeout": 100,
    "proxy": "",
    "headers": [],
    "max_concurrent": 3,
    "speed_limit": "",
    "auto_merge": true,
    "delete_temp": true,
    "language": "zh-CN"
}

配置说明:

  • first_run: 是否首次运行(true=弹出路径选择,false=直接进入主界面)
  • save_dir: 下载保存目录(自动设置为 盘符:\hc
  • tmp_dir: 临时文件目录(固定为 <软件根目录>\tmp
  • max_concurrent: 最大并发下载数(默认 3)

3.4 本地数据库设计

使用 SQLite 存储已完成任务记录:

CREATE TABLE IF NOT EXISTS downloads (
    id TEXT PRIMARY KEY,           -- 任务唯一标识(UUID)
    url TEXT NOT NULL,             -- 下载链接
    url_hash TEXT NOT NULL,        -- URL 的 MD5 哈希值(前 8 位)
    file_path TEXT NOT NULL,       -- 最终保存路径
    file_name TEXT NOT NULL,       -- 文件名(时秒分.mp4)
    file_size INTEGER,             -- 文件大小(字节)
    download_time TEXT NOT NULL,   -- 下载完成时间(ISO 格式)
    status TEXT DEFAULT 'completed' -- 状态
);

CREATE INDEX IF NOT EXISTS idx_url_hash ON downloads(url_hash);
CREATE INDEX IF NOT EXISTS idx_download_time ON downloads(download_time);

3.5 运行中任务状态(tasks.json)

{
    "tasks": [
        {
            "id": "uuid-xxx",
            "url": "https://example.com/video.m3u8",
            "url_hash": "a1b2c3d4",
            "save_name": "video",
            "status": "downloading",
            "progress": 45.2,
            "speed": "5.2MB/s",
            "eta": "00:02:30",
            "start_time": "2026-06-01T14:30:00",
            "tmp_dir": "<软件根目录>\\tmp\\a1b2c3d4"
        }
    ]
}

3.6 文件保存流程

1. N_m3u8DL-RE 下载完成 → 临时文件在 <tmp>\<url_hash>\ 目录
2. 计算下载完成时间 → 格式化为 HHmmss(时秒分)
3. 创建目标目录 → <save_dir>\<url_hash>\
4. 移动文件 → <save_dir>\<url_hash>\<HHmmss>.mp4
5. 写入数据库 → 记录任务信息
6. 清理临时目录 → 删除 <tmp>\<url_hash>\ 及其内容
7. 更新 tasks.json → 移除已完成任务

3.7 程序启动流程

1. 程序启动
   ↓
2. 加载配置文件 (config.json)
   ↓
3. 判断是否首次运行 (first_run == true)
   ├─ 是 → 弹出 FirstRunDialog → 用户选择盘符 → 创建 hc 文件夹 → 保存配置
   └─ 否 → 继续
   ↓
4. 清理残留 N_m3u8DL-RE 进程
   ↓
5. 清空 tmp 文件夹
   ↓
6. 初始化数据库 (downloads.db)
   ↓
7. 读取 tasks.json 加载未完成的任务
   ↓
8. 将加载的任务加入下载队列
   ↓
9. 启动主窗口,显示任务列表
   ↓
10. 按并发限制(默认 3)依次启动下载任务

3.8 异常恢复流程

1. 检测到 tasks.json 存在未完成的任务
   ↓
2. 遍历任务列表,过滤状态为 downloading/paused/waiting 的任务
   ↓
3. 重置任务状态为 waiting
   ↓
4. 将任务加入 TaskManager 的等待队列
   ↓
5. TaskManager.check_queue() 自动调度,按并发限制启动任务

3.9 关键类设计

MainWindow (主窗口)
├── TaskListWidget (任务列表)
│   └── TaskItemWidget (单个任务项)
├── Toolbar (工具栏)
├── StatusBar (状态栏)
├── NotificationWidget (右下角提醒通知)
└── MenuBar (菜单栏)

Dialogs
├── FirstRunDialog (首次运行路径选择)
├── NewTaskDialog (新建任务)
├── SettingsDialog (设置)
├── TaskDetailDialog (任务详情)
└── SelectTrackDialog (轨道选择)

Core
├── DownloadEngine (下载引擎)
│   ├── start_task()
│   ├── pause_task()
│   ├── resume_task()
│   ├── cancel_task()
│   └── parse_output()
├── TaskManager (任务管理器)
│   ├── add_task()
│   ├── remove_task()
│   ├── get_tasks()
│   ├── get_active_count()
│   ├── check_queue()           # 检查等待队列,自动启动新任务
│   ├── save_running_tasks()    # 保存运行中任务到 tasks.json
│   └── is_duplicate_url()      # 检查 URL 是否已存在
├── ConfigManager (配置管理)
│   ├── load_config()
│   ├── save_config()
│   └── get/set 各项配置
├── DatabaseManager (数据库管理)
│   ├── init_database()         # 初始化数据库和表
│   ├── add_record()            # 添加已完成任务记录
│   ├── query_by_hash()         # 按哈希值查询
│   └── get_all_records()       # 获取所有记录
├── FileManager (文件管理)
│   ├── generate_url_hash()     # 生成 URL 哈希值
│   ├── generate_filename()     # 生成时秒分文件名
│   ├── move_to_final_path()    # 移动文件到最终保存路径
│   ├── cleanup_temp()          # 清理临时目录
│   └── ensure_dirs()           # 确保所需目录存在
└── ProcessManager (进程管理)
    ├── kill_n_m3u8dl_processes()  # 清理所有 N_m3u8DL-RE 进程
    └── is_process_running()       # 检查进程是否运行

四、开发计划

阶段一:基础框架搭建

  • [ ] 创建项目结构
  • [ ] 搭建 PyQt5 主窗口框架
  • [ ] 实现基础菜单栏、工具栏、状态栏
  • [ ] 实现配置管理模块

阶段二:核心功能开发

  • [ ] 实现 N_m3u8DL-RE 调用封装
  • [ ] 实现进度解析
  • [ ] 实现任务管理器
  • [ ] 实现新建任务对话框

阶段三:界面完善

  • [ ] 实现任务列表组件
  • [ ] 实现任务操作(开始/暂停/删除)
  • [ ] 实现设置对话框
  • [ ] 添加样式美化

阶段四:高级功能

  • [ ] 轨道选择功能
  • [ ] 限速功能
  • [ ] 代理设置
  • [ ] 批量下载

阶段五:测试与打包

  • [ ] 功能测试
  • [ ] 边界情况处理
  • [ ] PyInstaller 打包
  • [ ] 便携版测试

五、注意事项

5.1 便携版要求

  • 所有文件相对于程序目录
  • 配置存储在程序目录下的 config 文件夹
  • 无需写入注册表或系统目录
  • 可直接拷贝整个文件夹到其他电脑使用

5.2 N_m3u8DL-RE 集成

  • N_m3u8DL-RE.exe 放在程序目录下的 N_m3u8DL-RE 文件夹
  • 通过相对路径调用
  • 打包时需确保 N_m3u8DL-RE 相关文件被包含

5.3 跨平台考虑

  • 当前仅支持 Windows(因 N_m3u8DL-RE 为 Windows 版本)
  • 路径处理使用 os.pathpathlib
  • 命令行参数注意 Windows 转义

5.4 错误处理

  • 网络异常处理
  • N_m3u8DL-RE 进程异常捕获
  • 磁盘空间不足检测
  • 文件权限问题处理

六、依赖清单

Python 依赖

PyQt5>=5.15.0
requests>=2.28.0

外部依赖(已提供)

  • N_m3u8DL-RE.exe
  • ffmpeg.exe / ffplay.exe / ffprobe.exe
  • 相关 DLL 文件

七、参考资源

0

评论

博主关闭了所有页面的评论