How the `--timestamps` Flag Works in claude-video: Extracting Frames at Specific Moments

The --timestamps flag in claude-video parses comma-separated time values, validates them against optional range limits and frame budgets, then uses ffmpeg to extract JPEG frames at those exact moments, guaranteeing user-requested frames are preserved in the final analysis.

The claude-video skill provides fine-grained control over video frame extraction for AI analysis. When you need to ensure specific moments—such as transcript cues or critical events—are included in the visual context, the --timestamps flag lets you pin exact frames regardless of the automatic keyframe selection logic.

Parsing the Timestamp Input

The journey from user input to extracted frames begins with CLI argument processing and string normalization.

Flag Declaration in watch.py

In skills/watch/scripts/watch.py, the --timestamps argument is registered as a string input (lines 42–48). When invoked, the raw string is passed to parse_timestamps at line 81 for preprocessing before any extraction occurs.

Normalizing Time Formats in frames.py

The parse_timestamps function in skills/watch/scripts/frames.py (lines 95–107) handles the heavy lifting of converting human-readable time strings into machine-usable seconds. It splits the comma-separated input and normalizes each token using the parse_time helper, supporting multiple formats:

  • SS (seconds only)
  • MM:SS (minutes and seconds)
  • HH:MM:SS (hours, minutes, and seconds)

The function returns a sorted, deduplicated list of seconds ready for extraction.

Filtering Against Frame Budgets and Ranges

Before invoking ffmpeg, claude-video applies constraints to ensure the requested timestamps respect the active analysis window and global frame limits.

Range Validation and Capping Logic

In extract_at_timestamps (lines 48–62 of frames.py), the system filters the parsed timestamp list against the optional start_seconds and end_seconds boundaries. Timestamps falling outside this window are discarded and reported in the operation metadata.

If max_frames is set and the number of valid timestamps exceeds this budget, the function performs an even-sample selection to choose which cues to extract, ensuring uniform temporal coverage across the specified range.

Extracting Frames via ffmpeg

For each timestamp that survives filtering, claude-video invokes ffmpeg to capture a single high-quality frame.

The ffmpeg Command Construction

The extraction logic in frames.py (lines 63–73) constructs an ffmpeg command using fast-seek (-ss <timestamp>) for efficient random access:

ffmpeg -ss <timestamp> -i <video_path> -frames:v 1 -vf <scale_filter> -q:v 4 <output_path>

Key parameters include:

  • -ss <timestamp>: Fast seek to the exact second
  • -frames:v 1: Capture only one frame
  • -q:v 4: Set JPEG quality

The extracted frames are saved with the prefix cue_ (e.g., cue_0000.jpg, cue_0001.jpg) in the output directory.

Operation Metadata

The extract_at_timestamps function returns two objects:

  • out: A list of dictionaries describing each extracted frame (index, timestamp_seconds, path, reason="transcript-cue")
  • meta: Statistics including candidate count, selected count, drop reasons, and fallback status

This metadata is surfaced in the final report (handled in watch.py lines 78–88) to provide transparency about which requested timestamps were captured versus filtered.

Integrating Cue Frames into the Analysis

After extraction, watch.py merges these cue frames with frames selected by the detail engine (keyframes, scene-aware frames, etc.) via the merge_frames function. This integration guarantees that user-requested timestamps are never discarded, even when the overall frame budget is constrained by the --max-frames or --detail settings.

Practical Usage Examples

Extracting Specific Moments

Request exact frames at 30 seconds, 1 minute 15 seconds, and 2 minutes 5 seconds:

watch https://example.com/video.mp4 \
      --detail balanced \
      --timestamps "00:30,01:15,02:05"

The resulting report includes:

  • cue_0000.jpg (t=00:30, reason=transcript-cue)
  • cue_0001.jpg (t=01:15, reason=transcript-cue)
  • cue_0002.jpg (t=02:05, reason=transcript-cue)

Combining with Range Constraints and Frame Caps

Focus on a specific window while limiting total frames:

watch local_video.mov \
      --detail efficient \
      --start 00:10 --end 00:40 \
      --timestamps "00:12,00:18,00:35,00:45" \
      --max-frames 10

In this scenario:

  • 00:45 falls outside the 10–40 second range and is dropped (reported in metadata)
  • The remaining three timestamps are extracted as cue frames
  • These merge with up to seven additional frames selected by the efficient detail engine

Summary

  • skills/watch/scripts/watch.py: Handles CLI parsing of --timestamps and orchestrates the extraction workflow (lines 42–48, 78–88).
  • skills/watch/scripts/frames.py: Contains parse_timestamps (lines 95–107) for time format normalization and extract_at_timestamps (lines 124–165) for ffmpeg invocation.
  • Time format support: Accepts SS, MM:SS, and HH:MM:SS formats automatically.
  • Budget protection: Cue frames are filtered against --start/--end ranges and --max-frames limits, then merged with detail-engine frames to ensure preservation.
  • Output: JPEGs prefixed with cue_ accompanied by structured metadata describing extraction results.

Frequently Asked Questions

What time formats does the --timestamps flag accept?

The flag accepts comma-separated values in three formats: raw seconds (e.g., 90), minutes and seconds (01:30), or full timestamps (00:01:30). The parse_time function in frames.py normalizes all variants to seconds before processing.

How does claude-video handle timestamps outside the specified range?

If you provide --start and --end parameters alongside --timestamps, the system filters out any timestamps falling outside that window during the extract_at_timestamps phase (lines 48–62 in frames.py). These drops are reported in the operation metadata so you can verify which cues were skipped.

Are timestamp-extracted frames guaranteed to appear in the final analysis?

Yes. According to the implementation in watch.py, cue frames extracted via --timestamps are merged with the detail-engine frame list through a dedicated merge_frames operation that prioritizes user-requested timestamps. Even when --max-frames caps the total count, these specific frames are preserved in the final set sent for AI analysis.

Can I use --timestamps with the --detail efficient setting?

Absolutely. The --timestamps flag works across all detail levels (minimal, efficient, balanced, high). When combined with efficient or any capped mode, the system extracts your specified timestamps first, then fills the remaining budget with automatically selected frames from the detail engine.

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 →