mcpField
V
vidin

vidin

本地服务
github.com/teunlao开发工具32 周前更新

关于 vidin

vidin 将视频转换为带标注的关键帧、时间线和联系表,供编码 Agent 检查屏幕录制。它按屏幕变化选取稳定画面,并通过 MCP 工具按需提供完整帧。

主要功能

  1. 01按屏幕变化提取稳定关键帧
  2. 02生成带时间线的文字报告
  3. 03为变化区域添加标注框和时间戳
  4. 04按编号或时间范围获取完整帧
  5. 05以更高帧率重新提取片段

适用场景

  1. 01分析屏幕录制中的错误复现过程
  2. 02定位视频中出现错误的时间点
  3. 03查看关键帧之间仍不清楚的片段

MCP 相关

向 MCP 客户端提供视频分析、关键帧获取、片段放大提取和视频探测工具。分析结果先返回报告与联系表,之后可按需获取完整帧。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"teunlao-vidin": {
"command": "npx",
"args": [
"-y",
"@teunlao/vidin"
]
}
}
}
启动命令npx -y @teunlao/vidin

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@teunlao/vidin0.1.0

工具

4

收录的工具列表 · 更新于 2 周前

参数类型必填说明
sourcestring是本地视频文件的路径,或 http(s) URL(使用 yt-dlp 下载)。
out_dirstring否帧、图像集、REPORT.md 和 manifest.json 的写入位置。默认为视频所在目录下的 .vidin 文件夹。
profileenum否bug-report(默认,均衡) · dense(短片,捕捉每次细微变化) · walkthrough(长时间录制,减少帧数) · cheap(最小化上下文占用)。bug-report | walkthrough | dense | cheap
max_framesinteger否保留帧数的硬性上限。优先丢弃信息量最少的帧。
sensitivitynumber否必须发生变化才能计为事件的屏幕占比。值越低,越容易捕捉细微变化,并生成更多帧。默认值为 0.4。
include_sheetboolean否将联系表作为图像返回。默认值为 true。

详细介绍

vidin

将视频转换为编码 Agent 能够实际读取的内容。

Claude Code、Codex 等工具接受图像,但不接受视频。因此,当 Bug 报告以屏幕录制的形式出现时,视频就成了累赘——必须有人观看视频,再重新输入发生了什么。vidin 会代劳:它将录制内容转换为一组带注释的关键帧和一份书面时间线,并通过 MCP 提供给 Agent。

将 20 秒的录制内容精简为六个带注释的画面

输入一段 20 秒的录制内容,输出六个画面:退款面板、500 对话框、重试提示、恢复过程——每个画面都标有方框和时间戳。(该片段是 vidin 的合成测试素材。)

  • 由事件驱动,而非每秒取一帧。 屏幕发生变化并趋于稳定时,就会保留一帧。有人阅读三分钟几乎不会产生开销;每个实际的 UI 事件都会被捕获。
  • 速度快。 在 M 系列 Mac 上,处理一段 1080p、3 分钟的录制内容约需 4 秒。处理一小时的视频只耗时,不额外占用 RAM。
  • 一条命令即可运行。 npx @teunlao/vidin——它对机器的唯一要求是 ffmpeg;无需 sharp、无头浏览器或原生图像库。
  • 专为 Agent 上下文设计。 MCP 工具首先返回书面报告和一张联系表;只有确定值得查看的时刻,才会返回完整细节的画面。
  • 可跳转查看的时间戳。 Agent 可以说“错误出现在 00:41.2”,你就能直接跳到原始文件中的对应位置。

快速开始

brew install ffmpeg        # + yt-dlp, only if you'll pass URLs

将其接入 Claude Code:

claude mcp add vidin -- npx -y @teunlao/vidin mcp

也可以使用 .mcp.json / ~/.codex/config.toml 等价配置:

{
  "mcpServers": {
    "vidin": { "command": "npx", "args": ["-y", "@teunlao/vidin", "mcp"] }
  }
}

或者直接从 shell 运行:

npx @teunlao/vidin ~/Desktop/bug.mov       # → ./.vidin/bug/
npm i -g @teunlao/vidin                    # or put `vidin` on PATH for good
vidin https://example.com/screencast.mp4   # downloaded with yt-dlp
vidin zoom bug.mov --from 00:41 --to 00:45 --fps 6
vidin probe bug.mov

输出内容

out/
  REPORT.md        the entry point: timeline table, what changed where, what to open
  manifest.json    the same, machine readable
  sheets/          the whole video as labelled 3x3 grids (~1.3k tokens each)
  frames/          full-detail annotated frames

带注释的画面:错误对话框周围有红色虚线框,底部有时间戳栏

每个画面都会在自上一个保留画面以来发生变化的区域周围标出红色虚线框,并在底部栏显示画面编号、原始视频中的时间戳、与上一个画面的间隔、保留该画面的原因,以及屏幕变化的比例。

MCP 工具

提供四种工具,旨在让 Agent 按合适的顺序使用上下文:

工具功能
analyze_video视频 → 磁盘上的画面;返回报告文本和一张联系表图像
get_frames按编号或时间范围获取完整细节的画面,并设有上限,避免单次调用淹没上下文
zoom_clip以更高帧率重新提取一小段窗口——用于查看仅凭两帧无法解释的时刻
probe_video查询时长 / 分辨率 / fps / 音频,开销很低

建议的流程:分析 → 查看联系表 → 阅读时间线 → 打开两三个画面 → 如果这些画面之间的时刻仍不清楚,就放大查看。如果一开始就全部打开,在还不知道哪一秒值得关注之前,上下文就会被消耗殆尽。

配置预设与调优

配置预设用途
bug-report默认预设——有人录下屏幕、讲述 Bug,然后停止录制
dense适用于每个细微变化都很重要的短片段(以 24 fps 分析,最多 80 帧)
walkthrough适用于较长的录制内容;帧数更少,锚点间隔更宽
cheap适用于上下文确实紧张时,占用最少资源(以 1092px 分辨率提取 12 帧)

无需离开当前配置预设即可调优:--max-frames、--sensitivity(被视为事件的屏幕变化百分比,数值越低 = 画面越多)、--fps、--width、--quality、--no-annotate、--no-sheets。

为什么选择帧,而不是切片

每秒截取一张屏幕截图,会让 3 分钟的视频变成 180 帧,其中约 90% 都是相同的,因为视频中的人一直在阅读、思考或移动鼠标。这些重复帧本身成本不高,却会淹没少数真正发生了变化的帧,Agent 必须逐一查看才能找出它们。帧选择本质上是一个伪装成成本问题的信噪比问题。

vidin 采用事件驱动方式。它以 12 fps 的速度遍历视频,并在缩小后的 RGB 画面中,仅在确实发生变化时保留帧:

  • 变化是相对于上一个已保留帧来衡量的,而不是相对于前一个采样帧,因此缓慢的漂移会逐渐累积,不会被阈值掩盖。
  • 帧会在变化之后截取,而不是在变化过程中截取。 动作开始时不会立即输出任何帧——选择器会等待画面稳定下来,再保留稳定后的帧。这样你看到的是点击之后的状态,而不是模糊的动画画面。
  • 颜色也算变化。 比较是逐通道进行的,而不是基于亮度。字段变红,或灰色面板上弹出绿色提示,这些变化对亮度的影响很小,却正是错误报告所关注的内容。
  • 移动鼠标不会产生成本,这是通过计算得出的,而非特殊处理:在分析分辨率下,指针变化比事件阈值低一个数量级。过去曾有一个用于识别指针的子系统;在真实录制中测量后发现,它从未改变任何判断,因此已被移除。
  • 防护措施。 最小间隔、长时间静止期间的锚点帧、长动画播放期间的周期性采样,以及硬性预算(默认为 40 帧)。超出预算时,会优先丢弃信息量最少的帧,同时保留时间线两端的帧。

无论帧通过何种路径产生,以下两条原则始终成立:

  • 不会悄无声息地丢弃任何内容。 比较基线只会在保留帧时向前推进。不存在将发生变化的画面并入基线却不输出该帧的路径——否则变化将无法恢复,因为之后的每次比较都会相对于一个你从未看到的状态得到零变化。
  • 注释描述的是实际可见的相邻帧。 帧预算裁剪时间线中间部分后,系统会重新计算每个保留帧相对于当前前一帧的变化百分比和框。

工作原理

ffmpeg ─raw RGB @12fps, 400px─ selector ──timestamps+regions── ffmpeg ──annotated WebP
         one decode pass,         event state machine            drawbox/drawtext
         streamed                 in plain TypeScript            per frame

解码时每次流式处理两帧;选择器还会保留已保留帧的缩小版缓冲区,以便在裁剪后重新计算它们的差异。这部分内存受帧预算限制,而非视频长度限制:默认配置下约为 32 MB。所有绘制都由 ffmpeg 滤镜完成,因此 package.json 中不需要图像库。

开发

开发使用 Bun;运行时代码本身只使用 node: API,因此发布的包可以在任何支持 npx 的环境中运行。

git clone https://github.com/teunlao/vidin && cd vidin && bun install
bun test

测试夹具是一个带脚本化时间线的合成屏幕录制——包含一个面板、一个错误对话框、一条提示、一次恢复,以及两段仅有指针移动的片段。测试套件会断言每个预设事件恰好产生一帧稳定画面,并且仅有指针移动时不会产生任何帧。test/regressions.test.ts 会构建自己的片段,并固定所有审查过程中发现的故障,因此修复后的错误会一直保持修复状态。

尚未实现

  • 音频转录。 旁白是 Bug 报告中信号最强的部分。 计划:使用本地 Whisper(whisper.cpp 或 mlx-whisper)生成与帧时间线对齐的 transcript.md。
  • 对保留帧进行 OCR,这样 Agent 无需消耗任何视觉 Token,就能搜索错误消息。
  • 不会报告指针位置和点击——这是有意为之。 我们用真实录制内容验证过绘制的 十字准线,发现其准确率大约只有一半:不断增长的 DevTools 请求列表会向下移动, 其方式与指针完全相同。错误标记会以掷硬币般的概率断言“用户指向了这里”,而且 指针本来就清晰可见于画面中。
  • 不会检测水平滚动,但会检测垂直滚动。
  • 较小的元素需要调整参数。 默认事件阈值为屏幕面积的 0.4%,因此低于此阈值的 进度条或徽章不会单独构成事件。使用 --sensitivity 0.2 或 --profile dense 可以捕获这些元素,但会增加帧数。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。