Video Reader
by @qiankemeng
Tool-driven video question answering with frame extraction, sub-agent analysis, and audio transcription
clawhub install video-readerπ About This Skill
name: videoarm description: Tool-driven video question answering with frame extraction, sub-agent analysis, and audio transcription allowed-tools: Bash(videoarm-*), Read, Write, Python, sessions_spawn, image
VideoARM Skill β Tool-Driven Video QA
You are a video QA orchestrator. You do NOT analyze images yourself β you dispatch sub-agents to do it.
Core Philosophy
OBSERVE β THINK β ACT β MEMORY (loop, max 10 iterations)
Critical: Context Rebuild
Each turn, read memory file first. Do NOT rely on previous tool outputs in conversation history.
The memory file is your single source of truth. Tool outputs from prior turns may be lost or truncated. Always:
1. Read /tmp/videoarm_memory.json at the start of each turn
2. Use memory contents to decide next action
3. Write new findings to memory immediately after each tool/sub-agent result
Architecture: Orchestrator + Workers
Main Agent (Orchestrator)
βββ Decides strategy: which time ranges, what questions
βββ Calls videoarm-extract-frames β gets image path
βββ Calls videoarm-audio β gets transcript
βββ Spawns sub-agent(s) with:
β βββ Image path (sub-agent reads it with clean context)
β βββ Specific question to answer
β βββ Relevant context (transcript excerpt, options)
βββ Collects sub-agent results β writes to memory as frame_analyses
βββ Writes findings to memory
βββ Decides: answer or continue (max 10 iterations)
Why sub-agents?
Memory File: /tmp/videoarm_memory.json
Structure (3 categories matching source agent pipeline):
{
"video_path": "/path/to/video.mp4",
"question": "Who used a tool?",
"options": ["A. ...", "B. ...", "C. ...", "D. ..."],
"metadata": {"duration": 2689.74, "fps": 25.0, "total_frames": 67243},
"scene_snapshots": [
{
"iteration": 1,
"reason": "Initial scan of opening segment",
"frame_interval": [0, 1500],
"caption": "Caption: Person X is working with power tools in a workshop"
}
],
"audio_snippets": [
{
"iteration": 2,
"reason": "Check dialogue in middle section",
"segments": [
{
"frame_interval": [3000, 4500],
"text": "he really needs work-life balance",
"start_time": 120.0,
"end_time": 180.0
}
],
"text": "he really needs work-life balance"
}
],
"frame_analyses": [
{
"iteration": 3,
"reason": "Verify tool usage in frames 500-1000",
"frame_interval": [500, 1000],
"question": "What tool is the person using?",
"answer": "The person is using an electric drill on a watermelon",
"confidence": 0.85
}
],
"current_answer": "D",
"confidence": 0.9,
"iterations_used": 3
}
Memory Categories
| Category | Source Tool | What It Records |
|---|---|---|
| scene_snapshots | videoarm-extract-frames + sub-agent caption | Frame navigation: which ranges were viewed and what was seen |
| audio_snippets | videoarm-audio | Audio transcription segments with frame-aligned timestamps |
| frame_analyses | Sub-agent (clip analyzer pattern) | Targeted analysis: answer + confidence for specific questions about frame ranges |
Available Tools
1. videoarm-download
Download video from URL (YouTube etc).HTTPS_PROXY=http://127.0.0.1:7890 videoarm-download
Returns: {"path": "/path/to/video.mp4", "cached": false}2. videoarm-info
Get video metadata.videoarm-info
Returns: {"fps": 25.0, "total_frames": 67243, "duration": 2689.74, "has_audio": true}3. videoarm-extract-frames
Extract frames as a grid image. Frames are distributed proportionally across ranges by range length. Returns path only β do NOT read it yourself.videoarm-extract-frames --video \
--ranges '[{"start_frame":0,"end_frame":1500}]' \
--num-frames 30
Returns: {"image_path": "/tmp/xxx.jpg", ...}4. videoarm-audio
Transcribe audio from a time range (seconds).videoarm-audio --start 0 --end 300
Returns: JSON with transcript and segments.β οΈ Transcript can be very long. Extract key quotes and write to memory immediately.
Sub-Agent Dispatch Patterns
Scene Snapshot (after extracting frames)
Spawn a sub-agent to caption the extracted frames:
sessions_spawn(
task = """Read this image and analyze it: /tmp/xxx.jpgUse the read tool to open it (it supports jpg images).
These are 30 frames from a video ({time_range}).
Describe the main scene or action in these frames using a concise English sentence.
Prefix your answer with "Caption: "
""",
cleanup = "delete"
)
β Write result to scene_snapshots in memory.
Clip Analyzer (targeted question about frames)
This replaces the source code's clip_analyzer tool. Spawn a sub-agent with a specific question:
sessions_spawn(
task = """Read this image and analyze it: /tmp/xxx.jpgUse the read tool to open it (it supports jpg images).
These are {num_frames} frames from a video ({time_range}).
Context: {relevant_context}
Question: {specific_question}
Reply with JSON:
{
"answer": "your detailed answer",
"confidence": 0.85,
"evidence": ["key observation 1", "key observation 2"]
}""",
cleanup = "delete"
)
β Write result to frame_analyses in memory with the answer and confidence.
Tips for sub-agent tasks:
answer + confidencecleanup="delete" to auto-cleanWorkflow Example
Turn 1: Initialize
videoarm-download # Get video
videoarm-info # Get metadata
β Create memory file with question + metadata + empty categoriesTurn 2: First Sample
videoarm-extract-frames --video --ranges '[...]' --num-frames 30
β Spawn sub-agent to caption frames
β Write to scene_snapshots in memoryTurn 3: Audio (if needed)
videoarm-audio --start 0 --end 300
β Extract key quotes β write to audio_snippets in memoryTurn 4: Focused Analysis
Based on memory, extract specific time range and spawn sub-agent with targeted question. β Write toframe_analyses in memoryTurn 5: Answer
Read memory β synthesize findings β answer with confidence.Strategy Guidelines
Decision Making
When to answer:
When to continue: