# How to Extract Frames at Specific Timestamps Using the --timestamps Flag in Claude-Video

> Easily extract frames at specific timestamps using Claude-Video's --timestamps flag. Learn to specify times in HH:MM:SS, MM:SS, or seconds format for precise video frame extraction.

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

---

**Claude-Video's `watch` command can extract exact frames at user-specified timestamps using the `--timestamps` flag with comma-separated time values in `HH:MM:SS`, `MM:SS`, or seconds format.**

The claude-video repository provides a powerful video analysis toolkit that includes precise frame extraction capabilities. When you need to capture specific moments from a video rather than relying on automatic sampling, the `--timestamps` flag allows you to extract frames at exact temporal coordinates. This functionality integrates seamlessly with the tool's transcript analysis and detail-level framing systems, storing output as `cue_*.jpg` files alongside regular frames.

## Understanding the --timestamps Flag

The `--timestamps` flag accepts a comma-separated string of time values that specify exactly where in the video to capture frames. According to the source code in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py), the entry point parses this input using `parse_timestamps()` between lines 81-86, converting human-readable time strings into seconds for processing.

**Supported timestamp formats include:**
- Seconds only: `12` or `12.5`
- Minutes and seconds: `01:30` or `01:30.250`
- Hours, minutes, and seconds: `00:05:00` or `00:05:00.500`

When you invoke the `watch` skill with this flag, the system validates each timestamp against optional `--start` and `--end` boundaries before proceeding to extraction.

## The Frame Extraction Pipeline

The core extraction logic resides in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) within the `extract_at_timestamps()` function. This routine handles the heavy lifting from lines 44-90, orchestrating FFmpeg subprocesses to pull exact frames without re-encoding the entire video.

### Directory Preparation and Cleanup

Before extraction begins, the function prepares the output directory at lines 44-48. It creates the directory if missing and removes any existing `cue_*.jpg` files to prevent conflicts with previous runs:

```python
out_dir.mkdir(parents=True, exist_ok=True)
for existing in out_dir.glob("cue_*.jpg"):
    existing.unlink()

```

### Focus Window Clamping

If you specify `--start` or `--end` parameters alongside `--timestamps`, the system clamps the requested timestamps to this focus window (lines 48-52). Timestamps falling outside the range are tracked in the `dropped_out_of_window` metadata count rather than being extracted.

The logic uses:

```python
lo = start_seconds or 0.0
hi = end_seconds if end_seconds is not None else float("inf")

```

### Frame Cap and Even Sampling

When the number of requested timestamps exceeds the `--max-frames` limit, the system applies intelligent sampling at lines 54-57. The `_even_indices` helper selects evenly distributed timestamps from your list, always preserving the first and last cues while dropping intermediate frames to meet the cap.

### FFmpeg Extraction Process

For each validated timestamp, the system executes FFmpeg via `subprocess.run()` (lines 60-73). The command seeks to the specified time using `-ss` and extracts a single frame:

```python
cmd = [
    "ffmpeg", "-y", "-ss", str(t), "-i", str(video_path),
    "-frames:v", "1", "-q:v", "2",
    "-vf", f"scale={resolution}:-1",
    str(out_path)
]

```

Each extracted frame is saved as `cue_####.jpg` in the `<work-dir>/frames/` directory, with zero-padded numbering to maintain chronological order.

## Command-Line Usage Examples

**Extract specific moments from a YouTube video:**

```bash
watch "https://youtu.be/ABC123" \
  --timestamps "00:05,00:30,02:15" \
  --detail transcript

```

This command downloads the video, extracts frames at 5 seconds, 30 seconds, and 2 minutes 15 seconds, and includes only these cue frames in the final report.

**Combine cue frames with balanced sampling on a local file:**

```bash
watch /path/to/video.mp4 \
  --timestamps "00:10,01:00,01:30,02:00" \
  --detail balanced \
  --max-frames 50

```

Here, the four specified timestamps are extracted alongside automatically selected balanced frames, with the total frame count capped at 50.

## Programmatic API Usage

You can invoke the extraction logic directly from Python without using the CLI:

```python
from pathlib import Path
from skills.watch.scripts.frames import extract_at_timestamps

video = "/tmp/video.mp4"
out_dir = Path("/tmp/frames")
timestamps = [12.0, 30.5, 125.0]  # seconds as floats

frames, meta = extract_at_timestamps(
    video_path=video,
    out_dir=out_dir,
    timestamps=timestamps,
    resolution=512,
    max_frames=10,
)

print("Extracted frames:", frames)
print("Metadata:", meta)

# meta contains: requested_count, selected_count, dropped_out_of_window

```

The function returns a tuple containing the list of extracted frame paths and a metadata dictionary tracking how many timestamps were requested, selected, and dropped due to window constraints.

## Integration with Detail Levels

After extraction, [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py) merges the cue frames with regular detail-engine frames (lines 27-31) using the `merge_frames()` function. This ensures that timestamp-specific frames appear alongside auto-generated frames in the final markdown report, each annotated with their timestamp and reason (`transcript-cue`).

The cue frames use a distinct `cue_` prefix to avoid filename collisions with the standard `frame_*.jpg` naming convention used by the detail engine.

## Summary

- **Pass timestamps** to the `watch` command using `--timestamps "00:01,00:30,02:15"` with flexible formatting support.
- **Source files**: Parsing occurs in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py) (lines 81-86); extraction logic lives in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) (lines 44-90).
- **Window clamping**: Combine `--timestamps` with `--start` and `--end` to restrict extraction to specific video segments.
- **Frame capping**: When requests exceed `--max-frames`, the system evenly samples your timestamp list while preserving endpoints.
- **Output**: Frames are saved as `cue_*.jpg` in the work directory's `frames/` folder and merged into the final report.

## Frequently Asked Questions

### What timestamp formats does claude-video support?

Claude-video accepts timestamps in several formats: plain seconds (`45` or `45.5`), minutes and seconds (`01:30`), or full hours-minutes-seconds (`00:05:00`). Fractional seconds are supported in all formats (e.g., `01:30.250`). The `parse_time()` function in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) (lines 95-104) handles these conversions, normalizing all inputs to float seconds for FFmpeg processing.

### How does the --timestamps flag interact with --start and --end?

When you specify `--start` or `--end` alongside `--timestamps`, the system filters your timestamp list to include only values within that window. Timestamps outside the range are counted in the `dropped_out_of_window` metadata field but are not extracted. This allows you to specify a broad list of interesting moments while restricting actual extraction to a specific segment of interest.

### What happens if I request more timestamps than --max-frames allows?

If your comma-separated timestamp list contains more entries than the `--max-frames` limit, the system applies even sampling via `_even_indices` in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) (lines 54-57). It preserves the first and last timestamps from your list and selects evenly spaced intermediate timestamps to stay within the limit, ensuring temporal distribution across your requested moments.

### Where are the extracted frames saved and how are they named?

Extracted timestamp frames are saved in the `<work-directory>/frames/` directory with the naming pattern `cue_####.jpg`, where `####` is a zero-padded index. This distinguishes them from automatically generated detail frames (`frame_*.jpg`). After extraction, [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) merges these cue frames into the final analysis report, listing each frame's path, exact timestamp, and extraction reason.