Even-Sampling Algorithm for Thinning Video Frames in Claude-Video

The even-sampling algorithm reduces candidate video frames to a fixed-size subset by selecting evenly spaced indices while guaranteeing the first and last frames are always retained.

The bradautomates/claude-video repository implements this deterministic thinning mechanism within its watch skill to manage token budgets when processing video content. When candidate frames exceed user-specified or internally computed limits, the even-sampling algorithm ensures uniform temporal coverage without clustering in dense regions.

Core Implementation

The algorithm centers on two helper functions defined in skills/watch/scripts/frames.py that handle index calculation and frame selection.

_even_indices Function

The _even_indices(count, n) function computes which indices to select from a collection of length count when you need exactly n samples. Located at lines 83–92, it implements the mathematical formula:

round(i * (count - 1) / (n - 1))   for i in range(n)

This distributes n points uniformly across the interval [0, count-1]. The function handles edge cases explicitly: when n >= count it returns every index (list(range(count))), and when n <= 1 it returns only the first index ([0]). By using count - 1 in the numerator and n - 1 in the denominator, the calculation always includes both the first frame (index 0) and the last frame (index count-1).

_even_sample Function

The _even_sample(candidates, n) function at lines 93–104 executes the actual thinning operation. It accepts a list of candidate frame dictionaries and the desired sample size n, then performs three critical operations:

  1. Selection: Uses _even_indices to determine which frames to keep
  2. Cleanup: Deletes JPEG files for dropped frames using Path(cand["path"]).unlink() to free disk space
  3. Re-indexing: Updates the index field of surviving frames to create a contiguous sequence starting from 0

This ensures downstream code receives a clean, sequentially indexed subset without orphaned files consuming storage.

How the Even-Sampling Algorithm Works

The thinning process follows a deterministic four-step pipeline when the watch skill processes video segments.

1. Determine the Sample Budget The calling code establishes a cap based on context—whether processing transcript timestamps, scene cuts, or keyframes. If candidates exceed this cap, the algorithm triggers automatically.

2. Calculate Uniform Indices Using the formula round(i * (count - 1) / (n - 1)), the algorithm maps the desired sample size onto the full candidate range. This mathematical approach guarantees O(n) complexity without requiring additional sorting beyond the original chronological order.

3. Select and Clean Frames The function pulls corresponding frame dictionaries from the candidate list, permanently removes unselected files from the filesystem, and reassigns indices to maintain continuity.

4. Preserve Temporal Boundaries By always including indices 0 and count-1, the algorithm ensures the resulting thumbnail set spans the entire video segment regardless of how aggressively the budget constraints reduce the sample size.

Usage in the Video Processing Pipeline

The even-sampling algorithm serves as the universal thinning mechanism across three distinct extraction engines in skills/watch/scripts/frames.py.

Timestamp Extraction When users supply transcript timestamps via extract_at_timestamps (lines 54–58), the algorithm caps the number of cues. If a user provides seven timestamps but sets max_frames=4, the system retains the first, last, and two evenly spaced intermediate frames.

Scene-Cut Detection After detecting scene cuts in extract_scene_or_uniform, the engine may generate more candidates than the allowed budget. Lines 145–146 invoke _even_sample to reduce the set while maintaining representative coverage across the entire clip duration.

Keyframe Deduplication Following keyframe extraction and deduplication (lines 75–76), the same thinning logic applies to ensure the final set adheres to token-cost constraints without sacrificing temporal range.

Python Code Examples

Direct Invocation of _even_sample

from pathlib import Path
from skills.watch.scripts.frames import _even_sample

# Generate 30 candidate frames

candidates = [
    {"index": i, "path": f"/tmp/frame_{i:04d}.jpg"} 
    for i in range(30)
]

# Reduce to 10 evenly spaced frames

selected = _even_sample(candidates, n=10)

print("Chosen indices:", [f["index"] for f in selected])

# Output: Chosen indices: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

Thinning Timestamp Cues

from skills.watch.scripts.frames import extract_at_timestamps

video_path = "example.mp4"
timestamps = [0.0, 5.2, 10.1, 15.4, 20.0, 25.6, 30.0]

# Force reduction to 4 frames using even-sampling

frames, meta = extract_at_timestamps(
    video_path,
    Path("/tmp/output"),
    timestamps,
    max_frames=4,
)

print(f"Selected {meta['selected_count']} frames")  # → 4

Scene Extraction Pipeline Integration


# Simplified excerpt from extract_scene_or_uniform workflow

scene_candidates = detect_scene_changes(video_path)

if len(scene_candidates) > max_frames:
    # Apply even-sampling to respect budget constraints

    final_frames = _even_sample(scene_candidates, max_frames)
    # Surviving frames are re-indexed 0..max_frames-1

    # Dropped frame files are automatically deleted

Summary

  • Deterministic Coverage: The even-sampling algorithm uses linear interpolation (round(i * (count - 1) / (n - 1))) to select frames at uniform intervals.
  • Boundary Preservation: First and last frames are always retained, ensuring the thumbnail set represents the full temporal span of the video.
  • Resource Management: Unselected frames are immediately deleted via Path.unlink() to prevent disk space exhaustion during long processing jobs.
  • Universal Application: The same _even_sample logic governs timestamp, scene-cut, and keyframe extraction pipelines in skills/watch/scripts/frames.py.
  • O(n) Performance: Index calculation requires only a single pass with no sorting overhead, making it suitable for real-time video processing workflows.

Frequently Asked Questions

How does the even-sampling algorithm decide which frames to keep?

The algorithm calculates evenly spaced indices across the full candidate range using the formula round(i * (count - 1) / (n - 1)) for each position i from 0 to n-1. This mathematical approach guarantees the first frame (index 0) and last frame (index count-1) are always selected, with intermediate frames distributed uniformly between them.

What happens to frames that are not selected by the algorithm?

Dropped frames are permanently removed from the filesystem. The _even_sample function calls Path(cand["path"]).unlink() on every unselected candidate to free disk space immediately. The surviving frames then receive new consecutive indices starting from 0 to ensure downstream components receive a clean, sequential dataset.

Where is the even-sampling algorithm implemented in the codebase?

The core logic resides in skills/watch/scripts/frames.py at lines 83–104. The _even_indices function handles the mathematical index calculation, while _even_sample manages frame selection, file deletion, and re-indexing. This module is imported and utilized by the main orchestration logic in skills/watch/scripts/watch.py.

Why use even-sampling instead of random sampling for frame thinning?

Even-sampling provides deterministic, uniform temporal coverage that avoids clustering frames in high-activity regions while ensuring sparse sections remain represented. Unlike random sampling, it guarantees O(n) performance without sorting overhead and consistently preserves the first and last frames—critical for maintaining context in video analysis tasks.

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 →