简体中文
能力扩展计划
2026-10-27 更新:DASH、progressive FLV / MP4 与独立 AAC 均已改为浏览器磁盘封装,容量根据浏览器剩余配额动态检查,预留输入与输出空间。下文历史阶段中的 512 MB 限制已取消;实现与验证见 实现说明 和 验证记录。
首次计划:2026-10-04;最近更新:2026-10-05。基于「设计并实现视频下载方案」聊天及当前代码。
当前 P0~P5 功能均已实现,包括 P3 任务控制、P4 原生助手交接及 P5 素材组合,行为约定见文末。发布验收仍须区分构建、模拟接口测试和真实环境,最新证据与未覆盖项见 验证记录。
能力地图
| 阶段 | 能力 | 用户价值与边界 |
|---|---|---|
| 本轮 P0 | 自选分 P | 当前 / 全部 / 自选;勾选、全选、反选;按视频原始顺序下载,显示数量和总时长 |
| 本轮 P0 | 画质偏好 | 最高可用、最高 1080P / 720P / 480P;记住选择;已入队任务保留原设置 |
| 本轮 P0 | 暂停队列 | 当前任务继续完成,暂停领取下一项;刷新后仍暂停;恢复后继续 |
| 本轮 P0 | 队列整理 | 标题 / BV / 分 P 搜索,失败筛选,一次重试失败任务,跳过重复任务 |
| 本轮 P1 | 素材导出 | 仅音频 M4A、封面原图、SRT 字幕、弹幕 XML,明确输出和无素材状态 |
| 本轮 P1 | 文件组织 | 命名模板、按 UP / 视频建目录、可选完成通知、JSON / CSV 下载记录 |
| P2 已实现 | 大型任务 | OPFS 分块缓存、安全 Range 续传、链接刷新、本地 FFmpeg 命令行助手 |
| P2 已实现 | 批量来源 | 链接列表、收藏夹、合集 / 系列、UP 投稿;分页预览、限速、权限反馈与重复跳过 |
| 本轮 P3 | 会话恢复 | 自动保存最近一次批量来源、分页、勾选、选项快照与入队结果,手动继续 |
| 本轮 P3 | 长期历史 | 独立成功记录、搜索筛选、导出、重新入队与跨队列历史去重 |
| 本轮 P3 | 任务控制 | 单项暂停保留缓存、继续、等待顺序调整 |
| 本轮 P4 | 本地集成 | 原生通信交接、进度与结果回传、过期链接刷新协助 |
| 本轮 P5 | 素材组合 | 一次选择多类素材、按视频归档、整体完成与失败展示 |
本轮行为约定
- 保留单视频一键下载和多 P 默认当前分 P 的行为。
- 自选项用页码传输,后台重新读取元数据后校验全部页码;空选择、失效页码拒绝入队。按元数据顺序去重。
- 画质是上限,不是权限承诺。只选择实际返回且不超过上限的流;无法确认或没有符合上限的流时明确失败。竖屏按短边判断分辨率。
- 默认最高可用,旧队列通过 schema 默认值兼容。当前任务的偏好存入任务快照,重试沿用;修改默认值不影响既有任务。
- 暂停是队列调度状态,不是网络暂停或断点续传。当前下载 / 合并 / 保存继续完成。
- 设置与暂停状态用 storage.local 保存,通过后台序列化修改,多个界面通过 storage.onChanged 同步。
- 批量重试只处理失败项,跳过已有活跃任务和同分 P 重复历史,校验 1000 条队列容量;取消项仍可单项重试。
- 不增加扩展权限、运行依赖或媒体存储方式。
组件与逻辑边界
| 模块 | 职责与契约 |
|---|---|
| DownloadPanel | 组合视频信息、选择器、提交与进度,接收 url |
| DownloadPartPicker | 接收 pages/currentPage,mode 与 selectedPages 双向模型;只负责范围选择 |
| DownloadQuality | 画质选择器,quality 双向模型,支持 disabled |
| DownloadQueue | 队列查询、过滤、暂停/恢复与批量操作 |
| useVideoDownload | 页面解析、分 P 选择、过期响应保护和入队请求 |
| useDownloadSettings | 加载、同步、更新持久化设置,暴露错误与加载状态 |
| downloads/queue/jobs | 分 P 校验、创建任务、重试去重和调度选择的纯函数 |
| background/services/downloads | 校验消息、序列化队列与设置操作 |
| bilibili/streams | 根据实际返回的分辨率和画质上限选择流 |
实施与验收
- 扩展类型、消息、队列纯函数和取流策略,补充边界测试。
- 接入设置持久化及后台暂停/重试;runner 使用任务快照。
- 实现粉色主题选择器、搜索筛选与队列操作,补充使用文档。
- 运行 test、format:check、lint、typecheck、Chromium / Firefox 构建。
- Chromium 加载生产扩展,验证分 P 自选、画质快照、暂停恢复、搜索、批量去重和真实 FFmpeg 输出;保留截图并注明模拟接口范围。Firefox 运行验证以环境可用性为界。
本轮完成状态
四项 P0 已实现。原阶段 21 个单元测试通过,格式、Lint、类型检查和 Chromium / Firefox 生产构建通过。Chromium 已验证任务快照、跨界面设置同步、暂停恢复、真实 WASM 合并保存、批量去重及窄屏布局,详情见 验证记录。后续阶段的实施记录见下文。
P1 实施约定(2026-10-04)
- 任务新增素材类型、字幕语言、UP 主和文件设置快照。旧队列自动补齐默认值,仍下载 MP4;活跃任务和重试按 BV / CID / 类型 / 字幕语言去重,封面只按 BV 去重。
- M4A 使用最高码率的实际 AAC 音轨,避免下载视频轨,不转码;无独立音轨、试看、DRM 明确拒绝。音视频仍受 512 MB 输入上限约束。
- 封面每个视频一份,根据真实图片签名确定扩展名。字幕每分 P 一份 SRT,自动优先中文,同语言优先人工字幕;可指定中文或英文,缺少指定语言不会悄悄换语言。弹幕使用当前 XML 快照,不声称是全历史。三种文本/图片素材输入上限为 16 MB。
- 文件模板仅允许列出的变量,目录模式固定在 Bilibili 下;每一层单独清理字符并按 UTF-8 字节限制长度。保存动作与现有 browser.downloads 完成检测、取消及 Blob 释放共用。
- 通知默认关闭,在设置页的点击事件中申请可选权限,保存完成才通知。记录只导出当前筛选,JSON / CSV 均只包含用户可见元数据,CSV 对公式前缀转义。
- 新增
https://comment.bilibili.com/*主机权限用于弹幕,并加入仅作用于本扩展请求的 Referer 规则;沿用既有可选 notifications 权限,不新增运行依赖。
P1 模块边界
| 模块 | 职责与契约 |
|---|---|
| DownloadAssetPicker | kind / subtitleLanguage 双向模型,只负责输出和语言选择 |
| DownloadFileSettings | 组合命名、目录预览、保存反馈与通知开关 |
| useDownloadFileSettings | 设置草稿、校验、文件名预览和用户手势中的权限请求 |
| useDownloadHistory | 根据调用时的筛选快照导出记录,管理保存和错误状态 |
| bilibili/subtitles、cover | 字幕选择和 SRT 转换、图片格式识别 |
| downloads/files/fetchAsset | 下载并验证封面、字幕、弹幕,返回 Blob 与输出格式 |
| downloads/files/createDownloadPath、history/serializeDownloadHistory | 安全路径生成、记录格式转换的纯函数 |
| downloads/queue/runner | 按类型分派,复用队列、取消、文件保存与真实完成检测 |
P1 验收包括旧队列迁移、多种素材同时入队、封面去重、音频只有 AAC 轨、字幕时间轴、无素材错误、文件设置快照、筛选记录导出、通知授权拒绝与完成触发。验证范围与结果继续记录在 verification.md。
P1 已实现:32 项测试和静态检查通过,双浏览器构建通过;Chromium 已验证五类输出的真实保存、错误 / 取消 / 重试、设置快照和记录导出。原生通知显示、真实账号素材权限与 Firefox 运行验证仍有边界,见验证记录。P2 的来源分页与缓存 / 断点续传契约已在后续两个阶段落实,见下文。
P2 批量来源(2026-10-05)
P2 首先完成批量来源,随后实现下文的大型任务。浏览器端 512 MB 上限保持不变。 以下为 P2 当时的契约;第 6、7 项的历史范围和会话持久化由文末 P3 扩展。
行为契约
- 下载中心提供链接列表、收藏夹、合集 / 系列、UP 投稿入口。先预览再选择,来源分页由用户点击继续,每份预览最多 500 条。
- 链接列表每行一个 BV / av 号或 HTTPS 完整视频链接,保留
p;无效行单独列出,按视频编号和分 P 去重。av / BV 别名在后台重新解析为 BV 后再次按任务身份去重。 - 收藏夹 / 合集 / 投稿沿用当前浏览器账号权限;固定 API 主机和已知 URL 形状,不接受任意请求地址。API 原始结构经 Zod 校验,不将受限和失效条目伪装成可下载视频。
- 批量读取与入队元数据共用后台串行调度,操作之间至少间隔 1 秒,网络等待不占用队列写锁。风控、登录或网络错误停止本次操作,不自动重试。
- 入队按预览顺序逐视频提交;视频元数据由后台重新读取,多 P 可选择链接指定页或全部页。每个视频原子提交,超过 1000 个活跃任务容量时不提交该视频,保留此前结果。
- 活跃任务始终去重,默认再跳过保留历史中的成功任务,可显式关闭;失败 / 取消记录可重新导入。去重仍按 BV / CID / 素材类型 / 字幕语言,封面按 BV,不以画质区分。成功历史仅来自最近 100 条终态记录,不承诺全量历史或磁盘文件检测。
- 批次开始时固定输出类型、语言、画质和已保存的命名 / 目录设置。停止入队在当前请求后生效,既有下载任务不变;关闭页面后不继续发起新请求。预览仅存在页面内存,不承诺导入会话跨刷新恢复。
- 不增加权限或运行依赖,全部复用现有下载队列、素材导出与保存流程。
模块边界
| 模块 | 职责 |
|---|---|
types/batch | 来源、候选条目和分页响应的边界契约 |
bilibili/batch | 输入识别、来源 API 与分页归一化 |
downloads/batch/jobs | 已下载跳过策略、活跃任务容量与原子创建 |
background/services/downloads | 限速、来源读取、可信元数据复查和串行入队 |
useBatchImport | 预览、选择、分页、选项快照、逐项结果与停止控制 |
download/batch | 来源表单、预览列表、导入选项与组合容器 |
验收覆盖所有来源的分页、无效 / 重复链接、av / BV 别名、隐藏或失效条目、无权限与风控、部分成功、停止入队、容量、设置快照,以及桌面和窄屏布局。实际验证结果见 验证记录。
批量来源已实现:53 项测试和静态检查、双浏览器构建通过;Chromium 验证了模拟来源的完整导入流程及真实 MP4 保存。匿名真实收藏夹 / 系列读取通过,合集 / UP 请求受到 -352 限制,真实登录成功路径与 Firefox 运行仍待补验。
P2 大型任务(2026-10-05)
行为契约
- 浏览器音视频写入 OPFS 不可变小块,只有块文件提交后才原子更新元数据。刷新丢失最多尚未提交的小块;损坏或孤立片段不会混入输出。缓存键包含 BV / CID、媒体类型和整组所选轨道的表示身份,不保存临时 URL。
- 重试重新取流。同资源主机与路径、强 ETag、相同总大小且 Content-Range 严格匹配断点才追加。200 重置前缀,206 / 416 校验,弱或缺失 ETag、变化的轨道或 CDN 安全重下;完整缓存使用条件请求重新确认。媒体地址最多刷新一次。
- FFmpeg 通过 WORKERFS 只读挂载缓存 Blob,减少输入内存复制;输出仍使用 WASM 内存,保留单任务 512 MB 输入预算。估算超限会提前失败并提示本地助手,实际传输也校验总预算。
- 成功 / 主动取消清理缓存,失败 / 中断保留;移除记录后的残留在下载中心空闲时清理。清理和执行共用跨标签页锁。配额不足明确失败,不申请 unlimitedStorage 或自动删除仍可重试的任务。
- 音视频终态任务可导出版本化
.bili.json,重新解析当前账号实际返回的流,保留任务的画质偏好、命名与目录。文件含临时媒体地址,不能当作永久可重放任务或分享凭证;不包含 Cookie。 - Python 标准库助手校验清单、HTTPS CDN 与重定向、路径和本地缓存,流式写磁盘,通过固定参数启动已安装 FFmpeg 无损封装,重名不覆盖。本地任务不受 512 MB 浏览器限制;失败保留断点,链接过期需重新导出。没有后台服务或浏览器与助手状态同步。
- 不新增扩展权限或 JavaScript 运行依赖;用户选择本地助手时自行准备 Python 3 和 FFmpeg。浏览器仍需保持下载中心打开,暂停队列只停止领取下一项。
模块边界
| 模块 | 职责 |
|---|---|
downloads/media/mediaCache | OPFS 块与元数据、损坏恢复、缓存统计和清理 |
downloads/media/fetchCachedMedia | 条件请求、Range 校验、超时、限额和备选线路 |
downloads/media/mergeBrowserMedia | 只读挂载媒体、真实 FFmpeg 封装和 Worker 生命周期 |
downloads/queue/runner | 链接刷新、缓存锁、队列与保存编排 |
downloads/native/manifest、downloads/native/exportNativeTask | 校验导出契约与生成本地任务文件 |
DownloadCache、useDownloadCache | 缓存状态、并发安全清理与大型任务说明 |
DownloadNativeExport、useNativeDownload | 单任务导出状态与生命周期 |
scripts/native-downloader.py | 本地流式下载、磁盘续传与 FFmpeg 合并 |
P3 会话恢复与长期历史(2026-10-05)
依据「查找下一阶段功能规划」聊天,先实现批量会话恢复与长期成功历史。
行为契约
- 保存最近一次批量会话:来源输入、解析后的来源、分页位置、预览、勾选、输入错误和逐项结果。刷新后恢复状态,等待手动继续;读取中的页不会前移,未提交的条目可重试,不会自动发起批量网络请求。
- 首次入队固定素材、语言、分 P 范围、画质和文件设置。恢复时沿用快照,后续默认设置变化不影响继续导入。新的预览产生新会话。
- 会话写入由后台串行处理,并比较版本号。其他窗口的修改不会被旧窗口覆盖;冲突后载入最新会话再继续。会话最多 500 个预览条目、1 MiB,超过时明确报错。
- 入队前和提交时均校验会话、条目与选项。队列与逐项回执通过同一次 storage.local 写入提交;回复丢失后优先返回回执,即使任务已完成、清除或关闭成功去重,也不会再次提交该条目。没有提交任何任务的失败仍可重试。
- 成功记录独立于最近 100 条队列终态,以既有素材身份保存最近一次成功;最多 5000 条 / 3 MiB,超限淘汰最早记录并显示累计数量。只保存用户元数据和任务设置,不保存 Cookie、媒体数据或临时媒体地址。
- 首次使用迁移仍保留的成功队列记录;迁移过的空历史不再自动导入。只有新完成的任务才写入历史,因此删除记录后不会被后续进度更新恢复。清除队列保留独立历史,删除历史不删除磁盘文件。
- 成功历史支持搜索、素材筛选、分页、导出、删除与重新入队。重新入队保留设置快照,创建新的任务 ID 并清除旧执行状态。默认批量去重使用独立历史,显式关闭仍可重新下载,活动任务始终去重。
- 沿用现有扩展权限和运行依赖。存储写入失败明确提示,不能把未保存的会话显示成已保存。存储限额依据 Chrome storage API,成功历史与会话为队列留出空间,不申请 unlimitedStorage。
模块边界
| 模块 | 职责 |
|---|---|
types/batchSession、downloads/batch/session | 会话边界校验、版本比较、恢复与入队回执 |
useBatchImport、download/batch | 草稿保存、来源预览、恢复提示、选项快照和手动继续 |
types/downloadHistory、downloads/history/library | 成功记录迁移、大小约束、身份去重和新任务生成 |
useDownloadLibrary、DownloadLibrary | 成功历史同步、查询、分页、导出与用户操作 |
background/services/downloads | 串行提交、会话回执与队列共同保存、完成状态归档 |
P3 会话与历史验证
P3 本轮验证包括 94 项 JavaScript / TypeScript 测试、25 项本地助手测试、静态检查、双浏览器构建及 Chromium 的会话恢复 / 多窗口冲突 / 长期历史交互。场景和模拟数据边界见 验证记录。
P3 任务控制(2026-10-05)
- 单任务
paused独立于队列暂停,属于活动任务,继续参与容量、去重和缓存保留;不阻塞领取其他等待任务。 - 暂停撤销执行
runId,旧请求和迟到进度不得覆盖暂停或新执行;runner 每个阶段需后台确认后继续,保存阶段拒绝暂停。 - 下载 / 合并暂停保留已提交 OPFS 片段,继续重新解析并验证资源;主动取消清理缓存。刷新恢复不会把暂停项标为失败。
- 等待项可相邻上移 / 下移,后台序列化写入,显示顺序与执行顺序一致。已运行任务不被排序操作移动。
P4 原生助手集成(2026-10-05)
- 使用可选
nativeMessaging权限与白名单宿主,通过标准输入输出通信,不开启本地 HTTP 端口。注册脚本由用户手动运行,Chrome / Firefox 分别声明扩展 origin / ID;扩展不会自行安装宿主。 - 已暂停或终态音视频任务可交接,后台分配独立执行令牌并进入
native状态,阻止浏览器或另一窗口重复执行同一素材。 - 原生进度及最终路径回传队列,完成后进入长期历史并参与批量去重。取消 / 中断撤销旧执行的回写资格;保持下载中心打开以维持通信。
- 宿主复用现有流式写盘、路径校验、HTTPS CDN 白名单、ETag 与摘要验证、固定 FFmpeg 参数和不覆盖保存。媒体地址过期时请浏览器用原设置重新获取,次数有界,素材身份变化拒绝混合。
- Python / FFmpeg、原生宿主注册及系统环境是可选的使用前提;浏览器单任务 512 MB 输入上限保持不变。配置步骤见 原生助手集成。
P5 素材组合(2026-10-05)
- 视频面板与弹窗保留原单素材模式,组合模式选择视频 / 音频 / 封面 / 字幕 / 弹幕;字幕语言、范围与画质共用既有设置。
- 后台重新获取视频元数据,对全部成员校验后一次写入。按素材身份跳过已活动项;封面每 BV 一份,其余按所选分 P 创建。活动组合的全部成员共同计入 1000 个保留名额,新增任务还需满足 4 MiB 队列预算并预留状态增长空间,超限整组拒绝。
- 新成员记录
bundleId和bundleSize,沿用命名快照,目录固定为视频或 UP 主 / 视频。已存在且被跳过的任务保持原归属,不宣称也归档到本组合。 - 下载中心汇总进度和保存、失败、取消、缺失数,只有成员全部保存才显示整组完成。重试仍按单素材沿用原设置。
- 活动组合的终态成员不会被最近 100 条历史或清除记录丢弃;完成组合按整组淘汰,最新组即使超过 100 条仍完整保留,最大 1000 条。
发布验收
自动检查与本地浏览器场景见 验证记录。真实登录权限、真实 CDN 长时间续传、GB 级压力、Windows 助手以及可运行的 Firefox 实机仍需相应环境补验,不能用模拟测试或构建通过代替。
参考
取流实现参考:yt-dlp:只把实际返回的流当作可下载资源。
Chrome storage API:设置持久化与跨上下文更新。
OPFS(MDN):私有磁盘存储与配额。
HTTP 条件与 Range 语义(RFC 9110):强校验器和部分响应。
Emscripten WORKERFS:只读 File / Blob 挂载。