How Claude Video Scales Frame Budget With Video Duration
Claude Video calculates a target frame budget that grows with video duration using tiered caps defined in skills/watch/scripts/frames.py, automatically adjusting extraction density to balance visual detail against token consumption.
The bradautomates/claude-video repository implements an intelligent sampling strategy that adapts extraction rates based on content length. Understanding how the Claude Video frame budget scales with video duration helps developers optimize token usage while preserving critical visual information across different content types.
Tiered Budget Logic in frames.py
The core algorithm resides in skills/watch/scripts/frames.py, which provides two distinct budgeting strategies depending on whether you process a complete video or a specific time range.
Full-Video Processing with auto_fps
For complete video scans, the auto_fps function (lines 22-36) implements a five-tier scaling system that calculates target frame counts based on duration:
- Ultra-short clips (≤30 seconds): Targets approximately 1 fps, using the formula
min(max_frames, max(12, int(round(duration_seconds))))to ensure at least 12 frames even for brief content. - 30 seconds to 1 minute: Hard cap at 40 frames regardless of exact duration.
- 1 minute to 3 minutes: Fixed budget of 60 frames.
- 3 minutes to 10 minutes: Fixed budget of 80 frames.
- Long videos (>10 minutes): Uses the full
max_framesallowance (default 100).
The function returns an FPS value by dividing the target frame count by the duration, then passing the result through _clamp_fps to enforce safety limits.
Focused Range Processing with auto_fps_focus
When users specify --start and --end timestamps, the auto_fps_focus function (lines 41-55) applies a denser extraction strategy to preserve detail in narrow segments:
- ≤5 seconds: Targets ~6 fps for maximum granular detail.
- 5-15 seconds: Reduces to ~4 fps while maintaining high density.
- 15-30 seconds: Fixed budget of 60 frames.
- 30 seconds to 1 minute: Fixed budget of 80 frames.
- ≥3 minutes: Falls back to the full
max_framescap.
This focused approach ensures that cropped segments receive proportionally more frames per second than full-video processing would allocate.
Safety Limits and FPS Clamping
Both budgeting functions rely on _clamp_fps (lines 49-53) to enforce constraints that prevent runaway token usage. The implementation sets a hard maximum of 2 fps (MAX_FPS = 2.0) and guarantees at least one frame for any non-zero duration. This safety mechanism ensures that even high-frame-rate source material cannot exceed the budgetary limits, while ensuring every video yields extractable content.
Integration with the Watch Pipeline
The skills/watch/scripts/watch.py file (lines 55-58) orchestrates the selection between these strategies based on user input:
if focused:
fps, target = auto_fps_focus(effective_duration, max_frames=budget_cap)
else:
fps, target = auto_fps(effective_duration, max_frames=budget_cap)
The budget_cap value defaults to the frame_cap defined in skills/watch/scripts/config.py, though users can override this via the --max-frames flag to raise or lower the extraction ceiling.
Practical Usage Examples
These commands demonstrate how the automatic budgeting applies to real-world scenarios:
# 45-second clip (no range) → auto_fps yields ~45 frames (≈1 fps)
watch myshortclip.mp4
# 2-minute clip (no range) → capped at 60 frames
watch my2min.mp4
# 12-minute clip (no range) → uses default cap of 100 frames
watch my12min.mp4
# 10-second segment extraction → auto_fps_focus yields ~60 frames
watch my5min.mp4 --start 00:02:30 --end 00:02:40
To override automatic calculations, specify --max-frames, --fps, or --detail flags, which the auto_fps* functions respect when computing final budgets.
Summary
- Claude Video uses tiered logic in
skills/watch/scripts/frames.pyto scale frame budgets with video duration, ensuring short clips receive dense coverage while long videos respect cost constraints. - Short videos (≤30s) receive approximately 1 fps extraction, while medium videos hit fixed caps (40-80 frames) to control token costs.
- Long videos (>10min) respect the user-defined
max_frameslimit (default 100) regardless of additional length. - Focused ranges via
--start/--endtrigger denser sampling (up to 6 fps) to preserve detail in short segments without affecting the global budget. - A hard cap of 2 fps enforced by
_clamp_fpsprevents excessive token usage regardless of source material or duration.
Frequently Asked Questions
What is the maximum frame rate Claude Video will extract?
Claude Video enforces a hard limit of 2 fps through the _clamp_fps function in skills/watch/scripts/frames.py. Even if the budget calculation suggests higher density for short clips, this ceiling prevents excessive token consumption on high-frame-rate source material.
How does the frame budget differ for short clips versus long videos?
For clips under 30 seconds, the system targets approximately 1 fps to ensure adequate visual coverage. As duration increases, the budget switches to fixed caps (40, 60, or 80 frames) until hitting the 10-minute threshold, where it defaults to the maximum configured frames (typically 100). This tiered approach ensures short content retains detail while long content avoids prohibitive token costs.
Can I override the automatic frame budget calculation?
Yes. Users can supply --max-frames, --fps, or --detail flags when invoking the watch command. These values pass into auto_fps and auto_fps_focus as the max_frames parameter, which the functions use to clamp their calculated targets according to the tiered logic while respecting your specified ceiling.
Where is the default frame cap configured?
The default frame_cap resides in skills/watch/scripts/config.py, which feeds into the budget_cap variable used by watch.py. When no user override is provided, this configuration supplies the 100-frame default that limits extraction for videos exceeding 10 minutes in duration.
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 →