DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

cctv2333 /

cctv2333/dsh-vidlens

Verified

DSH plugin: 18 local tools that watch a public video the way a person does - metadata, chapters, timestamped frames, subtitle-first transcripts, and 527-class sound events - without downloading the whole video.

★ 0 Stars0 Forks3 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@d871f1bf

VidLens for DeepSeek Harness

ci npm PyPI DSH plugin MIT

把 vidlens 从一个 stdio MCP 外壳变成 DSH 原生插件:18 个 vidlens_* 工具、图片直接进对话、按工具设超时、外加三个零下载的缓存工具。

工程本体(Python)没有改一行逻辑:插件通过一个常驻桥进程调用 vl_mcp.py 里已经测过的工具函数,所以 MCP 外壳和插件的行为不会漂移。

  • 工程仓库(Python + MCP 服务器):https://github.com/cctv2333/vidlens
  • 本仓库(DSH 插件):https://github.com/cctv2333/dsh-vidlens
  • 插件要求:vidlens >= 1.4.0(video_soundscape 起)、Node ≥ 20、DSH >=0.2.1-rc.2 <0.3.0
用户: 这个视频讲了什么? <url>
  → vidlens_meta      0 下载:值不值得看
  → vidlens_plan      0 下载:切章节,挑 2–3 段
  → vidlens_window    只下这一窗的音频(或直接读缓存/字幕)
  → vidlens_sheet     只下这 20 秒,拼图带时间码,图直接附在结果里
  → vidlens_brief     平台字幕优先;无字幕才下音频做本地 ASR
  → vidlens_soundscape 台词之外的声音(吃饭/敲击/水声),带概率

相对 MCP 外壳的增强

能力 MCP 外壳 本插件
工具名 mcp__vidlens__video_meta vidlens_meta(短、可读)
超时 客户端一个全局 60s 每个工具自带预算(vidlens_brief 15 分钟,vidlens_scan 15 分钟)
图片 取决于客户端是否支持 MCP image content 走宿主 attachments.saveImage,成为持久图片附件,同轮就能看
缓存意识 无 vidlens_library(零网络列缓存)、vidlens_seek(零网络查原话)
批量筛选 无 vidlens_compare(最多 8 个链接,0 媒体下载)
行为约束 只在 MCP instructions 里 独立的 system-prompt 小节:先 meta→plan→抽样,绝不下整片
取消 断开连接 exec.signal 取消时重启桥进程,不留下卡死的下载
整片下载 video_full(confirm=true) 存在 故意不提供:需要画面就用 sheet/frames/scan

安装

前置:先有一份 vidlens。 二选一:

pipx install "vidlens-mcp[all]"          # 推荐:无 checkout,命令叫 vidlens / vidlens-mcp
# 或
git clone https://github.com/cctv2333/vidlens && cd vidlens && install.cmd

然后装本插件(三选一):

# A. 本地目录(开发)
plugin_manager action=install_bundle target=D:\vidlens\vidlens-mcp-dsh

# B. GitHub 直装(本包无 build/prepare 脚本,不需要 allowBuilds 权限)
dsh plugin --profile desktop add github:cctv2333/dsh-vidlens#<sha>

# C. npm(发布后)
dsh plugin --profile desktop add dsh-vidlens

插件会自动找 Python 工程:<本包>/../vidlens → D:\vidlens\vidlens → $VIDLENS_PROJECT; 找不到时按 $VIDLENS_PYTHON / .venv / python 依次尝试。PyPI 安装的形态下, 把 projectDir 指到 pipx 的 venv 或直接设 VIDLENS_PROJECT 都行(模块名不变)。

安装后这个 bundle 会插入一行 Host 插件:

- insert:
    - id: dsh-vidlens
      name: 'dsh-vidlens'
      config: {}

想改成别的工程位置(例如换机器)就在 config 里写:

- insert:
    - id: dsh-vidlens
      name: 'dsh-vidlens'
      config:
        projectDir: D:\path\to\vidlens
        pythonPath: D:\path\to\vidlens\.venv\Scripts\python.exe
        warm: true

字段都可省略:projectDir 默认依次取 <本包>/../vidlens、D:\vidlens\vidlens、$VIDLENS_PROJECT;pythonPath 默认取工程 .venv 里的解释器。

工具(18 个)

基础四件(0 下载)

工具 用途
vidlens_meta(url) 标题/UP主/时长/播放/平台字幕/平台标注音乐 + 注入风险扫描
vidlens_plan(url, window=300) 按切点/长静音分章节 + 建议顺序
vidlens_subs(url, lang=zh) 平台字幕(人工优先,其次自动/AI)
vidlens_library(limit=20, query='') 新增:本地缓存清单,避免重复下载

读内容

工具 下载量 用途
vidlens_window(url, start, end) 0(有缓存/字幕)或该窗音频 某时间窗的台词与停顿
vidlens_brief(url, ...) 平台字幕 0;无字幕才下音频 完整证据报告(结构/停顿/低置信词/广告段落/风险)
vidlens_seek(query, url='') 0(新增) 在缓存转写里按关键词查原话 → 时间码
vidlens_audio(url, start, end) 该段音频 SenseVoice 语种/情感/事件 + 节拍与能量
vidlens_soundscape(url, start, end) 该段音频 新增:AudioSet 527 类声音事件(吃饭/敲击/水声/碰撞…)+ 概率 + 时间码

看画面(图片直接进对话)

工具 下载量 用途
vidlens_sheet(url, start, end, cols, rows) 该段(20s≈0.9MB) 带绝对时间码的拼图
vidlens_frames(url, at=[...]) 该段 最多 6 张精确帧(读小字用)
vidlens_scan(url, n=24) 最低画质整片(7min≈14-21MB,用完即删) 全片抽样拼图(无音频视频)

判断 / 长视频 / 自检

工具 用途
vidlens_comments(url, limit=40) 评论区互动比、正负面、争议度、高赞评论 + 评论配图
vidlens_compare(urls=[...]) 新增:批量元数据对比(0 媒体下载,最多 8 个)
vidlens_job_start(url, ..., full=False) 长视频后台任务,立即返回 job_id
vidlens_job(job_id, wait_seconds=20) 轮询阶段/百分比,完成返回报告
vidlens_models(action=list) 本地模型目录与硬件建议(只读,不自动下载)
vidlens_doctor() 自检 python/ffmpeg/yt-dlp/依赖/模型/磁盘/网络

架构

DSH Host (index.js)
  ├─ 18 × ctx.tools.register(...)        原生工具 + 每工具 timeoutMs
  ├─ ctx.systemPrompt.section('vidlens') 取样协议(meta→plan→抽样)
  └─ Bridge (常驻)  ──stdin/stdout JSONL──▶  python -u bridge/vidlens_bridge.py
                                                │
                                                ├─ import vl_mcp   (复用工具函数)
                                                ├─ import vidlens_web / _extra / _sanitize
                                                └─ out/<id>/        (缓存,进程重启不丢)

为什么不是直接把 MCP 服务器挂上来:MCP 客户端只有一个全局工具超时,长视频 ASR 会被误杀;图片是否进模型取决于客户端实现;也拿不到「缓存清单 / 关键词定位」这类只在本地才有答案的能力。桥进程把「已验证的 Python 逻辑」和「宿主的原生能力」接在一起,两边都不用重写。

协议(每行一个 JSON)

// 启动
{"op":"ready","ok":true,"pid":1234,"project":"D:\\vidlens\\vidlens","python":"3.12.10","tools":["meta",...]}
// 请求 → 响应
{"id":7,"tool":"sheet","args":{"url":"...","start":"0","end":"20"}}
{"id":7,"ok":true,"text":"...","images":[{"path":"...jpg","mediaType":"image/jpeg","name":"sheet_0_20000.jpg"}]}
{"id":8,"ok":false,"error":"ValueError: ...","trace":"..."}

sys.stdout 在导入任何库之前就被指向 stderr,所以依赖里的杂散 print 不可能污染协议;桥只把帧写进保存下来的真实 stdout。

多进程安全:DSH 会话、MCP 服务器、插件桥是不同进程,进程内 threading.Lock 互相看不见。 工程侧用 vidlens_web.CrossProcessLock(进程内 RLock + out/.media.lock 文件锁,msvcrt/flock) 把「一个下载口」扩展到整台机器;超时可用 VIDLENS_LOCK_TIMEOUT(默认 900s)调整。 实测两个进程同时调 video_sheet:第二个的 acq 时间落在第一个 end 之后(串行,不互相踩)。

验证

离线(不联网、不下媒体)

node D:\vidlens\vidlens-mcp-dsh\tools\selftest.mjs
# 96/96 checks passed(工具表 + 桥握手 + library/models/seek + 强制杀进程后自愈)

带真实链路(约 1MB 媒体)

node D:\vidlens\vidlens-mcp-dsh\tools\selftest.mjs --live
# 98/98 checks passed

安装后在 DSH 里的实测(本机 2026-10-25,全部走原生工具通道)

调用 结果
vidlens_library(limit=6) 9 个缓存视频,标题/时长/段数/来源/占用/时间齐全(out/ 里的 bili/、comment_pics/ 等非视频目录已自动排除)
vidlens_doctor() 11/11:python 3.12.10、ffmpeg 7.1、yt-dlp 2026.10.21、4 个依赖、whisper 461MB、磁盘 332GB、B站 API 200
vidlens_meta(BV1PinG6fEPX) 真实标题/UP主/139514 播放;正确报出「字幕需要登录」
vidlens_plan(window=120) 3 章节,0 下载
vidlens_window(02:10–02:25) asr(cached),0 下载直接读缓存
vidlens_seek("宪法") 3 条原文 + 时间码(00:20.460、02:17.720…),0 网络
vidlens_sheet(60–72s, 3×2) 下载 12 秒,产出 1440×540 拼图,图片作为持久附件进入对话(时间码 00:00:59.995 … 00:01:09.594)
vidlens_frames([63, 68]) 2 张 960×540 帧,同一条结果里两张图都在
vidlens_compare(2 个链接) 一张 markdown 表,0 媒体下载
vidlens_job_start → vidlens_job 起任务拿到 job_id=6652ac4e,轮询后返回完整 brief(asr(cached),含低置信词/停顿/广告段)
vidlens_meta(错误 URL) 可读错误:ERROR: meta failed rc=1: ... HTTP Error 404,工具不崩

