# 安装与使用 从零到“发个链接就能聊”的完整步骤。全程不需要改 PATH、不需要管理员权限、不装后台服务。 > 适用:Windows 10/11 + DeepSeek Harness(DSH)桌面版 `0.2.1-rc.x` + Node ≥ 20。 --- ## 一、装什么(三样,后两样可选) | 组件 | 必需? | 作用 | 体积 | |---|---|---|---| | 插件本体 | **必需** | 阀门 + 抽帧 + 通道分类 | 50 KB | | ffmpeg | 要读**本地视频**才需要 | 解码、抽帧、转 16k 音频 | 88 MB | | whisper.cpp + 模型 | 要**无字幕视频的台词**才需要 | 本地语音识别(音频不出机器) | 11 MB + 465 MB | 只读 B 站的话,**插件本体就够**——分镜图和字幕都走公开接口,不需要 ffmpeg。 --- ## 二、拿代码 ```powershell git clone https://github.com/PoiFlos/dsh-video-gate.git cd dsh-video-gate ``` 没有 git 就点仓库页的 **Code → Download ZIP** 解压。 --- ## 三、目录怎么摆 插件会按**相对位置**去找 ffmpeg 和 whisper,所以推荐这种摆法(`<工作区>` 是你放代码的目录): ``` <工作区>\ ├── dsh-video-gate\ ← 本仓库 │ ├── index.js │ ├── lib\ │ └── ... └── tools\ ← 自己新建,不进仓库 ├── ffmpeg\ │ └── ffmpeg.exe └── whisper\ ├── whisper-cli.exe ├── whisper.dll ggml.dll ggml-base.dll ggml-cpu-*.dll └── models\ └── ggml-small.bin ``` 找不到也会退到环境变量和 PATH,详见第六节。 ### 3.1 装 ffmpeg 下载来源与 **sha256 校验值**见 [`provenance-ffmpeg.md`](provenance-ffmpeg.md)。 下完先核对,再放到 `tools\ffmpeg\ffmpeg.exe`: ```powershell (Get-FileHash .\ffmpeg.exe -Algorithm SHA256).Hash ``` ### 3.2 装 whisper.cpp(可选) 来源、文件清单、两个模型的哈希都在 [`provenance-whisper.md`](provenance-whisper.md)。 要点:只留 `whisper-cli.exe` 和它加载的 12 个 DLL,**不要 `whisper-server.exe`**(那是个本地 HTTP 服务,纯属多余攻击面)。 模型放 `tools\whisper\models\ggml-small.bin`(465MB)或 `ggml-medium.bin`(1.46GB,更准更慢)。 ```powershell (Get-FileHash .\models\ggml-small.bin -Algorithm SHA256).Hash ``` --- ## 四、装进 DeepSeek Harness DSH 里让 agent 执行(推荐): ``` plugin_manager action=install_bundle target=<你的路径>\dsh-video-gate ``` 或者用命令行: ```powershell dsh plugin --profile desktop add <你的路径>\dsh-video-gate ``` 装完**重启一次 DSH 桌面版**。Host 插件模块是启动时加载的,不重启不生效。 验证:问 agent「看一下视频通道状态」,它应该返回: ``` 视频通道阀门(只读) - 本地文件:开 - Bilibili:关 ``` --- ## 五、首次配置 配置文件在 `%USERPROFILE%\.dsh\video-gate\state.json`,不存在就是默认值。第一次用建议写一次: ```json { "version": 1, "channels": { "local": true, "bilibili": false }, "localRoots": ["D:\\素材", "C:\\Users\\<你>\\Videos"], "auditLog": true } ``` | 字段 | 说明 | |---|---| | `channels.local` | 本地文件通道,默认 `true` | | `channels.bilibili` | B 站通道,默认 `false`;也可以运行时用弹窗临时放行 | | `localRoots` | **本地文件允许的根目录**。不填就是“当前工作目录 + `~/Videos`”,基本等于没法用,所以务必填 | | `auditLog` | 每次放行/读取写一行到 `~\.dsh\video-gate\audit.jsonl` | `localRoots` 是安全边界:不在这些目录下的文件,插件直接拒绝,模型也没法绕。 --- ## 六、找不到 ffmpeg / whisper 时,按这个顺序找 | 组件 | 查找顺序 | |---|---| | ffmpeg | `state.json` 的 `ffmpegPath` → 环境变量 `FFMPEG_PATH` → `<插件目录>\..\tools\ffmpeg\ffmpeg.exe` → `<插件目录>\..\..\tools\ffmpeg\ffmpeg.exe` → PATH 里的 `ffmpeg` | | whisper | `whisperCli` / `whisperModel` → `WHISPER_CLI` / `WHISPER_MODEL` → `<插件目录>\..\tools\whisper\` 下的 CLI 与 `models\ggml-medium.bin` / `ggml-small.bin` | 不想摆目录,就在 `state.json` 里直接写绝对路径: ```json { "ffmpegPath": "E:\\bin\\ffmpeg.exe", "whisperCli": "E:\\bin\\whisper-cli.exe", "whisperModel": "E:\\bin\\ggml-small.bin" } ``` --- ## 七、日常怎么用 ### 7.0 先唤醒(每次开新会话都要一次) 在对话框里发这一句: > **启用读取视频插件** 插件会在后台收到这句话并启用,**不需要点任何按钮**。之后同一个会话里: - 发 B 站链接 → 弹阀门 - 发本地路径 → 直接抽帧 - 说“没字幕,听听在说什么” → 本地 whisper 转写 想关掉: > 关闭读取视频插件 状态随时可查:`/video`,或问「看一下视频通道状态」。 这是**会话级**开关——重启 DSH 或开新会话后要重新说一次;插件本身常驻,不需要重装。 ### 7.1 读一个 B 站视频 你只要把链接丢进来: > 这条讲了什么?https://www.bilibili.com/video/BV1xx 第一次会弹选择框,四个选项: | 选项 | 含义 | |---|---| | 只放行这一次 | 读完即失效,不写盘 | | 本会话放行 | 这次对话里不再问 | | 长期打开 Bilibili | 写入 `state.json`,重启后仍然有效 | | 保持关闭 | 拒绝本次读取 | 放行后返回:标题 / 时长 / 公开字幕(有就给文本)/ 分镜帧(每 5 秒一格,480×270,带烧录字幕)。 ### 7.2 读本地视频 > 把 D:\素材\拍摄.mp4 第 3 分钟那段看看 返回 720p 抽帧。想指定时间点,agent 会传 `at: [180, 190, 200]`。 ### 7.3 没字幕的视频要台词 > 这段没字幕,听听在说什么 agent 会传 `transcribe: true`,本地 whisper 返回带时间码的文本: ``` [0:00] 这是一段测试音频,用来验证本地语音识别是否正常工作。 ``` **音频不出机器**:先在本地被 ffmpeg 转成 16kHz 单声道 wav,再交给 whisper-cli。 单次最多处理前 15 分钟;普通桌面 CPU 上 7 分半的视频约 2–3 分钟。 ### 7.4 开关通道 > 把 Bilibili 通道关掉 agent 调 `video_valve`,弹确认框,你点“关掉(拒绝读取)”。 `/video` 命令只显示当前状态,不改开关。 ### 7.5 阀门窗口(独立小程序,不是对话框) 如果你不想每次都在对话里点弹窗,可以开一个**真正的桌面小窗口**,随时勾选开关: | 启动方式 | 说明 | |---|---| | 双击桌面 **「视频阀门」** 快捷方式 | 最省事(安装时由 `启动阀门.cmd` 生成) | | 双击仓库根目录的 **「启动阀门.cmd」** | 仓库自带 | | `pythonw gui\valve.py` | 手动启动 | 窗口里就两行开关(本地文件 / Bilibili)、一条「最近发生了什么」、和状态文件路径。 - **改动立即生效**:窗口写 `state.json`,插件每次读取前都会重读,**不用重启 DSH** - 窗口关掉不影响插件,下次再开还是同一个状态 - 勾上 Bilibili = 之后读 B 站**不再弹窗**;取消勾选 = 恢复成“每次都要你点” - 前提:Python 3.10+(Windows 官方安装包自带 tkinter,无需额外装) **关窗口的行为**: | 情况 | 行为 | |---|---| | 装了托盘支持(见下) | 缩到右下角托盘,左键点图标恢复 | | 没装 | 最小化到任务栏,点任务栏图标恢复 | 托盘支持是可选的,双击 **`安装托盘支持.cmd`** 一次即可(把 pystray + Pillow 装进 `gui\_vendor\`,**不动系统 Python**;不想要就删掉那个目录)。 > 注意它和「启用读取视频插件」不是同一层: > 窗口控制的是**通道**(持久,写盘);「启用」控制的是**本会话是否允许读视频**(内存,重启失效)。 > 两层都通过才会读——所以正常顺序是:先发「启用读取视频插件」,再用窗口决定放不放 B 站。 ### 7.6 需要登录才能拿字幕时(可选) 有些 B 站视频的 AI 字幕只对登录用户开放。这时 `video_read` 会直接告诉你: ``` 字幕轨:需要登录才能取(B 站 AI 字幕)。 想拿到完整台词:跟我说「登录 B 站」… ``` 流程: 1. 说 **「登录 B 站」** → 浏览器打开登录页,同时给出取 `SESSDATA` 的步骤 2. 登录后按 F12 → Application → Cookies → 复制 `SESSDATA` 的值 3. 写进 `%USERPROFILE%\.dsh\video-gate\bilibili.cookie`,一行:`SESSDATA=粘贴的值` 4. 回来说 **「登录好了」** → 重新读一次,这次会带上字幕 5. 想撤销:说 **「退出 B 站登录」**(插件删掉那个文件),或去 B 站「退出所有设备」 **安全边界(写死在代码里)**: - 只对 `bilibili.com` / `bili2233.cn` / `bilivideo.com` / `hdslb.com` 带这个值,其他域名一律不带 - 不写日志、不写进对话记录、不发往任何第三方 - 文件在本机,**能读这台电脑的人就能用**——这是它真正的风险,自己权衡 - 不想承担就别放:没有登录态照样能拿标题、分镜帧,只是拿不到 AI 字幕 --- ## 八、卸载 ``` plugin_manager action=remove_bundle target=dsh-video-gate ``` 再删掉 `tools\` 目录和 `%USERPROFILE%\.dsh\video-gate\`(状态 + 缓存 + 审计日志)。 没有别的残留:没装服务、没写注册表、没改 PATH。 --- ## 九、故障排查 | 现象 | 原因 | 怎么办 | |---|---|---| | 工具栏里没有 `video_read` | 没重启 | 完全退出 DSH 再打开 | | 「视频插件还没启用」 | 新会话默认关闭 | 发一句「启用读取视频插件」 | | B 站返回「元信息降级:HTTP 412」 | B 站风控 | 正常现象,标题/时长可能缺,分镜帧仍可取;隔一会儿再试 | | 「没取到可用字幕(试了 8 次都不对)」 | B 站 AI 字幕是**按需生成**的:生成好之前,接口会把**别的视频**的字幕递给你 | 正常现象。等一会儿再说「再读一次」(或先在网页上播一下这条视频),生成完成后就稳定了;插件会缓存成功结果,读过一次之后不再请求 | | 登录后仍然没有字幕 | 该视频没有 AI 字幕,或登录态过期 | 说「登录 B 站」重拿一次;或换本地 ASR | | 「路径不在允许的本地根目录内」 | `localRoots` 没配 | 按第五节写 `state.json` | | 「找不到 ffmpeg」 | 二进制没放对位置 | 按第六节的顺序检查,或写 `ffmpegPath` | | 转写很慢 | CPU 推理,正常 | 换 `ggml-small`;或只转写片段;15 分钟是硬上限 | | 转写术语错(WBPP、反卷积…) | small 模型对专有名词弱 | 换 `ggml-medium`,或把转写当参考不当引用 | | B 站视频没字幕、也要不到台词 | 匿名 `playurl` 拿不到音频流 | 这是设计边界:先下载到本地,再走本地通道 | | 窗口关掉后找不到了 | 缩到托盘/任务栏了 | 看右下角托盘图标,或任务栏;托盘需先装 `安装托盘支持.cmd` | --- ## 十、安全边界(为什么可以放心装) - 只允许 **http/https 的公开 GET**,全项目**没有任何 POST** - 域名白名单只有 `bilibili.com` / `b23.tv` / `bili2233.cn`,其余一律拒绝 - 拒绝内网与回环地址(SSRF) - 不读浏览器 cookie、不读注册表、不装任何 Python 包 - 本地文件只能读 `localRoots` 里的路径 - 子进程只用 argv 列表(无 shell),全部带超时 - ASR 全离线,没有 API key、没有上传 它防不了的是**视频内容本身带来的风险**:字幕、标题、画面里的文字都是外部数据,模型可能被其中的指令诱导。 处理陌生视频时,建议把 DSH 的权限预设调回“每次询问”,别用免审批模式。