How Claude Video Frame Cap Logic Works and When Warnings Trigger
Claude Video uses a detail-level-based frame cap system (efficient=50, balanced=100, token-burner/transcript=unlimited) with an optional --max-frames override, and triggers warnings only when local files have unrecognized video extensions.
The frame cap logic in bradautomates/claude-video governs how many frames the tool extracts from videos before sending them to Claude. This mechanism balances token cost against visual fidelity, implementing a tiered cap system in config.py that the main watch.py script consumes during processing.
Frame Cap Levels and Configuration
The frame_cap function in skills/watch/scripts/config.py maps user-selected detail levels to numeric limits. This function is the single source of truth for extraction budgets.
| Detail level | Frame cap | Behavior |
|---|---|---|
efficient |
50 | Minimal token usage for cost-sensitive workflows |
balanced |
100 | Default reasonable budget for most use cases |
token-burner |
None | Uncapped—engine may emit every frame |
transcript |
None | Uncapped—intended for transcript-only cues |
| Any other value | 100 | Falls back to balanced default |
Source: config.py lines 65-74
The balanced level serves as the implicit default when no detail level is specified, ensuring predictable behavior across different invocation patterns.
How the Frame Cap Is Applied
The watch.py entry point implements a three-step resolution for determining the effective frame limit:
- Explicit override: If
--max-framesis provided on the command line, that value takes precedence unconditionally - Detail lookup: Otherwise,
frame_cap(detail)is called to retrieve the cap for the current detail level - Pipeline injection: The resulting
max_framesvalue is passed to extraction pipelines (keyframe, scene-change, uniform sampling, etc.)
Source: watch.py lines 73-78
This design allows users to either respect the curated presets or bypass them entirely for specific requirements.
Example: Explicit Frame Override
# Use balanced default (100 frames)
watch https://example.com/video.mp4
# Override to extract only 30 frames regardless of detail level
watch https://example.com/video.mp4 --max-frames 30
Example: Uncapped Extraction
# Set detail environment variable to disable frame limiting
export WATCH_DETAIL=token-burner
watch https://example.com/video.mp4
When Warnings Are Triggered
The codebase contains one frame-related warning path. Unlike the silent capping mechanism, this warning explicitly alerts users to potential issues with local file handling.
In skills/watch/scripts/download.py, the resolve_local helper validates file extensions against the VIDEO_EXTS set. Unrecognized extensions trigger a warning to stderr while permitting continuation:
if p.suffix.lower() not in VIDEO_EXTS:
print(
f"[watch] warning: {p.suffix} is not a known video extension, proceeding anyway",
file=sys.stderr,
)
Source: download.py lines 31-36
Warning Trigger Example
watch /path/to/video.xyz
Output:
[watch] warning: .xyz is not a known video extension, proceeding anyway
No warnings exist for frame-cap violations. The cap operates silently—extraction functions (extract_keyframes, extract_scene_or_uniform, etc.) simply stop producing frames once the limit is reached.
Key Files in the Frame Cap System
| File | Purpose | Critical Lines |
|---|---|---|
skills/watch/scripts/config.py |
Maps detail strings to numeric caps | 65-74 (frame_cap function) |
skills/watch/scripts/watch.py |
Resolves effective max_frames and drives extraction |
73-78 (cap consumption logic) |
skills/watch/scripts/download.py |
Emits extension warnings for local files | 31-36 (warning condition) |
Summary
- Frame caps are detail-driven:
efficient(50),balanced(100),token-burner/transcript(unlimited) --max-framesalways wins: Explicit user values override all preset logic- Capping is silent: No warnings when limits are reached—extraction simply stops
- Only one warning exists: Unrecognized video extensions in
download.pytrigger stderr output but don't halt processing - Three files implement the system:
config.py(definitions),watch.py(application),download.py(extension validation)
Frequently Asked Questions
How do I disable the frame cap entirely in Claude Video?
Set the WATCH_DETAIL environment variable to token-burner or transcript. Both detail levels return None from frame_cap(), signaling extraction pipelines to process without limits. Alternatively, pass a very high --max-frames value to override any preset.
Why don't I see a warning when my video hits the frame cap?
The frame cap mechanism is intentionally silent. According to the source code in watch.py, the cap value flows directly into extraction functions that simply stop emitting frames once exhausted. No telemetry or logging indicates when truncation occurs—this design choice prioritizes clean output over operational transparency.
What video extensions does Claude Video recognize without warning?
The VIDEO_EXTS set in download.py defines recognized extensions. While the exact set isn't enumerated in the analyzed lines, common containers like .mp4, .mov, .avi, .mkv, and .webm are standard. Any extension not in this set triggers the [watch] warning message but processing continues.
Can I use different frame caps for different extraction methods?
Not through built-in configuration. The max_frames value resolved in watch.py lines 73-78 is passed uniformly to all extraction pipelines. Per-method caps would require modifying the extraction functions themselves or implementing custom preprocessing logic outside the main codebase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →