vision-analysis
Skill1 starsChanged 3 months agoMITView on GitHub
Interval-based and shot-level visual analysis — extract frame sequences, guide agent vision analysis of stills, classified on-screen text, and QC-style reports. Use for burned-in subtitles, graphics, title cards, and timecoded text inventories. Does not bundle a vision model; the agent analyzes images with its own capabilities.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- martgueritainaccurate875/skillstheir own version, first seen Nov 8, 2026
- yaokai123/AgentPawtheir own version, first seen Oct 11, 2026
- idexal/idexal-skillstheir own version, first seen Aug 26, 2026
- MiniMax-AI/skillstheir own version, first seen Mar 24, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- MiniMax-AI/skills★ 14ksame name
- martgueritainaccurate875/skills★ 6same name
- idexal/idexal-skills★ 2same name
- yaokai123/AgentPaw★ 1same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- AGENTS.mdAGENTS.md
- site/AGENTS.mdAGENTS.md
- site/CLAUDE.mdCLAUDE.md
- audioSkill
- captions-complianceSkill
- downloadSkill
- forced-narrative-exactSkill
- imageSkill
- inspectSkill
- install-media-toolsSkill
- program-masterSkill
- shotsSkill
- speech-captionsSkill
- subtitlesSkill
- timecodeSkill
- video-transformationSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 1 is distinctive, and 7 are very specific to this project.
0
Common
Most of the 3 edited versions we read keep these.
1
Distinctive
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 25
All script outputs write to the workspace root .mediaskills/generated/ (not inside this skill folder).
- Very specific: line 67
If your tools showed a filesystem path when loading this SKILL.md, strip SKILL.md and use that folder.
- Very specific: line 68
If you already ran another mediaskills script (for example .../audio/scripts/extract.py), this skill is a sibling of that folder: same …
- Very specific: line 91
Prefer absolute paths for --input / --output when cwd is uncertain.
- Distinctive: line 96
Before running any script, treat these two failures differently:
- Very specific: line 99
Only escalate sandbox permissions if the error is explicitly a permission denial (e.g.
- Very specific: line 125
Read references/AGENT_FRAME_ANALYSIS.md for the exact per-frame JSON schema and classification rules.
- Very specific: line 129
After forced_narrative_report.py (agent vision path) or compile_forced_narrative_report.py (OCR path), present burned-in dialogue in this …
“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Vision Analysis
Interval-based and shot-level visual analysis: frame extraction, agent-driven image analysis, and timecoded text reports.
When to use
- This skill — extract frame sequences, inventory on-screen text/graphics with timecodes, agent-guided visual QC.
forced-narrative-exact— exhaustive, frame-accurate burned-in dialogue inventory with exclusive-end SMPTE boundaries and completeness audit.shots— cut detection and midpoint stills when the unit of analysis is a shot.image—image.ocrfor a single still without a sequence pipeline.captions-compliance— validate separate caption sidecar files (SRT/VTT), not burned-in text.
Output paths
All script outputs write to the workspace root .mediaskills/generated/ (not inside this skill folder). Frame JPGs, manifests, and reports share that directory across skills. Override with $MEDIASKILLS_DATA_DIR/generated/ when set.
Agent vs scripts
| Step | Who | Tool |
| Extract frames from video | Script | extract_interval_frames.py or shots skill |
| View and analyze frame images | Agent (your vision/multimodal tools) | See references/AGENT_FRAME_ANALYSIS.md |
| Merge agent JSON into analysis doc | Script | merge_analysis.py |
| Validate analysis JSON | Script | validate_analysis.py |
| Generate reports | Script | text_on_screen_report.py, etc. |
| OCR without vision model | Script | compile_report.py (tesseract) |
This skill does not call Ollama, OpenAI, or any local vision server. If you cannot view images, use the legacy OCR path or tell the user that vision analysis requires an agent with image understanding.
Text types (text_type)
| Value | Meaning |
title | Title card / show open / episode title |
lower_third | Name/title bar in the lower third |
subtitle | Burned-in dialogue / forced narrative |
locator | Location/time bugs, network bugs, timecode |
graphic | Charts, maps, scoreboards, graphic packages |
background_text | Text physically in the scene |
credit | End credits / copyright |
other | Anything else |
Reports condense repeated identical text into single rows. Scene-description hallucinations in on_screen_text are filtered at report time. Use --force to regenerate reports after re-analysis.
Running scripts
This skill's scripts live in scripts/ alongside this file. Before running any script, resolve its absolute path from this skill's own directory — do not assume the shell cwd is the skill folder, the repo root, or the workspace. Stay in the workspace (so media paths resolve) and pass the absolute script path to uv run:
uv run <skill_directory>/scripts/extract_interval_frames.py --input "<path-to-media>"<skill_directory> is a placeholder. Never pass those angle brackets to the shell — the command will fail. Replace it with a real absolute directory before invoking uv run.
How to get that directory (do this yourself; do not ask the user first; do not skip the skill):
- If your tools showed a filesystem path when loading this
SKILL.md, stripSKILL.mdand use that folder. - If you already ran another mediaskills script (for example
.../audio/scripts/extract.py), this skill is a sibling of that folder: same parent, directory namevision-analysis. - Otherwise search standard install locations and confirm the script exists:
NAME=vision-analysis
for d in \
"$HOME/.agents/skills/$NAME" \
"$HOME/.cursor/skills/$NAME" \
"$HOME/.codex/skills/$NAME" \
"$HOME/.claude/skills/$NAME" \
"$PWD/.agents/skills/$NAME" \
"$PWD/.cursor/skills/$NAME" \
"$PWD/skills/$NAME"
do
if [ -f "$d/SKILL.md" ] && [ -e "$d/scripts/extract_interval_frames.py" ]; then
SKILL_DIR=$(cd "$d" && pwd)
break
fi
done
[ -n "$SKILL_DIR" ] || { echo "mediaskills: $NAME not found" >&2; exit 1; }
uv run "$SKILL_DIR/scripts/extract_interval_frames.py" --input "<path-to-media>"Prefer absolute paths for --input / --output when cwd is uncertain.
Missing binaries vs permissions
Before running any script, treat these two failures differently:
- If a required binary (
uv,ffmpeg,ffprobe,tesseract) reportsNo such file or directoryorcommand not found: this is a missing or unreachable binary, not a permissions issue. Escalating sandbox permissions will not fix it. Runcommand -v uv,command -v ffmpeg,command -v ffprobe, andcommand -v tesseractto see whether they resolve at all. If not, install or re-link them (install-media-toolsdoctor/install) rather than retrying with wider permissions.tesseractis required for the legacy OCR path (compile_report.py); agent-vision reports still needffmpeg/ffprobe/uv. - Only escalate sandbox permissions if the error is explicitly a permission denial (e.g.
Operation not permitted,Permission denied).
Recipe: interval frames for text / forced narrative
# 1. Extract 1 frame per second
uv run <skill_directory>/scripts/extract_interval_frames.py --input program.mp4
# 2. For each batch: get paths, analyze images yourself, write batch JSON
uv run <skill_directory>/scripts/get_frame_batch.py --manifest-path .mediaskills/generated/program_interval_frames.json --batch-index 0
# 3. After analyzing images in batch 0, merge your JSON
uv run <skill_directory>/scripts/merge_analysis.py \
--manifest-path .mediaskills/generated/program_interval_frames.json \
--frames-json batch0_analysis.json
# 4. Repeat step 2–3 for batch-index 1, 2, ... until all frames analyzed
# 5. Required validation (do not skip before reports)
uv run <skill_directory>/scripts/validate_analysis.py --analysis-path .mediaskills/generated/program_frame_analysis_....json
# 6. Reports
uv run <skill_directory>/scripts/text_on_screen_report.py --analysis-path .mediaskills/generated/program_frame_analysis_....json
uv run <skill_directory>/scripts/forced_narrative_report.py --analysis-path .mediaskills/generated/program_frame_analysis_....jsonRead references/AGENT_FRAME_ANALYSIS.md for the exact per-frame JSON schema and classification rules.
Forced narrative deliverable format
After forced_narrative_report.py (agent vision path) or compile_forced_narrative_report.py (OCR path), present burned-in dialogue in this table — not the raw on-screen text dump:
| Embedded TC | Speaker / context | Text (OCR) |
| 01:01:27:00 | Squatter | I want you to go before the throne of God! |
| 01:02:00:00 | Squatter | Can you get off the property? You're here illegally. |
| 01:02:30:00 | Squatter (phone) | Dispatch, they're trying to break into my bathroom. |
Rules for the agent:
- Embedded TC — use
embedded_tcfrom the report JSON when the source has a tmcd track; otherwise use file-relativestart_timecode. - Speaker — parse from burned-in caption labels (
SQUATTER:,OFFICER:, etc.); use—when no label is visible. - Text — literal burned-in dialogue only; exclude slates, legal cards, credits, show logos, and OCR garbage.
- Full coverage — include every dialogue line in the report; do not sample or truncate.
- JSON — cite the paired
*_forced_narrative_*.jsonfor programmatic use; CSV has the same columns.
Recipe: shot-based analysis (graphics, title cards)
# 1–2. From shots skill: detect cuts, extract midpoint frames
# uv run <shots_skill_directory>/scripts/detect.py --input program.mp4
# uv run <shots_skill_directory>/scripts/extract-frames.py --shots-path .mediaskills/generated/program_shots_....json
# 3. Batch + agent-analyze + merge (same loop as above)
uv run <skill_directory>/scripts/get_frame_batch.py --manifest-path .mediaskills/generated/program_shots_....json --batch-index 0
uv run <skill_directory>/scripts/merge_analysis.py --manifest-path ... --frames-json batch0_analysis.json
# 4. Graphics reports
uv run <skill_directory>/scripts/graphics_on_screen_report.py --analysis-path .mediaskills/generated/program_frame_analysis_....json
uv run <skill_directory>/scripts/extract_title_text.py --analysis-path .mediaskills/generated/program_frame_analysis_....jsonLegacy OCR path (no agent vision)
tesseract only — no text-type classification:
uv run <skill_directory>/scripts/compile_report.py --input program.mp4
uv run <skill_directory>/scripts/compile_forced_narrative_report.py \
--onscreen-json .mediaskills/generated/program_onscreen_text_....json \
--input program.mp4The second step filters OCR rows to burned-in dialogue and writes the forced-narrative table format above.
Gotchas
- Agent vision required for classified on-screen text — scripts extract frames and merge JSON; they do not interpret images.
- Long programs — 1s interval on a 1-hour show = 3600 frames; use
--interval 2or--max-frameson extract, or analyze a subset. - Incremental merge —
merge_analysis.pyappends batches; re-run with--forceto replace all frame entries. - Report reuse — report scripts skip regeneration unless
--forcewhen a matching report exists.
Available scripts
| Script | Purpose |
extract_interval_frames.py | Still every N seconds → manifest + JPGs |
get_frame_batch.py | Slice of frames from manifest for agent batches |
merge_analysis.py | Merge agent-written frame JSON into analysis doc |
validate_analysis.py | Check analysis JSON before reports |
analysis_schema.py | JSON schema for analysis documents |
text_on_screen_report.py | All text types, timecoded |
forced_narrative_report.py | Burned-in subtitles — dialogue table (agent analysis) |
compile_forced_narrative_report.py | Burned-in subtitles — dialogue table (from OCR JSON) |
graphics_on_screen_report.py | Graphics/titles (excludes subtitles) |
extract_title_text.py | Title cards and graphics text |
compile_report.py | Legacy tesseract OCR |
prepare_manifest.py | Legacy interval manifests |
list_extractions.py / compile_all_reports.py | Inventory helpers |
Acceptance checks (agent must pass before delivery)
- Contract: exit 0,
ok: true, everyoutput_pathsentry exists and is non-empty. - Skill gate: run
validate_analysis.pysuccessfully before any delivery report (text_on_screen_report,forced_narrative_report, etc.). - Coverage:
analyzed_countequalsframe_count; do not sample-deliver partial analysis. - Spot-check: verify first/middle/last report rows against source frames; exclude hallucinated scene text from dialogue tables.
- On failure: re-merge or re-analyze; do not ship unvalidated reports. For exhaustive frame-accurate dialogue, prefer
forced-narrative-exact.
Do not use for
- Built-in vision/LLM calls (agent analyzes frames; scripts merge JSON only)
- Replacing
speech-captionsfor dialogue transcription - Real-time stream analysis
Related skills
shots— cut detection and midpoint stillsimage— single-still OCRvideo-transformation— frame extraction at arbitrary timestamps
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

