# How to Extract Frames at Specific Timestamps with `--timestamps` in claude-video

> Easily extract frames at exact timestamps using claude-video with the --timestamps flag. Convert time strings into seconds and capture JPEGs with ffmpeg.

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

---

**The `claude-video` skill extracts exact frames at user-specified timestamps via the `--timestamps` flag, converting time strings like `"4:32,7:10,9:55"` into sorted, deduplicated seconds and invoking `ffmpeg` to capture JPEGs at each cue point.**

The `bradautomates/claude-video` repository provides a frame extraction engine that supports precise timestamp-based sampling through its CLI and Python API. When you pass the `--timestamps` argument to the watch skill, the system parses your time cues, filters them against optional start/end windows, and generates individual frame files marked with `"reason": "transcript-cue"` for identification in the final output.

## Understanding the Frame Engine Architecture

The timestamp extraction logic lives in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py), which orchestrates parsing, filtering, and image generation. The workflow moves through four distinct phases before merging results into the final frame set.

### Parsing Time Strings with `parse_timestamps()`

At lines 95–103 of [`frames.py`](https://github.com/bradautomates/claude-video/blob/main/frames.py), the `parse_timestamps()` function handles the initial conversion of the raw CLI string. It accepts comma-separated values in formats like `"4:32"` or `"7:10"`, converts each to floating-point seconds, and returns a sorted, deduplicated list.

```python
from skills.watch.scripts.frames import parse_timestamps

# Converts "4:32,7:10,9:55" to [272.0, 430.0, 595.0]

timestamps = parse_timestamps("4:32,7:10,9:55")

```

### Filtering and Sampling with `extract_at_timestamps()`

The `extract_at_timestamps()` function (lines 124–158) manages the core selection logic. This routine first validates each timestamp against user-provided `--start` and `--end` boundaries, dropping any cues that fall outside the active range. If the remaining count exceeds `max_frames`, the engine applies the `_even_indices` sampling strategy to evenly thin the list while preserving temporal distribution.

### ffmpeg Integration for Frame Capture

For every retained timestamp `t`, the engine constructs and executes an `ffmpeg` command at lines 160–175. The command seeks to the exact second (`-ss`), extracts a single video frame (`-frames:v 1`), and writes it as a JPEG file named `cue_*.jpg` (e.g., `cue_0000.jpg`, `cue_0001.jpg`).

### Merging Cue Frames into the Primary Set

After extraction, `merge_frames()` (lines 112–119) combines the timestamp-based frames with those generated by other detail engines (scene detection, keyframe analysis, or uniform sampling). This function preserves chronological order, re-indexes the combined list, and ensures cue frames are never dropped by subsequent sampling stages.

## Using the `--timestamps` Flag from the Command Line

Invoke the [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) entry point with the `--timestamps` argument to request specific frames from a video URL or local file. The skill downloads the video if necessary, processes your time cues, and includes the resulting frames in the final JSON payload.

```bash

# Assume $SKILL_DIR points to the skill directory

python3 "$SKILL_DIR/scripts/watch.py" "https://youtu.be/abc123" \
  --detail balanced \
  --timestamps 4:32,7:10,9:55

```

The execution flow performs four actions:
1. Downloads the video to a temporary cache if not already present.
2. Parses the three timestamps into seconds and sorts them.
3. Extracts JPEGs for each cue point, naming them `cue_0000.jpg`, `cue_0001.jpg`, and `cue_0002.jpg`.
4. Returns a JSON object where each frame dictionary contains `"reason": "transcript-cue"`.

## Programmatic Frame Extraction with Python

You can bypass the CLI and call the frame engine directly from Python code. This approach is useful when integrating timestamp extraction into larger workflows or when you need fine-grained control over output directories and resolution.

```python
from pathlib import Path
from skills.watch.scripts.frames import (
    parse_timestamps,
    extract_at_timestamps,
)

video_path = "/tmp/video.mp4"
out_dir = Path("/tmp/frames")

# Parse the timestamp string

timestamps = parse_timestamps("4:32,7:10,9:55")

# Extract frames at 512px resolution, keeping all cues

frames, meta = extract_at_timestamps(
    video_path,
    out_dir,
    timestamps,
    resolution=512,
    max_frames=None,  # Retain every requested timestamp

)

print(frames)  # List of dicts with path, timestamp_seconds, reason

print(meta)    # {'engine': 'timestamps', ...}

```

### Combining Cue Frames with Scene Detection

To ensure timestamp frames appear alongside automatically selected scene frames, use the `merge_frames()` utility:

```python
from skills.watch.scripts.frames import merge_frames

# scene_frames from extract_scene_or_uniform()

# cue_frames from extract_at_timestamps()

all_frames = merge_frames(scene_frames, cue_frames)

```

The merged list maintains chronological order and is the version rendered to users, guaranteeing that your explicitly requested timestamps are preserved even when scene-based sampling occurs.

## Key Implementation Details

**Time Format Flexibility.** The `parse_timestamps()` implementation handles standard time notation and converts to floating-point seconds, enabling sub-second precision if your input includes decimal values.

**Window Constraints.** When using `--start` or `--end` flags in conjunction with `--timestamps`, the `extract_at_timestamps()` function filters cues before any sampling occurs. This ensures you only extract frames within your specified analysis window.

**Even Sampling Fallback.** If you request more timestamps than `max_frames` allows, the `_even_indices` logic evenly distributes the selected cues across your time range rather than simply truncating the list.

**Documentation Reference.** The [`SKILL.md`](https://github.com/bradautomates/claude-video/blob/main/SKILL.md) file at lines 45–48 explicitly documents the `--timestamps` flag and its intended use as a transcript cue mechanism.

## Summary

- The `--timestamps` flag in `bradautomates/claude-video` enables extraction of exact frames at user-specified times via the [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) CLI.
- **`parse_timestamps()`** (lines 95–103) converts comma-separated time strings into sorted, deduplicated seconds.
- **`extract_at_timestamps()`** (lines 124–158) filters cues against `--start/--end` windows and applies even sampling if frame limits are exceeded.
- The engine invokes `ffmpeg` at lines 160–175 to generate `cue_*.jpg` files marked with `"reason": "transcript-cue"`.
- **`merge_frames()`** (lines 112–119) integrates cue frames with scene or keyframe selections while preserving chronological order.

## Frequently Asked Questions

### What timestamp formats does the `--timestamps` flag accept?

The `parse_timestamps()` function accepts comma-separated time strings in standard notation like `"4:32"` (minutes:seconds) or `"7:10"`. These are converted to floating-point seconds, allowing for precise positioning and optional sub-second decimal values.

### How does the engine handle timestamps outside the `--start` or `--end` range?

The `extract_at_timestamps()` function automatically filters out any timestamps that fall before the `--start` value or after the `--end` value before extraction begins. This ensures you only generate frames within your specified analysis window, preventing unnecessary `ffmpeg` invocations.

### Can I combine timestamp-based frames with scene detection?

Yes. Use the `merge_frames()` function (lines 112–119) to combine the list from `extract_at_timestamps()` with frames from `extract_scene_or_uniform()`. The merge preserves chronological order and guarantees that your explicitly requested cue frames are included in the final output.

### What file naming convention is used for timestamp frames?

The engine generates JPEG files named `cue_0000.jpg`, `cue_0001.jpg`, etc., corresponding to the sorted order of your input timestamps. Each frame dictionary in the output JSON includes `"reason": "transcript-cue"` to distinguish these from scene-selected or keyframe-selected frames.