Files

120 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BiliDownloader
哔哩哔哩视频下载器 —— **Python 零依赖本地服务 + shadcn/ui 界面 + Edge 应用模式窗口**
> 这是**弃用 WinUI3 后的重构版**。旧版(C# / WinUI3,位于 `E:\deepseek\BiliDownloader`)能编译能跑,
> 但需要 MSIX 打包且本机存在 WinUI3 启动限制;这一版改成浏览器界面,双击即用、无运行时依赖。
## 启动
双击 **`start.cmd`** —— 它会起本地服务并打开一个 Edge 应用模式窗口(无地址栏、无标签页,看起来就是独立应用)。
停止:双击 `stop.cmd`。
也可以手动:
```powershell
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` 同目录):
```json
{
"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 及以下,界面会明确提示。
## 重新构建前端
```powershell
cd ui
npm install # 首次
npm run build # 产物到 ui/dist,由 server.py 托管
npm run dev # 开发模式(热更新,代理 /api 到 8799)
```