合并受阻
变更摘要
本次 PR 新增了「摄像头实时观测」技能(camera-observation skill),核心由两段跨平台脚本协作完成:Windows 侧 capture_live.py 持续抓取摄像头画面并切分为短视频片段,WSL 侧 realtime_analyze.py 常驻加载 Mage-VL 模型并轮询分析这些片段、输出实时解说。改动聚焦于摄像头采集的健壮性处理与模型的离线、常驻推理流程。
主要改动
- 新增 Windows 侧采集脚本
capture_live.py:通过cv2.VideoCapture持续读取摄像头,强制使用CAP_DSHOW后端打开,并输出到cam_live/seg_<timestamp>.mp4,按--segment秒切分、以--fps控制帧率。 - 新增抓帧失败重试与无效片段丢弃机制:
cap.read()失败时等待 0.2 秒后重试;片段小于 50KB 或少于 5 帧时调用path.unlink(missing_ok=True)删除该片段并继续,避免空/坏片段进入后续分析。 - 新增 WSL 侧实时分析脚本
realtime_analyze.py:轮询live_dir下的新seg_*.mp4,对每个片段按--num-frames均匀采样帧,调用Mage-VL模型生成解说并通过seen集合避免重复处理。 - 新增模型离线加载与常驻机制:脚本设置
HF_HUB_OFFLINE=1与TRANSFORMERS_OFFLINE=1,使用AutoProcessor、AutoModelForCausalLM一次加载模型后常驻循环监听,analyze_segment中通过torch.inference_mode()进行推理。 - 新增可配置的提示词与采样参数:提供
DEFAULT_QUESTION默认解说提示词(重点识别发光的 LCD 屏、GIF 动图及 LED 灯状态),并暴露--question、--num-frames、--max-new-tokens、--model、--live-dir等命令行参数。


代码审查
我已逐一审查了两个变更文件,共报告 5 个问题。
审查结论
atomcode/skills/camera-observation/scripts/capture_live.py —— 发现 3 个问题:
- P1:直接用最终文件名写入,分析端会读到未完成片段,导致每段画面被永久跳过(核心功能失效)
- P3:
--segment <= 0时外层循环无 sleep,陷入建删空文件的热循环 - P3:未使用的
import os(可选清理)
atomcode/skills/camera-observation/scripts/realtime_analyze.py —— 发现 2 个问题:
- P3:
--num-frames <= 0产生空帧列表,导致每段分析失败 - P3:未使用的
import sys(可选清理)
汇总
- 发现数:P0 0 个,P1 1 个,P2 0 个,P3 4 个
- 总体风险判断:中等偏高。最严重的是生产端/消费端之间缺少"文件完成"的同步机制(原子改名),它会使整个实时分析流水线实际上无法正常工作;其余为参数边界与死代码等次要问题,建议一并修复。
| 类型 | 数量 |
|---|---|
| 🔴 阻塞 | 1 |
| 🟡 建议 | 2 |
⛔ 需要修改


/ai summary


⚠️ 已有 AI 任务正在处理中,请稍候,无需重复触发。


🔵 Low Priority
变更行:capture_live.py:9 import os 在文件中从未被引用,属于死代码/未引用导入,lint 会告警且无任何用途。
建议:删除第 9 行未使用的 import os。


🔵 Low Priority
变更行:realtime_analyze.py:14 import sys 在文件中从未被引用,属于死代码/未引用导入,lint 会告警且无任何用途。
建议:删除第 14 行未使用的 import sys。


🟠 High Priority
变更行:capture_live.py:42 直接用最终文件名 seg_XXXX.mp4 打开 cv2.VideoWriter 持续写入,直到第 53 行 writer.release() 才写入 mp4 的 moov 索引。
受影响行为/契约:realtime_analyze.py:96 用 glob("seg_*.mp4") 轮询并把新文件名立即加入 seen(第 97-99 行),没有任何"文件已完成"判断,默认假设目录里的 .mp4 都是完整片段。
失败模式:两个脚本并行运行时(这正是设计用途),capture_live 每 10 秒持续写一个文件,分析端每秒轮询,必然在文件还在写入时(moov 未写入、CAP_PROP_FRAME_COUNT 返回 0 或只读到前几帧)就把它抓走。此时 analyze_segment 返回"(无法读取片段)"或只分析到残缺帧;更关键的是该文件名已被加入 seen,等 10 秒后文件真正写完也不会再被分析。结果是几乎每一段画面都被永久跳过,整个实时分析流水线失效。
建议:先写入临时文件名(如 path.name + ".part",不会被 seg_*.mp4 匹配),在 writer.release() 后再 tmp_path.rename(path),确保分析端只会看到完整片段。


概述
新增 camera-observation 技能,包含摄像头实时画面捕获(Windows 侧)和 Mage-VL 模型分析(WSL
侧)的双进程管道,模型常驻加载不重复读权重
涉及文件:
关联 Issue
变更类型
测试计划
已验证的 Provider
检查清单