关于 bug2context
bug2context 将 Bug 录屏整理为带时间戳的 Markdown 时间线,供 AI Agent 阅读,并整合关键帧、OCR、设备日志和语音旁白。它面向排查视频所示问题的开发者,可在本地处理,且各处理阶段均可选。
主要功能
- 01生成带时间戳的视频时间线
- 02提取并去重关键帧
- 03识别屏幕文字
- 04对齐 Android logcat 日志
- 05可选转录语音旁白
适用场景
- 01结合 logcat 检查崩溃录屏
- 02查看用户发送的屏幕录制
- 03定位相关画面和屏幕错误
MCP 相关
MCP 服务提供分析视频、获取单帧图像和列出已处理数据包的工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 1 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ocr | boolean | 否 | |
| workdir | string | 否 | |
| max_frames | any | 否 | |
| video_path | string | 是 | |
| transcribe_audio | boolean | 否 |
详细介绍
bug2context
将 bug 的屏幕录像转换为结构化的时间顺序上下文,让 AI Agent 能够真正读取。
截图会丢失来龙去脉:bug 转瞬即逝,静态画面没有时间线,日志和旁白也完全在别处。大模型无法处理视频。此工具会将录像提炼为一份 Markdown 时间线——关键帧、屏幕文字、设备日志和语音旁白,全部以同一时钟为准。
- 无需 SDK。 适用于任何视频,包括别人通过 WhatsApp 发给你的视频。
- 本地优先。 数据不会离开你的设备。无需账户、API 密钥或云服务。
- 原生支持 MCP。 Claude Code 会将其作为工具调用;你只需指定文件即可。
uvx bug2context # guided menu
uvx bug2context process bug.mp4 --out bundle/
不带参数运行时会打开菜单——录制 Android 设备、处理已有视频,或列出之前生成的报告包——并将内容写入 ~/.bug2context/,MCP 服务会在此查找。以下标志可以调用它的所有功能;菜单只是让你不用记住这些标志。
输出内容
- `[00:00]` 🖼 `frames/frame_001_00-00.png` — start of recording
OCR: Cart 2 items
- `[00:04]` 🖼 `frames/frame_002_00-04.png` — screen changed
OCR: Applying discount..
- `[00:04]` 📋 W/DiscountEngine: rate field missing
- `[00:06]` 🖼 `frames/frame_003_00-06.png` — screen changed
OCR: TypeError: cannot read 'rate'
- `[00:06]` 📋 E/RideService: NullPointerException at RideRequest.kt:142
- `[00:06]` 📋 F/AndroidRuntime: FATAL EXCEPTION: main
- `[00:06]` 🎙 "ahí está, explota al aplicar el descuento"
完整运行示例见 examples/report.md。
bundle/
├── report.md the chronology above
├── frames/ the key frames, named by timestamp
└── meta.json the same data, structured, for programmatic use
安装
需要将 ffmpeg 添加到 PATH(brew install ffmpeg)。
uvx --from 'bug2context[ocr]' bug2context # OCR: Apple Vision on macOS, tesseract elsewhere
uvx --from 'bug2context[ocr,audio]' bug2context # plus spoken narration
也可以从源代码安装:
git clone https://github.com/emanueld92/bug2context
cd bug2context
uv sync --extra ocr --extra audio
每个阶段都是可选的,缺少时会自动降级且不会报错:没有 OCR 后端仍可获取帧,没有音轨仍可生成视觉时间线。
在 Claude Code 中使用
claude mcp add bug2context -- uvx --from 'bug2context[ocr]' bug2context-mcp
如果使用本地克隆:uvx --from /path/to/bug2context bug2context-mcp。
然后直接提出请求:“分析这个 bug 视频:~/Desktop/crash.mp4”。
| 工具 | 用途 |
|---|---|
analyze_bug_video | 视频 → 时间顺序报告(直接返回文本) |
get_frame | 获取一帧图像,供 Agent 查看 |
list_bundles | 列出之前处理过的报告包,按时间从新到旧排列 |
报告包默认保存至 ~/.bug2context/<video>-<timestamp>/。
Android:一条命令同时录屏和采集 logcat
uv run bug2context record --seconds 60 --package com.example.app --out bundle/
录制期间重现 bug。两路数据都从同一个主机时间戳开始——正是这个时间基准,才能让堆栈跟踪与显示崩溃的画面对应起来。
请传入 --package。 在真实手机上,仅按级别筛选并不足够:一次 2 分钟的录制收集到 7,634 条 W/E/F 日志,但没有一条来自被测应用——它们全是 AppOpsControllerImpl、GNSSMGT 等进程的日志。限定到应用进程后,只剩 35 条。无论进程为何,都会保留崩溃标签(AndroidRuntime、DEBUG),因为崩溃报告才是重点。
日志会先不加筛选地采集,再进行范围筛选,因此即使应用崩溃后重启,也会记录其崩溃过程。连续重复的相同条目会合并为一条,并附上 (×N) 计数——框架日志常常会成批出现,每批多达 15 条。
已经有日志文件?可以将它合并到任意视频中:
uv run bug2context process bug.mp4 --logcat logcat.txt --log-tag RideService
支持读取 -v time 和 -v threadtime 两种格式。--log-levels 默认值为 WEF,--log-max-lines 默认值为 80;日志按严重程度排序,因此达到上限时,不会为了保留启动日志而丢掉崩溃日志。若已知进程,可用 --log-pid 限定范围。如果设备时钟与录制器不一致,--log-offset 可将所有日志按 N 秒偏移;如果没有提供 --video-started-at,则以第一条日志为时间基准。
screenrecord 最长录制 3 分钟,因此 record 会拒绝更长的录制,而不是返回被静默截断的视频。按 Ctrl-C 可安全地提前结束录制——会先在设备上完成文件收尾,因为直接终止本地 adb 会留下 ffprobe 无法打开的文件。
超过 10 分钟的视频会被拒绝,并显示用于剪辑视频的 ffmpeg 命令(可通过 --max-duration 0 覆盖此限制)。除时间外,其他开销都不会随视频时长急剧增长,但仍呈线性增长:仅解码一项,速度约为实时的三分之一。
旁白
uv run bug2context process bug.mp4 --transcribe --language es
默认关闭:首次使用时会下载模型,而且这是最慢的阶段;大多数录制也没有语音旁白。如果没有音轨,或音轨音量低于 −50 dB,则会自动跳过——whisper 会在静音中编造听起来很可信的句子,因此这一保护措施是为了保证输出质量,而不仅仅是提速。
如何选择帧
ffmpeg 会生成过多候选帧(场景切换和固定间隔采样,因此不会跳过缓慢变化的屏幕),随后通过感知哈希合并近似重复帧。--max-frames 会限制结果数量,始终保留开场帧,之后保留变化最大的帧。
| 标志 | 默认值 | 说明 |
|---|---|---|
--scene-threshold | 0.08 | ffmpeg 判定切换所用的场景分数 |
--interval-seconds | 1.0 | 未检测到切换时的强制采样间隔 |
--max-frames | auto | 每 2 s 一帧,数量介于 20 到 40 之间 |
--phash-distance | 4 | 低于此值时,帧视为重复 |
--ocr-upscale | 2 | OCR 前放大;宽度超过 1600 px 时跳过 |
端到端测得的 OCR 时间:
| 来源 | 结果 | 用时 |
|---|---|---|
| 合成视频,3 min,1080×1920 | 19 帧 | 8.5 s |
| Android 录屏,2 min,720×1612 @ ~12 fps | 118 个候选帧 → 20 帧 | 16 s |
| macOS 录屏,90 s,2880×1864 @ 60 fps | 97 个候选帧 → 18 帧 | 86 s |
识别出的文本会按帧内容缓存在 ~/.cache/bug2context/ 中,因此对同一视频使用不同设置重新运行时,只需处理实际发生变化的部分——在一段 44 s 的视频上测得,冷运行耗时 9.0 s,热运行耗时 3.3 s,输出相同。两次提取同一视频会得到逐字节相同的帧,因此缓存是安全的。删除该目录即可重置缓存。
Retina 桌面录屏是最慢的情况,原因无法规避:成本来自以 60 fps 解码 5.4 megapixel 的画面(26 s),再加上 OCR;Vision 无论图像大小如何,每帧都需约 1.6 s。此类录屏的处理时间大致要按实时计算;手机录屏则远低于此时间。
关于 --ocr-upscale:一帧经重新压缩的 1080×1920 画面中的堆栈跟踪,在 1× 时被识别为 Null PointerSxception Ride Requestkt14,在 3× 时则被正确识别为 NullPointerException Ride Request kt 142。对于重新压缩严重的来源,请调高此值——请对方发送视频文件,而不是 WhatsApp 视频。对于宽度已达 1600 px 或更大的帧,会跳过放大;在这些帧上,放大没有带来可测量的改善,却会为每帧生成 5760×3728 的图像。
OCR 还会过滤掉碎屑而非文本的行,例如 »、.lll (100 4,以及误读的状态栏时钟。在一次真实录屏中,这过滤掉了 210 行报告中的 41 行,且没有误删真实文本。看起来像错误的信息绝不会被过滤。
已知限制
感知哈希比较的是视觉结构。它能识别导航界面、对话框和错误横幅,但无法检测布局相同、仅有少量文本变化的情况——在 1080×1920 画面上测得,无论哈希大小如何,这类差异都处于噪声下限之内,因此没有任何 --phash-distance 值能够将其区分开来。
OCR 无法弥补这一点:它只处理通过去重的帧,因此已经合并的屏幕不会被读取。测得对每个候选帧都进行读取,一段 3 min 的视频要耗时 48–59 s,会占满整个时间预算。如果你的 bug 确实是相同屏幕上的少量文本变化,请录制裁剪后的画面或降低分辨率,让文本占据画面更大的区域。
开发
uv sync --extra ocr
uv run pytest -q
共 183 项测试。设备录制会有意进行模拟——测试套件不应录制任何人的手机。Whisper 通过 BUG2CONTEXT_TEST_WHISPER=1 选择性启用,以确保测试套件保持离线。
许可证
MIT——参见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。