Files
bili-downloader-web/README.md
T

5.0 KiB
Raw Blame History

BiliDownloader

哔哩哔哩视频下载器 —— Python 零依赖本地服务 + shadcn/ui 界面 + Edge 应用模式窗口

这是弃用 WinUI3 后的重构版。旧版(C# / WinUI3,位于 E:\deepseek\BiliDownloader)能编译能跑, 但需要 MSIX 打包且本机存在 WinUI3 启动限制;这一版改成浏览器界面,双击即用、无运行时依赖。

启动

双击 start.cmd —— 它会起本地服务并打开一个 Edge 应用模式窗口(无地址栏、无标签页,看起来就是独立应用)。

停止:双击 stop.cmd。

也可以手动:

python server.py            # 起服务并自动开窗口
python server.py --no-open  # 只起服务,自己用浏览器打开 http://127.0.0.1:8799/

功能

  • 站内搜索:WBI 签名的官方搜索接口,卡片列表展示封面 / 标题 / UP主 / 时长 / 播放量
  • 粘贴链接或 BV 号直接解析
  • 清晰度可选:按真正能下到的流列出(不是标称支持),默认最高
  • 多线程加速下载:文件切段并发下载(默认 16,可调 1~64),断线按分片续传,支持跨进程断点续传
  • 实时进度:SSE 推送,总体 + 视频流 + 音频流三条进度、实时速度、速度曲线、ETA
  • ffmpeg 无损封装为 mp4,产物文件名带清晰度
  • 深浅色主题(默认深色)并记忆

架构

BiliDownloaderWeb/
├─ start.cmd / stop.cmd      双击启动 / 停止
├─ server.py                 本地 HTTP 服务(标准库 http.server,只监听 127.0.0.1)
│                            JSON API + SSE 进度推送 + 托管前端产物
├─ engine.py                 下载引擎(已实测验证的核心逻辑)
│    ├─ WBI 签名的站内搜索
│    ├─ 视频详情 / 分P / 清晰度
│    ├─ 多线程分段下载(Range 分片 + 每片重试 + 旁路状态文件续传)
│    └─ ffmpeg 封装
├─ config.json               sessdata / outputDir / threads / preferAvc / keepParts
├─ ui/                       React 19 + Tailwind 4 + Vite 7 + shadcn/ui(new-york)
│    └─ src/{App.tsx,components/,lib/}
└─ tools/                    验收脚本
     ├─ smoke_api.py         后端 API 冒烟
     ├─ e2e_download.py      端到端下载验收(含 ffprobe 与全片解码校验)
     └─ ui-check.mjs         浏览器端验收(Edge 无头 + CDP,真的驱动一次搜索)

为什么是"本地薄服务 + 浏览器界面":前端需要跨域访问 B 站 API、需要写本地磁盘、需要用 ffmpeg, 浏览器自己做不到,所以后端必须存在;而这层后端用 Python 标准库就够,零第三方依赖, engine.py 里那套逻辑也已在上一轮里逐项实测过。

验收结果(都是实测,非推断)

后端 API(tools/smoke_api.py)

项 结果
站内搜索 numResults=1000,返回 20 条,封面 URL 正常
视频详情 标题/UP主/时长/分P 全部正确
清晰度列表 按 dash.video 实际流构建

端到端下载(tools/e2e_download.py)—— 13/13 通过

产物: [4K]当你用《航拍中国》的方式打开崂山育才——航拍育才 [480P标清].mp4
大小: 11.2 MB    流: h264 852x480 + aac
时长: 90.0s(源 91s)    全片解码: 无错误
速度: 峰值 15.9 MB/s,16 线程    耗时: 2.0s
中间文件: 已清理

浏览器界面(tools/ui-check.mjs,Edge 无头 + CDP)—— 18/18 通过

其中包含真的驱动界面:填入关键词 → 触发提交 → 等结果渲染(21 个卡片)→ 点选第一个 → 等清晰度解析 → 断言「开始下载」可点。另有:React 挂载、深色主题生效、无横向溢出、零脚本错误。

两个必须知道的坑(都踩过)

1. 清晰度列表必须取 dash.video,不能取 accept_quality

accept_quality / support_formats 只反映视频标称支持什么,与当前账号能否下载无关。 实测:未登录时 accept_quality 仍列出 120(4K),但 dash.video 里只有 32(480P)。 按前者建列表会让用户选到根本拿不到的清晰度,点下载才报错。

2. 产物文件名必须带清晰度

否则同一视频下不同清晰度会互相覆盖 —— 实测踩过:480P 的验收下载把之前下好的 4K 文件直接盖掉。

配置

config.json(与 server.py 同目录):

{
  "sessdata": "...",
  "outputDir": "E:\\deepseek\\downloads",
  "threads": 16,
  "preferAvc": true,
  "keepParts": false
}

threads 实测:16 线程约 4.1 MB/s,32 线程约 6.8 MB/s;过高可能触发 CDN 限流。

⚠️ sessdata 等同于账号登录凭据,明文存在本机。别把这个目录分享给他人。 未登录/失效时 B 站只放出 480P 及以下,界面会明确提示。

重新构建前端

cd ui
npm install          # 首次
npm run build        # 产物到 ui/dist,由 server.py 托管
npm run dev          # 开发模式(热更新,代理 /api 到 8799)