☰
【openclaw实用Skill】camsnap 技能:用 RTSP/ONVIF 把摄像头接进 AI 工作流
2026/10/17 22:07:27 网站建设 项目流程

1. 摄像头画面接进 AI 工作流,卡点到底在哪

camsnap 是 openclaw 技能库里一个专门跟摄像头打交道的命令行工具,核心能力就一句话:从 RTSP/ONVIF 摄像头里抓帧、录片段、做运动检测,然后把画面交给后面的 AI 处理。它适合谁?适合手上已经有网络摄像头、想用命令行批量管理、又想让大模型"看见"实时画面的开发者。你可以把它理解成摄像头和 AI 之间的一根转接线——摄像头负责出流,camsnap 负责取流,ffmpeg 负责转码,AI 负责理解。

但真正动手你会发现,卡点从来不在"装个工具"这一步。我见过太多人卡在三个地方:第一,摄像头地址填错,RTSP 路径少一段就 401;第二,ONVIF 探测能发现设备,但取流时 ffmpeg 报Invalid data found when processing input;第三,画面是拉下来了,可 AI 读不了——因为给的是 H.265 裸流或者时间戳错乱的 TS 片段。这三个问题分别对应发现、取流、转码三个环节,任何一个断了,整条链路就废。

这篇就按"发现问题→准备工具→写配置→验证→排错"的顺序走一遍。重点放在可复制的配置片段和 ffmpeg 参数上,因为这才是你真正会反复改的东西。至于 AI 那一端,我会用 TaoToken 的模型对话接口做演示,把转码后的帧喂进去,确认它真的能"看懂"画面。整条链路跑通之后,你就能把摄像头变成 AI 工作流里的一个普通数据源,跟读文件、调接口没什么区别。

先说清楚一个前提:camsnap 本身不负责 AI 推理,它只负责把画面变成 AI 能吃的格式。所以别指望装完它就能自动识别画面内容,那是下一步的事。它的价值在于把"取流"这件脏活标准化了——设备发现、快照、录片段、运动监控、诊断,全都有对应命令,不用你自己拼 ffmpeg 命令拼到怀疑人生。

2. 前置准备:camsnap 安装、ffmpeg 依赖与 TaoToken 接入

camsnap 的安装走 Homebrew,一条命令的事:

brew install steipete/tap/camsnap

装完先别急着加摄像头,确认 ffmpeg 在 PATH 里。camsnap 的所有取流和转码动作都依赖 ffmpeg,它自己不带解码器:

which ffmpeg ffmpeg -version

如果which没输出,说明 ffmpeg 没装或者没进 PATH,先brew install ffmpeg。这一步看着废话,但后面camsnap snap报ffmpeg not found的时候,你会回来感谢自己提前查了。

接下来是 AI 那一端。camsnap 把画面转成 JPEG 或 MP4 之后,要交给模型处理,我用 TaoToken 的接口来演示。先去控制台拿 Key:

  • 控制台入口:https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_content=console&utm_campaign=rewrite
  • API Key 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api-keys&utm_campaign=rewrite

拿到 Key 之后,Base URL 用https://taotoken.net/api,注意这个地址不带 UTM 参数,是纯 API 端点。模型 ID 按你实际要用的填,比如做视觉理解就选支持图像输入的模型。这三件套——Base URL、Key、Model ID——后面配置里会反复出现,先记牢。

如果你打算长期跑编码或 Agent 类任务,可以顺手看下 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding-plan&utm_campaign=rewrite 。不过这篇的重点是摄像头取流,AI 只是验证环节,所以先用按量接口跑通就行。

环境准备好之后,目录结构建议这样规划,后面配置和输出路径都按这个来:

mkdir -p ~/.config/camsnap mkdir -p ~/camsnap-out/snapshots mkdir -p ~/camsnap-out/clips

配置文件放~/.config/camsnap/config.yaml,输出统一丢到~/camsnap-out下面,这样清理和排查都方便。别把输出目录设成/tmp,重启就没了,调试到一半文件消失很抓狂。

3. 可复制配置:camsnap config.yaml 与 ONVIF 探测命令

camsnap 的配置文件是 YAML 格式,路径固定~/.config/camsnap/config.yaml。最小可用配置长这样:

cameras: kitchen: host: 192.168.0.10 user: admin pass: your_password rtsp_path: /Streaming/Channels/101 onvif_port: 80 door: host: 192.168.0.11 user: admin pass: your_password rtsp_path: /cam/realmonitor?channel=1&subtype=0 onvif_port: 80

这里最容易错的是rtsp_path。不同品牌路径完全不一样:海康常见/Streaming/Channels/101,大华常见/cam/realmonitor?channel=1&subtype=0,通用 ONVIF 设备可能是/onvif1或/live/ch0。填错就是 401 或 404,别怀疑密码,先怀疑路径。

不想手动猜路径,用 ONVIF 探测。camsnap 自带 discover 命令:

camsnap discover --info

它会广播 ONVIF 探测包,把局域网里响应的设备列出来,带上厂商、型号、服务地址。如果这条命令没输出,先确认摄像头和你在同一网段,且 ONVIF 功能是开着的——很多摄像头默认关 ONVIF,要去 Web 后台手动打开。

discover 只能发现设备,拿不到完整 RTSP 路径。要拿路径,用 ONVIF 的媒体服务接口探测。装个onvif-util或者直接用 curl 打 SOAP 请求都行,这里给一个用 curl 探测媒体配置的片段:

curl -s -X POST http://192.168.0.10/onvif/media_service \ -H "Content-Type: application/soap+xml" \ -d '<?xml version="1.0"?> <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"> <s:Body> <GetProfiles xmlns="http://www.onvif.org/ver10/media/wsdl"/> </s:Body> </s:Envelope>' | grep -o 'rtsp://[^<]*'

返回里会带rtsp://开头的完整地址,把它拆成 host + path 填进 config.yaml。注意 ONVIF 返回的地址可能带认证信息,填配置时把 user/pass 单独拆出来,别整段塞进 rtsp_path。

配置写完后,用 add 命令再确认一遍(它会校验连通性):

camsnap add --name kitchen --host 192.168.0.10 --user admin --pass your_password

如果 add 成功但 snap 失败,八成是 rtsp_path 的问题,回到上面重新探测。这一步别偷懒,路径对了后面全顺。

4. 验证请求:ffmpeg 转码参数与 AI 读取画面

配置就绪后,先抓一张快照验证取流:

camsnap snap kitchen --out ~/camsnap-out/snapshots/shot.jpg

成功的话会返回文件路径。用file和identify确认它是张真图,不是 0 字节的壳:

file ~/camsnap-out/snapshots/shot.jpg identify ~/camsnap-out/snapshots/shot.jpg

identify会输出分辨率,正常应该是 1920x1080 或 1280x720 之类。如果报identify: no decode delegate,说明文件是坏的,回去查 RTSP 路径。

快照通了,再录一段片段验证帧率:

camsnap clip kitchen --dur 5s --out ~/camsnap-out/clips/clip.mp4 ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate,codec_name -of default=nw=1 ~/camsnap-out/clips/clip.mp4

avg_frame_rate应该是 25/1 或 30/1。如果显示 0/0 或者帧率极低,说明取流不稳,可能是网络抖动或者摄像头编码参数太激进。这时候手动用 ffmpeg 转码一遍,把流规整成 AI 友好的格式:

ffmpeg -rtsp_transport tcp -i "rtsp://admin:your_password@192.168.0.10/Streaming/Channels/101" \ -vf "fps=1,scale=1280:-1" \ -c:v libx264 -preset ultrafast -crf 28 \ -t 5 ~/camsnap-out/clips/normalized.mp4

几个参数解释一下:-rtsp_transport tcp强制走 TCP,避免 UDP 丢包导致的花屏;fps=1把帧率降到 1 帧每秒,AI 处理图像不需要 30 帧;scale=1280:-1限制宽度,减少 token 消耗;libx264+ultrafast保证转码速度。这套参数实测下来,5 秒片段转码不到 1 秒。

转码完抽一帧出来,喂给 TaoToken 的模型对话接口验证 AI 能不能读:

ffmpeg -i ~/camsnap-out/clips/normalized.mp4 -vframes 1 ~/camsnap-out/snapshots/frame.jpg

然后用模型对话接口把这张图传进去。模型对话入口:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=chat&utm_campaign=rewrite 。请求体大致这样:

{ "model": "your-vision-model-id", "messages": [ { "role": "user", "content": [ {"type": "text", "text": "描述这张监控画面里有什么"}, {"type": "image_url", "image_url": {"url": "data:image/jpeg;base64,<base64>"}} ] } ] }

Base URL 用https://taotoken.net/api,Header 带Authorization: Bearer <你的Key>。如果模型能返回画面描述,说明整条链路通了:摄像头→camsnap→ffmpeg→AI。这一步是整个流程的验收点,别跳过。

5. 常见报错排查:401、local proxy failed 与 reading choices

排错这块我按真实遇到的报错来列,每个都给定位思路。

401 Unauthorized:出现在 camsnap snap 或 ffmpeg 拉流时。九成是密码错或 rtsp_path 错。先确认密码里有没有特殊字符(@、:、#要 URL 编码),再确认路径。海康的 101 是主码流,102 是子码流,填错也能连上但可能没画面。

local proxy failed:这个报错通常出现在 AI 请求环节,不是摄像头环节。意思是请求没发出去,本地网络或代理配置有问题。检查 Base URL 是不是写成了https://taotoken.net/api(别多加斜杠或路径),检查环境变量里有没有残留的HTTP_PROXY。如果你在容器里跑,确认容器能出网。

reading choices 相关报错:这类报错一般出现在解析模型返回时,说明返回体不是预期的 JSON 结构。常见原因是模型 ID 填错,接口返回了错误信息而不是正常响应。先单独用 curl 打一次模型对话接口,看原始返回:

curl -s https://taotoken.net/api/chat/completions \ -H "Authorization: Bearer <你的Key>" \ -H "Content-Type: application/json" \ -d '{"model":"your-model-id","messages":[{"role":"user","content":"hi"}]}'

如果返回里带error字段,按提示改模型 ID 或 Key。如果返回正常但你的代码解析失败,检查是不是把流式响应当非流式解析了。

OAuth 相关报错:如果你用的是 Claude Code 或 Codex 这类带 OAuth 的工具,报 OAuth 失败通常是 token 过期或回调地址不匹配。这类工具接入时同样要配全三件套:Base URL、Key、Model ID。以 Codex 的auth.json为例,配置片段:

{ "base_url": "https://taotoken.net/api", "api_key": "<你的Key>", "model": "your-model-id" }

Claude Code 的 settings 里同理,Base URL 填https://taotoken.net/api,Key 填控制台拿的那串,Model ID 按需选。三件套缺一个就连不上,别只填 Key 不填 Base URL。

ffmpeg 报 Invalid data found:取流成功但转码失败,通常是编码格式问题。H.265 流用默认参数可能解不了,加-c:v libx264强制转 H.264。或者加-fflags +genpts修复时间戳。

帧率为 0 或极低:网络问题居多。先ping摄像头看延迟,再ffprobe看原始流帧率。如果原始流就低,去摄像头后台调编码参数;如果原始流正常但转码后低,检查-vf fps=参数是不是设太小。

排错的核心思路是分段验证:先确认摄像头本身能出流(用 VLC 拉一下 RTSP),再确认 camsnap 能取到,再确认 ffmpeg 能转,最后确认 AI 能读。哪一段断了就修哪一段,别一上来就怀疑 AI。

6. 把摄像头变成 AI 工作流的常规数据源

整条链路跑通之后,camsnap 的价值才真正体现出来:它把摄像头抽象成了一个命令行可调用的数据源。你可以写个定时任务,每分钟抓一帧,转码后丢给模型做异常检测;也可以用camsnap watch做运动触发,只在有动静时才调 AI,省 token。

运动监控的命令长这样:

camsnap watch kitchen --threshold 0.2 --action 'ffmpeg -i {file} -vframes 1 /tmp/frame.jpg'

threshold是灵敏度,0.2 比较适中,环境光变化大的场景调到 0.3 以上避免误报。--action里可以用{file}占位符拿到触发时的片段路径,后面接你自己的处理逻辑。

长期跑的话,建议把输出目录做成滚动清理,别让磁盘被片段塞满:

find ~/camsnap-out/clips -name "*.mp4" -mtime +7 -delete

最后提一句,camsnap 的 doctor 命令值得定期跑:

camsnap doctor --probe

它会检查每个摄像头的连通性、配置完整性和 ffmpeg 可用性。我习惯把它加进 crontab,每天早上跑一次,有问题提前发现,别等要用的时候才发现摄像头掉线了。

接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite ,里面有针对不同模型的请求示例,配合 camsnap 的输出格式改一下就能用。摄像头这边搞定之后,剩下的就是你想让 AI 看什么、怎么看了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询