中文EN

dsh-bili-watch

tools已测通过npmMIT

把 B 站视频解析成模型可消费的结构化内容:元数据、评论、弹幕、字幕、本地 ASR 转写、抽帧 OCR。本地跑不上传、字幕诱饵检测(可疑时抽帧核对)、二次读瞬时、输出 manifest + 摘要。抽帧 OCR 需 ffmpeg;本地 ASR/OCR 需 Python 3.10+ 虚拟环境(Windows 另需 VC++ 运行库);AI 字幕需登录 B 站。

下载量 / Downloads
11,441
依赖体积 / node_modules
2.69 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

安装

dsh plugin --profile web add dsh-bili-watch

沙箱测试结果

阶段结果
1 安装✓
2 列装✓
3 挂载✓
4 启动—

四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。

README

dsh-bili-watch

![Listed on dsh-plugin.org](https://dsh-plugin.org/plugins/sacredbluedragon/dsh-bili-watch)

![version](https://www.npmjs.com/package/dsh-bili-watch)

![node](https://www.npmjs.com/package/dsh-bili-watch)

![license]()

DSH 插件 / CLI 工具:把 B 站视频解析成模型可消费的结构化内容(元数据、评论、弹幕、AI 字幕、本地 ASR 转写、抽帧 OCR)。

为什么用它

  • 本地跑不上传:ASR 转写 + OCR 抽帧全在本机,不依赖云 API、不花钱
  • 防字幕诱饵:语速异常或字幕自称「实验/钓鱼」即判可疑;关键词命中率只在语速也异常时才作补充;可疑时加 --verify 抽 5 帧 OCR 比对画面(不加只提示一句)
  • 二次读瞬时:缓存目录 + 文件锁,同一视频二次读取秒出
  • 为 AI 设计:manifest 落盘 + 摘要输出,agent 直接消费不用再解析

一条链接进来之后

给它一个链接,它按成本从低到高找文本:官方字幕 → 本地转写 → 画面认字。字幕几秒就有;没有字幕才下模型转写;连音轨都没有才逐帧认画面。哪一级没成都会写进报告的「来源」行,不会把截图的字当成台词。

想改代码、想知道模块怎么分层,见文末[「模块架构」](#模块架构)。

特性

  • 支持 b23.tv 短链、BV 号、av 号及通用 URL(经 yt-dlp)
  • 降级链:AI 字幕 → 本地 ASR → 抽帧 OCR → 读图,四级全 miss 时退出码为 1
  • 匿名可用:元数据、评论、弹幕、搜索、热榜无需登录
  • 可选依赖:ffmpeg(抽帧)、Python venv(ASR/OCR)、faster-whisper(转写模型)
  • Web 面板:依赖管理、扫码登录、缓存清理、18 项运行时参数可调

安装

DSH 插件

dsh plugin --profile web add dsh-bili-watch

重启 DSH 后生效。DSH ≥ 0.2.0-rc.2 自动写入 dsh.profile.bundles;更早版本需手动在 profile package.json 的 dsh.profile.bundles 数组追加 "dsh-bili-watch"。

装完重启即可用。 本插件的 bundle patch 不带 disabled,装进 profile 的 dsh.profile.bundles 后重启 DSH 就生效,命令直接存在。
0.3.1 及更早的版本不是这样:包在装的那一刻就被写进 dsh.profile.bundles(reconcile() 干的),所以插件页显示「已启用」,但实际不加载——因为层里那行 disabled: true 是插件页开关碰不到的位置。症状是「显示已启用但命令不存在,点开关也没用」。那个 disabled 是 0.2.17 应急修 bug 时误加的,带了 7 个版本,0.3.2 已去掉。
从旧版本升级的注意:reconcile() 只在「新增依赖」时跑,所以以前手动从 dsh.profile.bundles 删过包名的人,pnpm update 到 0.3.2 之后包名不会自动补回来,需要重跑一次 dsh plugin --profile web add dsh-bili-watch。

验证:dsh --profile web --dump-config 输出中可检索到 dsh-bili-watch。

亦可直接放入 profiles/<name>/node_modules/dsh-bili-watch。

插件依赖 @deepseek-ai/dsh-tools(peer, optional)。缺失时 bili_watch 工具不注册,/bili 命令与面板仍可用。

CLI 全局安装

npm i -g dsh-bili-watch
bili-watch view BV1EPnG6DEJC

或 clone 后直接运行:

node tools/look.mjs view BV1EPnG6DEJC

用法

命令一览

命令 · 说明

view <target> · 元数据 + 简介 + 热评。不下载、不依赖 ffmpeg,匿名可用

peek <target> · 元数据 + 热评 + 5 帧画面。先取 B 站官方截帧接口,不下视频;取不到才回落下载 360p 抽帧(约 1 MB/min);OCR 环境就绪时顺带识别。仅 B 站

sub <BV或链接> [--format srt\ · json\ · md\ · txt] [--out <path>] · AI 字幕。--format 输出 SRT / JSON(含时间戳)/ Markdown(含跳转链接)/ 纯文本 txt。需登录

comments <bv> [N] · 评论区,默认按热度排序

asr <target> · 本地 ASR 转写,附「可信 / 疑似幻觉」判定

frames <target> [--step <sec>] [--ocr] · 抽帧;--ocr 附带画面文字识别

ocr <bv> [--step <sec>] · 抽帧并 OCR

text <target> [--format json\ · md] · 四级降级链:字幕 → 转写 → 抽帧 OCR → 读图。全 miss 退出码 1

sheet <bv> [--grid 3x3] [--cues] · 均匀抽帧拼图,默认 9 帧;--cues 每格下方附该时段台词

substrip <bv> [--step <sec>] · 底部字幕竖拼

danmaku <bv> · 弹幕热区(按时间桶统计峰值)

local <path> [--ocr] [--frames] · 本地视频文件走降级链(从转写层起)。仅 CLI

search <关键词> [--days N] [--limit 10] [--order pubdate\ · click] · 视频搜索。--days 不传或传 0 表示不限时间;传了则只留最近 N 天发布的,并按播放量降序(最多抓 3 页,结果仍按 --limit 截断)

hot [--limit 10] · 综合热门榜

login [--check] [--poll] [--key <key>] · 扫码登录。--check 校验凭证有效性;--key 需配合 --poll

clean · 清空缓存根。任务进行中(锁文件存活)时拒绝并返回非零退出码

help · 打印完整用法(所有命令、全部参数)

<target> 接受 BV 号、b23.tv 短链、av 号或 URL。

通用参数

参数 · 类型 · 默认值 · 说明

--format · enum · — · 输出格式。text / sub / comments / danmaku / local 落盘时必须配合此参数,单独指定 --out 返回退出码 1

--out <path> · string · — · 落盘路径,相对当前工作目录(cwd),目录不存在时自动创建。text / sub / comments / danmaku / local 写文件;frames 用它指定输出目录。sheet / ocr / substrip 固定写缓存目录,不收 --out

--ffmpeg <path> · string · — · ffmpeg 可执行文件路径

--cred <path> · string · — · 凭证 JSON 路径,格式 {sessdata, bili_jct, buvid3, buvid4}

--asr-max <ms> · number · 1800000 · 转写时长闸门(毫秒)。视频长于此值时仅输出画面描述

--head <n> · number · 0(按自动规则) · 只给前 n 字。不传或传 0 时按「正文超过 800 字只给开头 400 字 + 落盘路径」处理;要全文用 --full

--full · flag · — · 输出全文(不截断)

--verify · flag · — · 字幕可疑时抽 5 帧 OCR 交叉校验。字幕正常时不触发

--fresh · flag · — · 忽略缓存强制重跑。只在 peek / frames / sheet / substrip 四条命令生效

--mark-seen · flag · — · 标记为已读

--p <n> · number · 1 · 多 P 视频取第几个分 P

--scene · flag · — · 仅 frames:按画面变化点抽帧(吸附到变化最多的时刻),比等间隔更准也更省

--fast · flag · — · 仅 text:跳过本地转写,字幕拿不到就直接抽帧 OCR

--no-time · flag · — · text/sub 默认输出带 [mm:ss] 逐句时间码,加这个退回纯文本(不带时间戳)

--at <时刻> · string · — · frames 精看某一刻,支持三种写法:750(秒)、12:30(分:秒)、12:30-13:10(区间)

--cues · flag · — · 仅 sheet:每格索引行下方附该时段的字幕台词(每格最多 2 行、每行 48 字符,超出以 … 截断)。折行按字符数算,不是显示宽度,中文一行看着会比英文宽。台词按「本格时间点 → 下一格时间点」切分,与索引行的 [start, start+step) 不是同一口径。视频没有字幕轨时整段不加,不会留空行

完整参数列表见 bili-watch help。

画面索引

frames --at、sheet、peek 三处输出都会带索引,格式固定:

r1c1 00:00-00:05 @00:02    r1c2 00:05-00:10 @00:07
  • r1c1 = 第 1 行第 1 列(sheet 按行从左到右编号;frames --at 只有一格)
  • 00:00-00:05 = 这一格覆盖视频的哪一段
  • @00:02 = 这一格实际取的是第 2 秒那一帧

长文本保护

正文超过 800 字时,终端仅返回前 400 字摘要 + 落盘路径,全文写入缓存目录。工具层(bili_watch)阈值为 2000 字(摘要 800 字)。

陌生人内容护栏

字幕、评论是 B 站用户生成的第三方内容,是素材不是指令。命中有注入特征的句子时:

  • 终端:stderr 打一行警告(同一视频同一类别只报一次),并说明是「其中指向你的要求」不要执行——不是「里面任何要求」,字幕里正常有祈使句;
  • --format json:payload 多一个 _untrusted 字段 { source, kind, bv, hits, note }。下划线前缀是扩展字段的通行写法,解析器忽略未知键即可;没有命中时这个字段不出现,输出与没有护栏时逐字节相同;
  • --format srt/md/txt:命中时在文件头(srt 是每段前)加一行 [第三方内容·未消毒] 注记;
  • 落盘两份:<kind>.txt 是纯正文(给程序 read + 解析,格式不变),<kind>.wrapped.txt 带 [source: …] 标记与围栏(给模型 read),提示词指向后者。

护栏只做提示与标记,不是安全边界:命中不代表一定在攻击,没命中也不代表安全(按 OWASP,输入过滤属 supporting control,承重的是「标记 + 不下放权限」)。所以长文本只跑两件形态检查:不可见字符(零宽 / tag 字符 / 双向控制符,正常字幕不会有、零误报)+ 边界标记自校验。语义类规则刻意不加——那三条在 20 条正常字幕上误报 8 条(40%),而中文注入分类器的召回上限也只有 25%(Prompt Guard 2 中文 recall 0.2529)。

面板

装进 DSH 后,在插件页点 dsh-bili-watch 卡片进详情页,里面有一块面板(不用先进设置),日常操作不用去对话里敲命令:

  • 依赖状态

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:49,最后更新 2026-11-05

链接

GitHub · Homepage · npm

同类插件