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

> Learn how the --timestamps flag in claude-video extracts JPEG frames at specific moments using ffmpeg. Preserve exact frames for your video analysis.

- Repository: [bradautomates/claude-video](https://github.com/bradautomates/claude-video)
- Tags: how-to-guide
- Published: 2026-07-07

---

**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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/frames.py) (lines 63–73) constructs an ffmpeg command using fast-seek (`-ss <timestamp>`) for efficient random access:

```bash
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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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:

```bash
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:

```bash
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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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`](https://github.com/bradautomates/claude-video/blob/main/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.