拼图实测(时间码烧在每格左上角):

contact sheet

发布(维护者)

  • CI:.github/workflows/ci.yml —— 会 checkout 两个仓库(本插件 + cctv2333/vidlens 作为兄弟目录), 装 Python 核心后跑离线自检;另外两个 job 校验 manifest 可发布、tarball 含 bridge/ 与 LICENSE。
  • 发版:打 tag 即发布 npm。
git tag v1.2.0 && git push origin v1.2.0

release.yml 会 npm pack、npm publish --access public,走 Trusted Publishing(OIDC)—— CI 里没有任何长期 token。npm 的 publisher 只能在包存在后配置,所以首次发布要在本地做一次 (npm stage publish → npm stage approve,全程不需要把 token 交给 CI,见 RELEASING.md),之后打 tag 即可。

注意:PowerShell 5.1 不支持 &&,用 ; 或分行。

实现笔记

  • output.schema 不能用 {type:'json'}:宿主对工具输出 schema 做严格校验,只接受 object/array/string/number/integer/boolean/null。第一版用了 {type:'json'},安装直接 application: failed(JsonSchemaError: unsupported JSON schema)。现在写成显式的 object schema(text + images[])。
  • 被杀掉的旧进程不能污染新进程:超时/取消会 kill() 工作进程并在同一 tick 重建。旧 进程的 exit 事件是异步到的,必须先判 this.child !== child 再清理,否则它会把新 进程上排队的请求全部 reject(这个 bug 是自检里的「强制杀进程后自愈」用例抓到的)。
  • 本插件不导出 Config:Config.listConfigs 里这一行显示 status: absent(没有配置 schema),但 config: 里的 projectDir / pythonPath / warm 仍会原样传给 apply()。 不导出 schema 是刻意的:schema 需要 schemastery,而插件的解析链未必能找到宿主那份 @deepseek-ai/schemastery;宁可少一个设置表单,也不要一个「载入期 import 失败 → 18 个工具整体消失」的失败模式。
  • 图标:icon.svg 是原创矢量图(2042 字节,well-formed XML,256×256,边缘圆角 + 时间码刻度 + 镜头环 + 播放三角)。结构校验通过;Plugin Manager 里的实际渲染效果 没有在浏览器里验证(无头浏览器对 file: / data: 导航超时),这一项留待用户目视确认。

路线图

产品级路线图(已做 / 未做 / 验收标准 / 不做清单)在工程仓库: vidlens/ROADMAP.md。

插件专属待办,按工作量从小到大:

  1. Config schema(现在 status: absent,只能手改 YAML)
  2. /vl <url> 斜杠命令
  3. present 交付物卡片(brief.md / 拼图)
  4. 右侧栏 Web 面板(缓存列表 + brief 预览 + 时间轴)
  5. 设置页(模型路径 / 代理 / cookie)

边界与已知限制

  • job 状态在进程内存:vidlens_job_start 起的任务,桥进程重启(超时/取消/宿主重启)后会消失;已下的缓存不丢,重跑即可。
  • 取消 = 杀桥进程:Python 侧没有协作取消,所以被取消/超时的调用会重启工作进程(缓存在磁盘上,代价很小)。
  • 需要 cookie 的站点(抖音、B 站 AI 字幕)默认不碰:按报错提示设 VIDLENS_COOKIES_FROM_BROWSER=edge 或 VIDLENS_COOKIES=path\cookies.txt。
  • 不下整片:video_full 故意没有移植。整片画面需求用 vidlens_scan(最低画质、用完即删)。
  • PyPI 形态也能接:工程装成 wheel 后没有 vidlens.py 旁边的 checkout 标记,插件的 目录嗅探找不到它;把 config.projectDir 指到 pipx 的 venv 目录(或任意含 vidlens.py 的目录),或设 VIDLENS_PROJECT 即可。安装形态下 out/ 会落在 %LOCALAPPDATA%\vidlens\out。
  • Windows 优先:工程默认路径与 .venv\Scripts\python.exe 是 Windows 习惯;Linux/macOS 用 projectDir + pythonPath 显式指定即可(跨进程锁在 POSIX 用 flock)。
  • 工程本体仍无 LICENSE,公开分发前需项目所有者选定;本包 license 标为 UNLICENSED。
—/ 5

No ratings yet

Verified DSH bundle

Commit d871f1bfe9c5

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout