How the MAX_FPS Cap of 2.0 Impacts Frame Selection in claude-video

The MAX_FPS = 2.0 hard ceiling in claude-video ensures frame extraction never exceeds 2 frames per second, enforcing token budget compliance by clamping calculated rates regardless of video length or the --max-frames parameter.

The MAX_FPS constant sits at the heart of claude-video's frame selection algorithm in bradautomates/claude-video. This repository implements a Claude-powered video analysis tool that extracts visual frames for LLM consumption, balancing comprehensiveness against token limits. Understanding how this 2.0 FPS cap shapes frame selection helps users predict behavior across different video durations and optimize their --max-frames settings.

Where MAX_FPS Is Defined and Enforced

In skills/watch/scripts/frames.py, the constant is declared at module level:

MAX_FPS = 2.0

Source: skills/watch/scripts/frames.py#L19

This value feeds into the _clamp_fps helper function, which applies the ceiling before any final frame calculations:

def _clamp_fps(fps: float) -> float:
    return min(fps, MAX_FPS)

Source: skills/watch/scripts/frames.py#L49-L52

Both automatic FPS calculation paths—auto_fps for standard mode and auto_fps_focus for focused frame selection—route their computed target rates through _clamp_fps. This architectural choice guarantees the 2.0 FPS limit applies universally, regardless of which extraction strategy is active.

How Frame Selection Works Under the Cap

Claude-video uses a budget-driven extraction model. Rather than extracting at a fixed rate, it calculates what FPS would hit the user-specified --max-frames limit (default 100) given the video's duration. The MAX_FPS cap then truncates this calculation.

The mathematical flow is:

  1. Compute target_fps = max_frames / duration_seconds
  2. Apply actual_fps = min(target_fps, MAX_FPS)
  3. Derive final frame count: total_frames = actual_fps × duration

This creates two distinct behavioral regimes based on video length.

Impact on Long vs. Short Videos

Long Videos: Cap-Enforced Sparsity

For videos exceeding 50 seconds with default settings, the budget math would suggest FPS below 2.0 anyway (100 frames ÷ 50s = 2.0 fps). For longer content, the budget itself limits extraction before the cap engages.

However, with elevated --max-frames values (e.g., 300 or 500), the cap becomes the active constraint. A 5-minute video with --max-frames 600 would mathematically support 2.0 fps exactly—but cannot exceed it. The cap thus protects token budgets from users who might otherwise request frame-dense analysis of lengthy content.

Short Videos: Density at the Ceiling

For videos under 50 seconds, the budget math often produces target FPS above 2.0. Consider a 10-second clip with default --max-frames 100:

  • Uncapped calculation: 100 ÷ 10 = 10.0 fps
  • After _clamp_fps: 2.0 fps
  • Actual frames extracted: 20 frames

The cap preserves temporal density up to the limit but prevents over-sampling that would waste tokens on near-duplicate frames. This is particularly relevant for auto_fps_focus mode, which attempts denser extraction around detected scene changes—the cap ensures even this aggressive mode respects the 2.0 ceiling.

Practical Configuration Implications

Users cannot override MAX_FPS through CLI flags. The constant is hardcoded, making the 2.0 ceiling a non-negotiable system constraint according to the claude-video source code.

To maximize frame coverage:

  • Increase --max-frames rather than expecting higher density—this extends the cap's reach across longer durations
  • Split long videos into shorter segments if scene-level granularity is critical
  • Use --focus mode (auto_fps_focus) to concentrate the 2.0 fps budget on high-information regions rather than uniform sampling

Summary

  • MAX_FPS = 2.0 in skills/watch/scripts/frames.py enforces a hard extraction ceiling
  • _clamp_fps applies this limit to both auto_fps and auto_fps_focus calculations
  • Short videos hit the cap and extract at exactly 2.0 fps despite higher budget allowances
  • Long videos may fall below the cap based on --max-frames ÷ duration math
  • The cap is immutable via configuration—users must work within its constraints through frame budget allocation and video segmentation

Frequently Asked Questions

What is the exact value of MAX_FPS in claude-video?

The MAX_FPS constant is set to 2.0 at line 19 of skills/watch/scripts/frames.py. This value has remained fixed in the repository's main branch and cannot be modified through command-line arguments or configuration files.

Can I extract more than 2 frames per second from a short video?

No. Even with --max-frames set higher than your video duration would require at 2.0 fps, the _clamp_fps function enforces the ceiling. A 5-second video with --max-frames 100 still extracts only 10 frames (2.0 fps × 5s), not 100 frames. The cap takes precedence over the budget calculation when the budget would permit higher rates.

Why does claude-video limit frame extraction to 2 FPS?

The 2.0 FPS cap serves as a token economy mechanism. Claude's vision capabilities consume significant context window per image; unconstrained frame rates from short videos could rapidly exhaust available tokens. The cap ensures predictable, bounded resource consumption across all video lengths while preserving sufficient visual information for analysis tasks.

How does MAX_FPS interact with the --focus flag?

The --focus flag activates auto_fps_focus, which applies intelligent scene detection to concentrate frames on high-variance regions. However, both auto_fps and auto_fps_focus routes pass through _clamp_fps. Focused extraction redistributes the 2.0 fps budget temporally—it does not increase the rate. You get smarter frame placement, not more frames per second.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →