dsh-bili-subtitle
DeepSeek Harness 插件:直读 B 站官方 AI 字幕(WBI 签名 + 扫码登录),支持分 P、时间切片,md→PDF/DOCX 一键下载
- Stars
- 0
- Language
- Python
- Created
- Oct 26, 2026
- Updated
- Oct 26, 2026
Introduction
dsh-bili-subtitle
给 DeepSeek Harness 用的 B 站 AI 字幕直读插件:给一个 BV 号 / 视频链接 / b23.tv 短链,直接拿到这个视频的官方 AI 字幕(ai-zh)逐字稿,可选按时间切片,再一键导出 PDF / DOCX 并给出本机下载链接。
不借助任何第三方下载站、不抓网页 DOM:自己算 WBI 签名,直接读播放器接口 x/player/wbi/v2。
为什么需要登录
从 2023 年起 B 站对匿名用户隐藏字幕:/x/player/wbi/v2 里 need_login_subtitle: true,subtitles 数组是空的。所以这个插件带一套扫码登录流程,把 cookie 存到 ~/.dsh/bili-cookies.json(SESSDATA / bili_jct / DedeUserID 等),之后的字幕请求都带着它。
工具
bili_subtitle(url, start?, end?, timestamps?)
| 参数 | 类型 | 说明 |
|---|---|---|
url | string,必填 | BV 号、完整 B 站链接,或 b23.tv 短链 |
start / end | number,可选 | 只要某一段,单位秒 |
timestamps | boolean,默认 true | 每段前加 [m:ss] 时间码 |
返回 { bvid, title, duration, chapters, count, text };chapters 来自视频自带的 view_points(精华章节),可以用来把长视频切成「第几组」。
内部流程:
b23.tv 短链 → 取 Location 拿 BV
→ x/web-interface/view?bvid= # aid / cid / 分P / view_points
→ 若 >1 个分P,按 cid 取指定 P
→ WBI:nav 接口拿 img_url/sub_url → mixinKey 置换表 → 签名
→ x/player/wbi/v2?bvid=&cid=&w_rid=&wts=
→ data.subtitle.subtitles[] 里挑 ai-zh
→ aisubtitle.hdslb.com/json {"body":[{"from","to","content"}]}
bili_login_qr(output?)
生成登录二维码 PNG(~/.dsh/bili-login-qr.png),返回 { path, qrcode_key }。纯手写二维码编码器(qr_gen.py,只用 zlib 手搓 PNG,不依赖 qrcode/Pillow)。二维码约 3 分钟过期。
bili_login_poll(key, timeoutMs?)
轮询扫码状态(86101 未扫 / 86090 已扫待确认 / 0 成功 / 86038 过期),成功后把 cookie 写入 ~/.dsh/bili-cookies.json。返回 state 与保存路径。
bili_export(md, formats?)
把整理好的 Markdown 导出成可下载文件:
| 参数 | 类型 | 说明 |
|---|---|---|
md | string,必填 | 源 .md 路径 |
formats | string[],默认 ["pdf","docx"] | 可选 pdf / docx / md |
- PDF:reportlab(A4、中文、表格、代码块),依赖同目录
md2pdf.py+libs/; - DOCX:纯 OOXML 手写(
md2docx.py,zipfile +document.xml),不依赖 python-docx; - 起一个只监听
127.0.0.1:8099的静态服务(serve_root.py),返回http://127.0.0.1:8099/get/<文件名>直链,响应头带Content-Disposition: attachment与 RFC 5987 的filename*,点一下就落盘、中文名不乱码。
返回 { files: [{ name, path, bytes, url }] }。
安装
cd ~/.dsh/profiles/web
git clone <this-repo> plugins/dsh-bili-subtitle
ln -s ../plugins/dsh-bili-subtitle node_modules/dsh-bili-subtitle
# package.json 里加 "dsh-bili-subtitle": "file:./plugins/dsh-bili-subtitle"
# cordis.patch.yml 末尾加:
# - insert:
# - id: bili-subtitle
# name: dsh-bili-subtitle
装完热加载即生效。首次使用先 bili_login_qr → 手机 B 站 App 扫码 → bili_login_poll。
cookie 只落在本机
~/.dsh/bili-cookies.json,不随仓库分发。
目录
dsh-bili-subtitle/
├── index.js # 插件主体:WBI 签名、view 接口、字幕抓取、QR 登录
├── export.js # bili_export:md→pdf/docx + 本地静态服务
├── qr_gen.py # 纯 zlib 手写二维码 PNG
├── md2pdf.py # Markdown → PDF(reportlab)
├── md2docx.py # Markdown → DOCX(纯 OOXML)
├── serve_root.py # 127.0.0.1 静态文件服务(attachment 下载)
└── libs/ # vendored reportlab 4.2.5 + PIL 桩 + 少量辅助
已知限制
- 只取 AI 字幕(
ai-zh);UP 主上传的人工字幕走的是另一套(subtitle_url指向aisubtitle之外的 CDN),未覆盖。 - 字幕必须登录;没登录时直接报错提示先扫码。
- 分 P 视频必须按 cid 取对 P,否则只会拿到第一个 P(常见坑:选组视频的第一个 P 只有十几句)。
- B 站的 AI 字幕本身有错字(人名、专有名词),拿到后仍需人工校对。
bili_export的下载服务是临时的(进程随会话走),重启后旧链接失效。
许可
MIT。libs/reportlab 为 ReportLab 的 BSD 授权代码;libs/PIL 是本仓库自带的桩实现。