# Frame Cap Logic in Claude-Video Detail Modes: A Technical Breakdown

> Understand Claude-Video's frame cap logic across detail modes. Learn how automatic budgets, minimum thresholds, and _even_sample ensure optimal frame sampling for video analysis.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: deep-dive
- Published: 2026-08-13

---

**Claude-Video enforces frame caps across its five detail modes—uniform, focused uniform, scene, keyframe, and timestamp—using a combination of automatic budget calculations, minimum thresholds, and the `_even_sample` helper that preserves first and last frames while evenly spacing intermediates.**

The frame cap logic in bradautomates/claude-video determines how many visual frames survive extraction based on the selected detail mode and user constraints. Implemented primarily in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) and orchestrated via [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py), each engine computes its own candidate set or budget before converging on a hard limit via the shared `_even_sample` utility function.

## Uniform Mode: Duration-Based Auto-FPS Budgeting

In uniform mode, the frame cap logic derives its budget from the video's effective duration. The `auto_fps()` function (lines 22‑38 in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py)) calculates a target frame count based on clip length, which then serves as the extraction limit passed to ffmpeg via the `max_frames` parameter.

After extraction, frames undergo optional deduplication via `dedupe_perceptual()` before the final cap is enforced. If the extracted set exceeds the budget, `_even_sample` trims the list to the target count by keeping the first and last frames and evenly distributing the remainder.

```python
meta = get_metadata(video_path)
duration = meta["duration_seconds"]
fps, target = auto_fps(duration, max_frames=100)     # budget ≈ 100 frames

frames = extract(video_path, out_dir, fps=fps, max_frames=100)
frames, _ = dedupe_perceptual(frames)               # optional dedup

frames = _even_sample(frames, target)               # enforce cap

```

## Focused Uniform Mode: High-Density Sampling for Short Ranges

When users specify a `--start` and `--end` range, the engine switches to `auto_fps_focus()` (lines 41‑59 in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py)). This focused variant applies a higher density multiplier for short durations—approximately six times the duration for clips under five seconds—while still respecting the global `max_frames` ceiling.

The cap enforcement follows the same pattern as standard uniform mode: extract at the calculated FPS, dedupe, then invoke `_even_sample` to limit the final output.

```python
fps, target = auto_fps_focus(effective_duration, max_frames=100)
frames = extract(video_path, out_dir,
                fps=fps,
                start_seconds=start_sec,
                end_seconds=end_sec,
                max_frames=100)

```

## Scene Detection Mode: Minimum Threshold Fallback Logic

The scene engine operates differently by first collecting all scene-change candidates without an initial cap. The `extract_scene_or_uniform()` function (lines 110‑124) checks if the candidate count meets `SCENE_MIN_FRAMES` (defined as 8).

If the threshold is met, frames are deduplicated and capped to `max_frames` via `_even_sample`. If fewer than 8 scenes are detected, the engine falls back to uniform extraction logic using the standard `auto_fps` budget calculation.

```python
scene_frames = extract_scene_candidates(video_path, out_dir)
if len(scene_frames) >= SCENE_MIN_FRAMES:
    deduped, _ = dedupe_perceptual(scene_frames)
    selected = _even_sample(deduped, max_frames or len(deduped))
else:
    # fallback to uniform

    selected, _ = extract_scene_or_uniform(...)

```

## Keyframe Extraction Mode: I-Frame Minimum Requirements

Keyframe mode extracts all I-frames without an initial limit. The `extract_keyframes` implementation (lines 76‑82) validates the candidate count against `KEYFRAME_MIN` (set to 4).

If fewer than 4 keyframes are found, the engine falls back to uniform extraction. Otherwise, the candidates are deduplicated and passed to `_even_sample` for capping to the user-specified `max_frames` or the default of 100.

```python
candidates = extract_keyframes(video_path, out_dir, max_frames=50)[0]
if len(candidates) < KEYFRAME_MIN:
    # fallback to uniform as above

    ...
else:
    selected = _even_sample(candidates, max_frames or len(candidates))

```

## Timestamp Mode: Cue Point Window Filtering

For user-provided timestamps, the engine filters cues to the active time window before extraction. If the filtered timestamp count exceeds `max_frames`, the `extract_at_timestamps` function (lines 25‑57) reduces the set by selecting evenly-spaced indices via `_even_indices`, effectively capping the output without re-running extraction.

```python
timestamps = parse_timestamps("0:10,0:20,0:30")
frames, meta = extract_at_timestamps(video_path, out_dir,
                                     timestamps,
                                     max_frames=10)   # caps to 10 cues

```

## The _even_sample Cap Enforcement Mechanism

Every detail mode ultimately delegates its frame cap logic to `_even_sample` (lines 93‑108 in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py)). This helper receives a list of candidate frames and a target integer `n`, then returns exactly `n` frames: the first frame, the last frame, and `n‑2` evenly spaced intermediates.

The function physically deletes JPEGs for dropped frames and re-indexes the survivors to ensure sequential naming. This deterministic approach guarantees temporal coverage while respecting hard limits.

## Summary

- **Uniform mode** calculates caps via `auto_fps()` based on total duration, defaulting to 100 frames unless overridden.
- **Focused uniform mode** uses `auto_fps_focus()` for higher density in short ranges, subject to the same `max_frames` ceiling.
- **Scene mode** requires at least 8 detected scenes (`SCENE_MIN_FRAMES`); otherwise it falls back to uniform logic.
- **Keyframe mode** requires at least 4 I-frames (`KEYFRAME_MIN`); otherwise it falls back to uniform logic.
- **Timestamp mode** filters and evenly samples user cues to fit within the `max_frames` budget.
- All modes converge on the `_even_sample` helper to enforce final caps while preserving temporal distribution.

## Frequently Asked Questions

### What happens if a video has fewer than 8 scene changes?

If the scene detection engine finds fewer than `SCENE_MIN_FRAMES` (8) candidates, `extract_scene_or_uniform` automatically falls back to uniform extraction mode. It calculates an appropriate FPS budget based on the clip's duration and proceeds with standard uniform sampling.

### How does the _even_sample function distribute frames when capping?

The `_even_sample` function always preserves the first and last frames from the candidate set, then selects `n‑2` additional frames spaced evenly throughout the remaining sequence. This ensures temporal coverage across the full clip duration while meeting the exact target count.

### What is the default frame cap if no max_frames argument is provided?

All engines default to a `max_frames` value of 100 when the user does not specify an alternative limit. This default is enforced during the final `_even_sample` call or via the ffmpeg `max_frames` parameter during initial extraction.

### How does focused uniform differ from standard uniform mode?

Focused uniform mode activates when users provide `--start` and `--end` timestamps, triggering `auto_fps_focus()` instead of `auto_fps()`. This function applies a higher frame density multiplier for short clips under five seconds, while standard uniform mode spreads frames evenly across the entire video duration.