← Back to Skills Marketplace
13681882136

Kami Video Search

by KamiVision · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ Security Clean
27
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install kami-video-search
Description
RTSP/RTMP camera stream recording with AI-powered video search. Start/stop background recording, check status, search video clips by natural language descrip...
README (SKILL.md)

Kamivision Video Recorder & Search

An intelligent video surveillance skill that records RTSP/RTMP camera streams, generates AI descriptions for each video segment using the Kamivision API, and supports natural language search across recorded footage.

Capabilities

  1. Start recording — launch background stream recording
  2. Stop recording — stop background recording
  3. Check status — view recording process status
  4. Search video — find video clips by natural language description (with optional time range)
  5. List recent events — show recent non-static video events
  6. View logs — display recording logs for troubleshooting

Trigger Words (Intent Routing)

Match user intent using these trigger words first, then fall back to semantic understanding:

Intent Trigger Words (EN) Trigger Words (ZH)
Start recording start record, start recording, start camera, start monitor, start stream, launch recording 开始录制,启动录制,启动监控,开始监控,启动摄像头
Stop recording stop record, stop recording, stop camera, stop monitor, stop stream, kill recording 停止录制,关闭录制,停止监控,关闭监控,关闭摄像头
Check status recording status, camera status, monitor status, is recording, check status 录制状态,监控状态,运行状态,查看状态
Search video search video, find video, find clip, look for, search footage, video search 搜索视频,查找视频,找视频,视频搜索,搜索片段
List recent recent events, recent clips, list events, what happened, show recent 最近事件,最近录制,最近发生了什么,查看事件
View logs show logs, view logs, recording logs, check logs 查看日志,显示日志,录制日志

If no trigger word matches, use semantic understanding to route to the closest intent.

First-Time Setup Flow

IMPORTANT: On first use, you MUST complete the setup flow before any other operation.

DO NOT use system Python directly. This skill requires its own isolated virtual environment (.venv) in the skill directory.

Step 0: Setup Flow (Follow in Order)

Follow these steps in exact order. Do not skip ahead.


Step 0.1: Check System Python (MUST be >= 3.8)

First, check if Python 3.8+ is installed on the system:

python3 --version

If Python 3.8+ is NOT found (command fails or version is below 3.8):

Tell the user:

🐍 Python 3.8 or higher is required but was not found on your system.

Install Python:

After installing, run python3 --version again to confirm.

DO NOT proceed until Python 3.8+ is confirmed.


Step 0.2: Check/Create Virtual Environment in Skill Directory

Once Python 3.8+ is confirmed, check if .venv exists in the skill directory:

ls -la {baseDir}/.venv/bin/python3

If .venv does NOT exist:

Tell the user:

📦 This skill needs its own isolated Python environment. I'll guide you to create it.

Step 1: Create the virtual environment

cd {baseDir}
python3 -m venv .venv

Step 2: Verify it was created

ls -la .venv/bin/

You should see: python, python3, pip, pip3, activate, etc.

Step 3: Activate and install dependencies

source .venv/bin/activate
pip install -r requirements.txt

Step 4: Verify installation

.venv/bin/python -c "import numpy; import requests; import cv2; print('All dependencies OK')"

If this prints "All dependencies OK", setup is complete!

DO NOT proceed until the user confirms .venv is created and dependencies are installed.

If .venv already exists:

  1. Verify the Python version:
{baseDir}/.venv/bin/python3 --version
  1. Verify dependencies are installed:
{baseDir}/.venv/bin/python -c "import numpy; import requests; import cv2; print('All dependencies OK')"
  • If imports succeed, proceed to configuration.
  • If imports fail, tell the user:

⚠️ Dependencies are missing or broken. Let's reinstall:

cd {baseDir}
source .venv/bin/activate
pip install -r requirements.txt

Pre-Recording Configuration

⚠️ MANDATORY: Before EVERY recording start, you MUST confirm all Required Parameters with the user.

DO NOT start recording without explicit user confirmation of these parameters. This is a mandatory step every single time, even if the values haven't changed since the last recording.

Mandatory Confirmation Flow

⚠️ CRITICAL: Display FULL detailed explanations for EVERY parameter. Do NOT use shortened summaries.

  1. Read current config from {baseDir}/stream_config.json
  2. Display ALL Required Parameters to the user with COMPLETE detailed explanations including:
    • Current value (当前值)
    • What it does / 作用: Full explanation of the parameter's purpose and how it's used in the code
    • How to get it / 如何获取: Step-by-step guidance on obtaining or choosing the right value
    • Format / 格式: Expected format with examples
    • Range / 取值范围: Valid values and constraints
    • Default / 默认值: If applicable
    • Impact of different values / 不同值的影响: Detailed breakdown of how different values affect behavior, costs, storage, API usage, etc. Include scenarios and recommendations.
    • Error behavior / 错误后果: What happens if configured incorrectly
  3. Ask for explicit confirmation (use the user's language):
    • English: "Please confirm if the above configuration is correct. See the detailed explanations above for each parameter. Let me know if you need to modify any parameters."
    • Chinese: "请确认以上配置是否正确?每个参数的详细说明见上文。如有需要修改的参数请告诉我。"
  4. Wait for user response:
    • If user says "yes"/"确认"/"开始" → proceed to start recording
    • If user provides new values → update config, then confirm again
  5. Only after confirmation → execute the start recording command

When displaying parameters, use this format for each:

Language Rule: Match the user's language. If the user writes in English, use English labels and explanations. If the user writes in Chinese, use Chinese labels and explanations.

English format:

📹 STREAM_URL = \x3Ccurrent_value>
   What it does: \x3Cfull explanation>
   How to get it: \x3Cstep-by-step guidance>
   Format: \x3Cformat with examples>
   Range: \x3Cvalid values>
   Default: \x3Cdefault value if applicable>
   Impact of different values: \x3Cdetailed breakdown with scenarios>
   Error behavior: \x3Cconsequences>

Chinese format:

📹 STREAM_URL = \x3Ccurrent_value>
   作用:\x3C完整解释>
   如何获取:\x3C逐步指导>
   格式:\x3C格式及示例>
   取值范围:\x3C有效值>
   默认值:\x3C默认值(如适用)>
   不同值的影响:\x3C详细的场景分析和影响说明>
   错误后果:\x3C配置错误的后果>

IMPORTANT: Use the complete parameter explanations from the "Required Parameters" section below. Do NOT summarize or shorten them. The user needs full context to make informed decisions.

Required Parameters (MUST confirm every time with full explanations)

Language Rule: Display parameter explanations in the same language the user uses.

  • English users: Use English labels (What it does, Format, Range, Default, Error behavior) and English explanations.
  • Chinese users: Use Chinese labels (作用,格式,取值范围,默认值,错误后果) and Chinese explanations.

English Version (for English-speaking users)

  1. STREAM_URL (Camera stream address)

    • What it does: The RTSP/RTMP stream URL of your camera. The code passes this directly to cv2.VideoCapture(STREAM_URL) to open the video stream. It supports RTSP, RTMP, and HTTP protocols.
    • How to get it:
      • Check your camera's admin web interface (usually at http://camera-ip/)
      • Look for "RTSP URL" or "Stream URL" in camera settings
      • Common formats: Hikvision rtsp://user:pass@ip:554/Streaming/Channels/1, Dahua rtsp://user:pass@ip:554/cam/realmonitor?channel=1&subtype=0
      • Contact your camera manufacturer's support if unsure
    • Format: rtsp://username:password@IP:port/path (e.g., rtsp://admin:[email protected]:554/stream1)
    • Range: Any valid stream URL. Validate: MUST start with rtsp://. Reject any other format and ask user to correct it.
    • Impact of different values:
      • Correct URL with valid credentials → Smooth recording, stable frames
      • Wrong IP/port → Connection timeout, recording fails after reconnection attempts
      • Wrong credentials → Authentication failure, no video stream
      • Unreachable camera (offline/network issue) → Same as wrong URL, recording stops
    • Error behavior: If the URL is wrong or unreachable, cv2.VideoCapture will fail to open. After 100 consecutive frame read failures, the code treats it as a stream disconnection and attempts reconnection (up to MAX_RECONNECT times, default 3). If all reconnections fail, recording stops entirely.
  2. KAMI_API_KEY (Kamivision API key)

    • What it does: Authentication key sent in the X-API-Key HTTP header when calling the Kamivision https://kamiclaw-skill-api.kamihome.com/v1/detect API for video description generation and text embedding. Without it, all API calls will return authentication errors, and no descriptions or embeddings will be generated — video search will not work.
    • How to get it:
      • Visit https://kamiclaw-skill.kamihome.com
      • Sign up / log in to your Kamivision account
      • Navigate to API Keys section
      • Create a new key or copy existing one (starts with sk_live_)
      • Keep this key secret — do not share publicly
    • Format: String starting with sk_live_ (e.g., sk_live_xxxxxxxxxxxxxxxx)
    • Impact of different values:
      • Valid key → API calls succeed, video descriptions generated, search works
      • Invalid/expired key → API returns 401/403, no descriptions generated, recording continues but search won't work
      • Empty key → Same as invalid, all API calls fail immediately
      • Rate limit exceeded → API returns 429, code retries per KAMI_API_RETRY, may lose some descriptions
    • Error behavior: If empty or invalid, the API returns a non-200 code. The code retries up to KAMI_API_RETRY times (default 3). After all retries fail, a RuntimeError is raised, the worker thread sends SIGTERM to the process, and recording stops.
  3. DEVICE_ID (Camera identifier)

    • What it does: A label for this camera. Used in three places: (1) video file naming pattern {DEVICE_ID}_{date}_{time}_{index}.mp4, (2) storage directory structure {DATA_DIR}/{DEVICE_ID}/{date}/{hour}/, (3) the device_id field in the SQLite index database.
    • How to get it:
      • Choose a meaningful name for this camera location (e.g., front-door, living-room, warehouse-1)
      • If you have multiple cameras, use unique IDs for each (e.g., CAM-001, CAM-002)
      • Use existing camera name from your NVR/DVR system for consistency
    • Default: CAM-001
    • Range: Any string that is valid as a file/directory name. Avoid special characters like /, \, :, *, ?, ", \x3C, >, |.
    • Impact of different values:
      • Descriptive name (e.g., front-door) → Easy to identify videos, organized file structure
      • Generic name (e.g., CAM-001) → Works fine, but less identifiable when managing multiple cameras
      • Changing DEVICE_ID later → Creates new subdirectory; old videos remain under old DEVICE_ID folder (manual migration needed if you want to consolidate)
      • Special characters in name → File/directory creation fails, recording cannot start
    • Error behavior: If it contains invalid filesystem characters, mkdir or file creation will fail with an OSError, and recording cannot start.
  4. SKIP_STATIC (Skip static frames)

    • What it does: Controls whether the AI description API is called for static (no-motion) video segments. Regardless of this setting, all video segments are always saved to disk. When true, each segment is analyzed by is_static_video() — it samples frame pairs, converts to grayscale, and computes mean absolute pixel difference. If below STATIC_THRESHOLD, the segment is marked is_static=True in the database, and the API call is skipped (no description or embedding generated). This means static segments are still recorded on disk but are invisible to search and list queries — they have no description or embedding, so search cannot match them and list_recent explicitly filters them out (not rec.get("is_static", False)).
    • Default: true (recommended)
    • Range: true or false (boolean)
    • Impact of different values:
      • true (recommended for most cases):
        • ✅ Saves API costs — only sends clips with actual motion to Kamivision
        • ✅ Faster search — fewer indexed entries, queries are quicker
        • ⚠️ Video files are still saved to disk — no disk space savings on video storage
        • ⚠️ Static segments are unsearchable — they exist on disk but cannot be found via search or list commands
        • ⚠️ May miss subtle events — very slight movements might be classified as static and become unsearchable
        • Best for: 24/7 recording, low-traffic areas, cost-conscious setups
      • false (describe everything):
        • ✅ Every segment gets a description and embedding — all clips are searchable
        • ✅ Complete searchable timeline — no gaps in search results
        • ❌ Higher API costs — every segment calls Kamivision API (including boring static footage)
        • ❌ Larger database — more index entries, slightly slower search
        • ⚠️ Disk usage is the same — video files are saved regardless
        • Best for: High-security areas, short-term recording, unlimited API budget
    • Error behavior: If set to a non-boolean value, Python's truthy evaluation applies — any non-empty string or non-zero number is treated as true. Setting to false means every segment will be sent to the API, which increases API usage and database size (but not video disk usage).
  5. STATIC_THRESHOLD (Motion sensitivity)

    • What it does: The threshold used by is_static_video() to decide if a video segment is "static". The function computes np.mean(np.abs(frame1 - frame2)) for sampled grayscale frame pairs (pixel values 0–255). If the average of all pair differences is below this threshold, the segment is considered static.
    • Default: 5.0
    • Range: 0.0255.0 (theoretical). Practical range: 1.020.0.
    • Only effective when: SKIP_STATIC is true
    • Impact of different values:
      • Very low (0.0 – 1.0):
        • Almost nothing is skipped — even completely still scenes pass through
        • API calls: Maximum (nearly 100% of segments sent)
        • Use case: Maximum sensitivity, don't miss anything (e.g., monitoring delicate equipment)
        • Downside: High API costs, defeats the purpose of SKIP_STATIC
      • Low (1.0 – 5.0):
        • Catches subtle changes — lighting shifts, leaves swaying, small animals
        • API calls: High (70-90% of segments sent)
        • Use case: Outdoor scenes with wind, areas with frequent minor movements
        • Downside: May still send many "unimportant" clips
      • Medium (5.0 – 15.0) — RECOMMENDED:
        • Normal motion detection — people walking, vehicles passing, doors opening
        • API calls: Moderate (20-50% of segments sent, depends on location)
        • Use case: Indoor rooms, entrances, hallways, parking lots
        • Best balance: Catches meaningful events while skipping empty periods
      • High (15.0 – 50.0):
        • Only significant motion — multiple people, fast vehicles, major activity
        • API calls: Low (5-20% of segments sent)
        • Use case: Very busy areas where you only care about major events
        • Downside: May miss single-person entries or slow movements
      • Very high (> 50.0):
        • Only extreme motion — crowds, chaos, rapid movement
        • API calls: Minimal (\x3C 5% of segments sent)
        • Use case: Almost never recommended — you'll miss most events
        • Downside: Essentially records only when there's intense activity
    • Tuning tips:
      • Start with 5.0, monitor for a day, check what got skipped
      • If too many false positives (static clips sent): increase by 2-3
      • If missing important events: decrease by 2-3
      • Different locations need different values — test and adjust
    • Error behavior: No validation in code. A negative value means nothing is ever static (all segments processed). An extremely high value (e.g., 200) means almost everything is skipped. Non-numeric values will cause a TypeError crash in np.mean() comparison.
  6. DATA_DIR (Storage directory)

    • What it does: Root directory for all recorded data. The code creates a hierarchical structure: {DATA_DIR}/{DEVICE_ID}/{YYYYMMDD}/{HH}/ for video files, and {DATA_DIR}/{DEVICE_ID}/index.db for the SQLite index. Directories are created automatically via Path.mkdir(parents=True, exist_ok=True).
    • How to get it:
      • Choose a directory with sufficient disk space
      • For Linux/Mac: /home/youruser/video_data or /mnt/storage/videos
      • For Windows: D:\video_data or C:\Users\YourName\video_data
      • Use external drive or NAS for long-term storage
      • Ensure the user running the recorder has write permissions
    • Default: ./video_data (relative to working directory)
    • Range: Any valid filesystem path (absolute or relative). Ensure the path is writable and has sufficient disk space. Each 10-second clip at 640×360 is roughly 200KB–1MB.
    • Impact of different values:
      • Local disk (fast SSD):
        • ✅ Fast write speeds, reliable recording
        • ✅ Quick search and playback
        • ⚠️ Limited capacity (check free space: df -h)
        • Estimate: 1 hour ≈ 72-360 clips ≈ 15-360 MB (depends on motion)
      • External HDD / NAS:
        • ✅ Large capacity for long-term storage
        • ⚠️ Slower write speeds — ensure stable network for NAS
        • ⚠️ Network issues can interrupt recording
        • Best for: Archive storage, multi-camera setups
      • Small partition (\x3C 10 GB free):
        • ⚠️ Will fill up quickly — monitor disk space
        • With RETENTION_DAYS=3: Should auto-clean, but verify regularly
        • Risk: If disk fills, recording produces corrupted files
      • Changing DATA_DIR later:
        • Old videos stay in old directory (manual migration needed)
        • New recordings go to new directory
        • Index database is per DEVICE_ID, so search only sees new videos
    • Disk space estimation:
      • Per 10-second clip: ~200KB (static) to ~1MB (high motion)
      • Per hour: ~72 clips × average size
      • Example: 50% motion, 500KB avg → 72 × 500KB ≈ 36 MB/hour
      • Per day: ~864 MB (continuous recording, moderate motion)
      • With SKIP_STATIC=true: Can reduce by 50-80% in low-traffic areas
    • Error behavior: If the path is not writable (permission denied), Path.mkdir() or cv2.VideoWriter() raises OSError/PermissionError and recording fails. If disk space runs out, cv2.VideoWriter.write() silently produces corrupted files (0 bytes), which are then skipped by the processing queue.
  7. RETENTION_DAYS (Data retention period)

    • What it does: Controls automatic cleanup of old recordings. A background thread runs index.purge_expired(RETENTION_DAYS) every hour. It queries the SQLite database for records where created_at \x3C (now - RETENTION_DAYS), deletes the corresponding video files from disk, removes the database records, and cleans up empty directories. After purging, it runs VACUUM to reclaim database file space.
    • Default: 3 (days)
    • Range: Integer >= 0. Set to 0 to disable auto-cleanup (keep forever). No upper limit, but very large values effectively disable cleanup.
    • Impact of different values:
      • 0 (disable cleanup):
        • ✅ Keep everything forever — complete archive
        • ❌ Disk space grows indefinitely — will eventually fill up
        • ❌ Database grows larger — search may slow down over time
        • Use case: Short-term testing, external backup system handles cleanup
        • ⚠️ WARNING: Monitor disk space manually!
      • 1-2 days:
        • ✅ Minimal disk usage — aggressive cleanup
        • ❌ May lose important footage if you don't check daily
        • ❌ Not enough time to review and export important clips
        • Use case: High-motion areas, limited disk space, daily review habit
      • 3-7 days — RECOMMENDED:
        • ✅ Balanced approach — enough time to review and export
        • ✅ Reasonable disk usage for most setups
        • ✅ Weekly review cycle works well
        • Use case: Most home/office security setups
        • Estimate: 7 days × ~1 GB/day ≈ 7 GB per camera (moderate motion, SKIP_STATIC=true)
      • 8-30 days:
        • ✅ Extended review window — don't miss old events
        • ❌ Higher disk usage — ensure adequate capacity
        • ❌ Larger database — slightly slower search
        • Use case: Compliance requirements, incident investigation, low-motion areas
      • > 30 days:
        • ✅ Long-term archive on local disk
        • ❌ Significant disk space required
        • ❌ Consider external storage or cloud backup instead
        • Use case: Legal/compliance requirements, very low motion areas
    • Disk space planning examples (per camera, SKIP_STATIC=true, moderate motion):
      • RETENTION_DAYS=3: ~3 GB
      • RETENTION_DAYS=7: ~7 GB
      • RETENTION_DAYS=14: ~14 GB
      • RETENTION_DAYS=30: ~30 GB
      • Multiply by number of cameras for total estimate
    • Manual override: You can manually delete old videos anytime by removing files from {DATA_DIR}/{DEVICE_ID}/ — the database will auto-cleanup orphaned entries on next scan
    • Error behavior: Negative values behave the same as 0 (no cleanup) because the cutoff time would be in the future. Non-integer values are used directly in timedelta(days=...) — floats work (e.g., 0.5 = 12 hours), but strings cause a TypeError crash.

中文版本 (for Chinese-speaking users)

  1. STREAM_URL (摄像头流地址)

    • 作用:摄像头的 RTSP/RTMP 视频流地址。代码将此值直接传给 cv2.VideoCapture(STREAM_URL) 来打开视频流,支持 RTSP、RTMP、HTTP 协议。
    • 如何获取:
      • 查看摄像头管理后台(通常访问 http://摄像头 IP/
      • 在摄像头设置中查找"RTSP URL"或"流地址"
      • 常见格式:海康威视 rtsp://user:pass@ip:554/Streaming/Channels/1,大华 rtsp://user:pass@ip:554/cam/realmonitor?channel=1&subtype=0
      • 如不确定,联系摄像头厂商客服
    • 格式:rtsp://用户名:密码@IP:端口/路径(如 rtsp://admin:[email protected]:554/stream1
    • 取值范围:任何有效的流地址。校验:必须以 rtsp:// 开头,否则拒绝并要求用户修正。
    • 不同值的影响:
      • 正确的 URL + 有效凭证 → 录制流畅,帧稳定
      • 错误的 IP/端口 → 连接超时,重连尝试后录制失败
      • 错误的凭证 → 认证失败,无视频流
      • 摄像头不可达(离线/网络问题)→ 同错误 URL,录制停止
    • 错误后果:如果地址错误或不可达,cv2.VideoCapture 将无法打开。连续 100 帧读取失败后,代码判定为断流并尝试重连(最多 MAX_RECONNECT 次,默认 3 次)。重连全部失败则录制彻底停止。
  2. KAMI_API_KEY (Kamivision API 密钥)

    • 作用:调用 Kamivision https://kamiclaw-skill-api.kamihome.com/v1/detect API 时通过 X-API-Key HTTP 头发送的认证密钥,用于生成视频描述和文本向量。没有它,所有 API 调用都会返回认证错误,不会生成描述和向量,视频搜索功能将不可用。
    • 如何获取:
      • 访问 https://kamiclaw-skill.kamihome.com
      • 注册/登录 Kamivision 账户
      • 进入 API Keys 页面
      • 创建新密钥或复制现有密钥(以 sk_live_ 开头)
      • 保密此密钥——不要公开分享
    • 格式:以 sk_live_ 开头的字符串(如 sk_live_xxxxxxxxxxxxxxxx
    • 不同值的影响:
      • 有效密钥 → API 调用成功,生成视频描述,搜索功能正常
      • 无效/过期密钥 → API 返回 401/403,无描述生成,录制继续但搜索不可用
      • 空密钥 → 同无效,所有 API 调用立即失败
      • 超出速率限制 → API 返回 429,代码按 KAMI_API_RETRY 重试,可能丢失部分描述
    • 错误后果:如果为空或无效,API 返回非 200 状态码。代码会重试 KAMI_API_RETRY 次(默认 3 次)。全部重试失败后抛出 RuntimeError,工作线程向进程发送 SIGTERM,录制停止。
  3. DEVICE_ID (摄像头标识)

    • 作用:摄像头的标签名。用于三个地方:(1) 视频文件命名 {DEVICE_ID}_{日期}_{时间}_{序号}.mp4,(2) 存储目录结构 {DATA_DIR}/{DEVICE_ID}/{日期}/{小时}/,(3) SQLite 索引数据库中的 device_id 字段。
    • 如何获取:
      • 为摄像头位置选择一个有意义的名称(如 front-door 大门,living-room 客厅,warehouse-1 1 号仓库)
      • 如有多个摄像头,为每个使用唯一 ID(如 CAM-001CAM-002
      • 为保持一致性,可使用 NVR/DVR 系统中现有的摄像头名称
    • 默认值:CAM-001
    • 取值范围:任何可作为文件/目录名的字符串。避免 /\:*?"\x3C>| 等特殊字符。
    • 不同值的影响:
      • 描述性名称(如 front-door)→ 易于识别视频,文件结构清晰
      • 通用名称(如 CAM-001)→ 可用,但管理多个摄像头时不易识别
      • 后期更改 DEVICE_ID → 创建新子目录;旧视频保留在旧 DEVICE_ID 文件夹下(如需合并需手动迁移)
      • 名称含特殊字符 → 文件/目录创建失败,录制无法启动
    • 错误后果:如果包含非法文件系统字符,mkdir 或文件创建会抛出 OSError,录制无法启动。
  4. SKIP_STATIC (跳过静止画面)

    • 作用:控制是否对静止(无运动)视频片段调用 AI 描述 API。无论此设置如何,所有视频片段都会保存到磁盘。 设为 true 时,每个片段会经过 is_static_video() 分析——抽取帧对,转为灰度图,计算像素差均值。如果低于 STATIC_THRESHOLD,该片段在数据库中标记为 is_static=True,跳过 API 调用(不生成描述和向量)。这意味着静止片段仍然录制在磁盘上,但搜索和列表查询无法找到它们——因为没有描述和向量,search 无法匹配,list_recent 也会显式过滤掉(not rec.get("is_static", False))。
    • 默认值:true(推荐)
    • 取值范围:truefalse(布尔值)
    • 不同值的影响:
      • true(推荐大多数情况):
        • ✅ 节省 API 费用——只发送有实际运动的片段给 Kamivision
        • ✅ 搜索更快——索引条目更少,查询更迅速
        • ⚠️ 视频文件仍然保存到磁盘——不节省视频存储空间
        • ⚠️ 静止片段不可搜索——它们存在于磁盘上,但无法通过搜索或列表命令找到
        • ⚠️ 可能错过细微事件——非常轻微的运动可能被判定为静止,从而变得不可搜索
        • 适用场景:24/7 录制、低流量区域、注重成本的设置
      • false(为所有片段生成描述):
        • ✅ 每个片段都有描述和向量——所有片段均可搜索
        • ✅ 完整的可搜索时间线——搜索结果无空白
        • ❌ API 费用更高——每个片段都调用 Kamivision API(包括无聊的静止画面)
        • ❌ 数据库更大——更多索引条目,搜索稍慢
        • ⚠️ 磁盘用量相同——无论如何视频文件都会保存
        • 适用场景:高安全区域、短期录制、API 预算充足
    • 错误后果:如果设为非布尔值,Python 的真值判断生效——任何非空字符串或非零数字都视为 true。设为 false 意味着每个片段都会调用 API,增加 API 用量和数据库大小(但不影响视频磁盘用量)。
  5. STATIC_THRESHOLD (运动灵敏度)

    • 作用:is_static_video() 函数用来判断片段是否"静止"的阈值, 值越大越容易被检测为静止片段, 越省费用。函数对抽样的灰度帧对计算 np.mean(np.abs(frame1 - frame2))(像素值范围 0–255)。如果所有帧对差值的平均值低于此阈值,则判定为静止。
    • 默认值:5.0
    • 取值范围:理论范围 0.0255.0,实用范围 1.020.0
    • 仅在以下条件生效:SKIP_STATICtrue
    • 不同值的影响:
      • 极低 (0.0 – 1.0)
        • 几乎不跳过任何片段——即使完全静止的场景也会通过
        • API 调用:最多(近 100% 片段发送)
        • 适用场景:最高灵敏度,不要错过任何事(如监控精密设备)
        • 缺点:API 费用高,违背 SKIP_STATIC 的初衷
      • 低 (1.0 – 5.0)
        • 捕捉细微变化——光线变化、树叶晃动、小动物
        • API 调用:高(70-90% 片段发送)
        • 适用场景:有风的户外场景、频繁轻微运动的区域
        • 缺点:可能仍发送许多"不重要"的片段
      • 中 (5.0 – 15.0) — 推荐
        • 正常运动检测——行人走动、车辆经过、门打开
        • API 调用:中等(20-50% 片段发送,取决于位置)
        • 适用场景:室内房间、入口、走廊、停车场
        • 最佳平衡:捕捉有意义事件的同时跳过空闲时段
      • 高 (15.0 – 50.0)
        • 仅显著运动——多人、快速车辆、主要活动
        • API 调用:低(5-20% 片段发送)
        • 适用场景:非常繁忙的区域,只关心重大事件
        • 缺点:可能错过单人进入或缓慢移动
      • 极高 (> 50.0)
        • 仅极端运动——人群、混乱、快速移动
        • API 调用:最少(\x3C 5% 片段发送)
        • 适用场景:几乎不推荐——会错过大多数事件
        • 缺点:基本上只在有激烈活动时录制
    • 调优技巧:
      • 5.0 开始,监控一天,检查什么被跳过了
      • 如果误报太多(静止片段被发送):增加 2-3
      • 如果错过重要事件:减少 2-3
      • 不同位置需要不同值——测试并调整
    • 错误后果:代码中无校验。负值意味着没有片段被判为静止(全部处理)。极高值(如 200)意味着几乎所有片段被跳过。非数字值会在 np.mean() 比较时引发 TypeError 崩溃。
  6. DATA_DIR (存储目录)

    • 作用:所有录制数据的根目录。代码创建层级结构:{DATA_DIR}/{DEVICE_ID}/{YYYYMMDD}/{HH}/ 存放视频文件,{DATA_DIR}/{DEVICE_ID}/index.db 存放 SQLite 索引。目录通过 Path.mkdir(parents=True, exist_ok=True) 自动创建。
    • 如何获取:
      • 选择有足够磁盘空间的目录
      • Linux/Mac: /home/你的用户名/video_data/mnt/storage/videos
      • Windows: D:\video_dataC:\Users\你的用户名\video_data
      • 长期使用可使用外接硬盘或 NAS
      • 确保运行录制器的用户有写入权限
    • 默认值:./video_data(相对于工作目录)
    • 取值范围:任何有效的文件系统路径(绝对或相对)。确保路径可写且有足够磁盘空间。每个 640×360 的 10 秒片段约 200KB–1MB。
    • 不同值的影响:
      • 本地磁盘 (快速 SSD)
        • ✅ 写入速度快,录制可靠
        • ✅ 搜索和播放迅速
        • ⚠️ 容量有限(检查可用空间:df -h
        • 估算:1 小时 ≈ 72-360 个片段 ≈ 15-360 MB(取决于运动量)
      • 外接硬盘 / NAS
        • ✅ 大容量,适合长期存储
        • ⚠️ 写入速度较慢——NAS 需确保网络稳定
        • ⚠️ 网络问题可能中断录制
        • 适用场景:归档存储、多摄像头设置
      • 小分区 (\x3C 10 GB 可用)
        • ⚠️ 会快速填满——需监控磁盘空间
        • 使用 RETENTION_DAYS=3:应自动清理,但需定期检查
        • 风险:磁盘满时,录制产生损坏文件
      • 后期更改 DATA_DIR
        • 旧视频保留在旧目录(需手动迁移)
        • 新录制进入新目录
        • 索引数据库按 DEVICE_ID 分离,搜索只看到新视频
    • 磁盘空间估算:
      • 每 10 秒片段:~200KB(静止)到 ~1MB(高运动)
      • 每小时:~72 个片段 × 平均大小
      • 示例:50% 运动,平均 500KB → 72 × 500KB ≈ 36 MB/小时
      • 每天:~864 MB(连续录制,中等运动)
      • 使用 SKIP_STATIC=true:低流量区域可减少 50-80%
    • 错误后果:如果路径不可写(权限不足),Path.mkdir()cv2.VideoWriter() 抛出 OSError/PermissionError,录制失败。如果磁盘空间耗尽,cv2.VideoWriter.write() 会静默产生损坏文件(0 字节),处理队列会跳过这些文件。
  7. RETENTION_DAYS (数据保留天数)

    • 作用:控制旧录像的自动清理。后台线程每小时执行一次 index.purge_expired(RETENTION_DAYS)。它查询 SQLite 数据库中 created_at \x3C (当前时间 - RETENTION_DAYS) 的记录,删除对应的视频文件,移除数据库记录,并清理空目录。清理后执行 VACUUM 回收数据库文件空间。
    • 默认值:3(天)
    • 取值范围:整数 >= 0。设为 0 禁用自动清理(永久保留)。无上限,但极大值等同于禁用清理。
    • 不同值的影响:
      • 0(禁用清理)
        • ✅ 永久保留所有内容——完整归档
        • ❌ 磁盘空间无限增长——最终会填满
        • ❌ 数据库变大——搜索可能随时间变慢
        • 适用场景:短期测试、外部备份系统处理清理
        • ⚠️ 警告:需手动监控磁盘空间!
      • 1-2 天
        • ✅ 磁盘用量最小——激进清理
        • ❌ 如不每天检查可能丢失重要片段
        • ❌ 没有足够时间审查和导出重要片段
        • 适用场景:高运动区域、磁盘空间有限、有每天审查习惯
      • 3-7 天 — 推荐
        • ✅ 平衡方案——有足够时间审查和导出
        • ✅ 对大多数设置来说磁盘用量合理
        • ✅ 适合每周审查周期
        • 适用场景:大多数家庭/办公室安防设置
        • 估算:7 天 × ~1 GB/天 ≈ 7 GB 每摄像头(中等运动,SKIP_STATIC=true)
      • 8-30 天
        • ✅ 延长审查窗口——不会错过旧事件
        • ❌ 磁盘用量更高——确保容量充足
        • ❌ 数据库更大——搜索稍慢
        • 适用场景:合规要求、事件调查、低运动区域
      • > 30 天
        • ✅ 本地磁盘长期归档
        • ❌ 需要大量磁盘空间
        • ❌ 建议改用外部存储或云备份
        • 适用场景:法律/合规要求、极低运动区域
    • 磁盘空间规划示例(每摄像头,SKIP_STATIC=true,中等运动):
      • RETENTION_DAYS=3: ~3 GB
      • RETENTION_DAYS=7: ~7 GB
      • RETENTION_DAYS=14: ~14 GB
      • RETENTION_DAYS=30: ~30 GB
      • 乘以摄像头数量得到总估算
    • 手动覆盖:你可以随时手动删除旧视频——从 {DATA_DIR}/{DEVICE_ID}/ 移除文件,数据库会在下次扫描时自动清理孤立条目
    • 错误后果:负值与 0 行为相同(不清理),因为截止时间会在未来。非整数值直接传给 timedelta(days=...)——浮点数可用(如 0.5 = 12 小时),但字符串会导致 TypeError 崩溃。

Configuration Update

IMPORTANT: Only update config and start recording AFTER explicit user confirmation.

After the user confirms the parameters (or provides updated values):

  1. Read the current config from {baseDir}/stream_config.json
  2. Update only the confirmed/changed fields
  3. Write the updated config back
  4. Then proceed to execute the start recording command

Never skip the confirmation step or assume previous values are still valid.

Command Execution

All commands MUST use the virtual environment Python interpreter at {baseDir}/.venv/bin/python.

All commands use the script at {baseDir}/stream_recoder2.py with config at {baseDir}/stream_config.json.

Start Recording

{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --start-daemon --log-file {baseDir}/stream_recorder.log

After running, parse the JSON output:

  • If status is "started": Tell user recording has started, show the PID
  • If status is "already_running": Tell user recording is already running, show the PID
  • On error: Show the error message and ask user to check their STREAM_URL and network

Stop Recording

{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --stop-daemon

Parse the JSON output:

  • If status is "stopped": Confirm recording has stopped
  • If status is "not_running": Tell user there's no active recording to stop

Check Status

{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --status

Parse the JSON output and report the status to the user in a friendly way.

Search Video

The user may provide a search query in natural language, optionally with a time range.

Time range parsing:

  • Natural language: "today morning", "yesterday afternoon", "this morning 8 to 12" → convert to YYYY-MM-DD_HH:MM:SS format
  • Fixed format: accept YYYY-MM-DD_HH:MM:SS or YYYY-MM-DD HH:MM:SS directly
  • If no time range specified, search all recorded footage
{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --search "QUERY_TEXT" --json

With time range:

{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --search "QUERY_TEXT" --time-start "YYYY-MM-DD_HH:MM:SS" --time-end "YYYY-MM-DD_HH:MM:SS" --json

Parse the JSON output and present results to the user:

  • Show the number of matches
  • For each result: time, description, score, and full video file path
  • If no results: tell the user no matching clips were found, suggest broadening the query or time range

List Recent Events

{baseDir}/.venv/bin/python {baseDir}/stream_recoder2.py --config {baseDir}/stream_config.json --list HOURS --json

Default HOURS to 24 if user doesn't specify. Parse and present results showing time, description, and video path.

View Logs

tail -100 {baseDir}/stream_recorder.log

Show the last 100 lines of the log file. If the user asks for more, increase the line count. If the log file doesn't exist, tell the user recording hasn't been started yet.

Error Handling

  • STREAM_URL connection failure: Tell the user to check the camera address, network connectivity, and credentials. Do NOT retry automatically.
  • Invalid API Key: Tell the user "Your Kamivision API key appears to be invalid. Please check it at https://kamiclaw-skill.kamihome.com". Do NOT retry.
  • Python not found: Guide installation per Step 0 above.
  • Virtual environment missing: Create .venv per Step 0, then install dependencies.
  • Dependency missing: Re-run {baseDir}/.venv/bin/pip install -r {baseDir}/requirements.txt.
  • Permission denied: Suggest running with appropriate permissions or changing DATA_DIR to a writable location.

Language

Respond in the same language the user uses. If the user writes in Chinese, respond in Chinese. If in English, respond in English.

For parameter explanations during recording setup:

  • English users: Use the English version of all 7 parameter explanations with English labels (What it does, Format, Range, Default, Error behavior).
  • Chinese users: Use the Chinese version of all 7 parameter explanations with Chinese labels (作用,格式,取值范围,默认值,错误后果).
  • Do not mix languages — if the user asks in English, show all explanations in English; if in Chinese, show all in Chinese.
Usage Guidance
Install only if you are comfortable granting access to your camera stream and sending frame snapshots to Kamivision for analysis. Protect the API key and camera credentials, verify the storage directory and retention period, keep upload mode set to image unless you intentionally want full-video upload, and stop the background recorder when monitoring is no longer needed.
Capability Analysis
Type: OpenClaw Skill Name: kami-video-search Version: 1.0.0 The skill provides legitimate video surveillance recording and AI-powered search functionality using the Kamivision API. The Python script (stream_recoder2.py) implements RTSP/RTMP stream capture, local SQLite indexing, and remote video analysis via base64-encoded frame uploads to kamiclaw-skill-api.kamihome.com. The SKILL.md instructions are highly prescriptive but focused on safety, mandating a virtual environment setup and requiring explicit user confirmation of all configuration parameters (like API keys and stream URLs) before recording begins. No evidence of unauthorized data exfiltration, obfuscation, or malicious command execution was found.
Capability Tags
requires-sensitive-credentials
Capability Assessment
Purpose & Capability
The stated purpose matches the capabilities: RTSP/RTMP recording, AI-generated descriptions, local indexing, and search. Users should still treat camera footage and generated descriptions as sensitive.
Instruction Scope
Instructions require first-time setup and explicit parameter confirmation before starting recording, which is good control, but the skill also routes broad natural-language requests like monitoring, search, logs, and recent events.
Install Mechanism
There is no install spec, but SKILL.md instructs users to create a local virtual environment and install requirements from requirements.txt. This is normal for a Python-based recorder, though dependencies are version-ranged rather than fully pinned.
Credentials
Camera stream access, local disk storage, external API calls, and SQLite indexing are proportionate to video search, but they involve sensitive home/security data.
Persistence & Privilege
The skill is designed to start a background/daemon recording process and auto-clean old clips. This is disclosed and purpose-aligned, but users should verify stop/status controls and retention settings.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install kami-video-search
  3. After installation, invoke the skill by name or use /kami-video-search
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial release of kamivision-recorder: AI-powered RTSP/RTMP camera stream recording and searchable surveillance. - Start and stop camera stream recordings in the background. - Search recorded video clips using natural language descriptions. - List recent non-static events and view detailed recording logs. - Strict setup and configuration flow: system Python >=3.8, mandatory isolated virtual environment, and confirmation of all parameters before any recording. - Detailed parameter display and multi-language support (English/Chinese) for setup and operation.
Metadata
Slug kami-video-search
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Kami Video Search?

RTSP/RTMP camera stream recording with AI-powered video search. Start/stop background recording, check status, search video clips by natural language descrip... It is an AI Agent Skill for Claude Code / OpenClaw, with 27 downloads so far.

How do I install Kami Video Search?

Run "/install kami-video-search" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Kami Video Search free?

Yes, Kami Video Search is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Kami Video Search support?

Kami Video Search is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Kami Video Search?

It is built and maintained by KamiVision (@13681882136); the current version is v1.0.0.

💬 Comments