# How --timestamps Extracts Specific Moments from Video in Claude-Video

> Learn how --timestamps in Claude-Video precisely extracts video moments using ffmpeg. Understand time string parsing and frame extraction for your dataset.

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

---

**The `--timestamps` flag parses time strings like `1:23` or `00:45` into exact seconds, extracts single frames at those absolute positions using ffmpeg, and merges these "cue" frames into the final dataset while reserving them against the global frame budget.**

The `bradautomates/claude-video` repository provides a `watch` skill that analyzes video content through selective frame extraction. When you need specific visual moments rather than scene-based sampling, the `--timestamps` CLI flag triggers a dedicated pipeline that operates alongside the standard extraction engine.

## Parsing Timestamp Inputs into Seconds

The workflow begins in [`skills/watch/scripts/watch.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/watch.py), where the CLI argument is converted into a list of floating-point seconds.

```python
cue_timestamps = parse_timestamps(args.timestamps)  # watch.py line 81

```

The heavy lifting occurs in [`skills/watch/scripts/frames.py`](https://github.com/bradautomates/claude-video/blob/main/skills/watch/scripts/frames.py) within the `parse_timestamps()` function (lines 295–310). This utility:

- Splits the comma-separated string and trims whitespace.
- Delegates each token to `parse_time()`, which supports **SS**, **MM:SS**, and **HH:MM:SS** formats.
- Returns a **sorted, de-duplicated** list of `float` values representing absolute seconds.

This ensures that input like `"2:15, 0:45, 1:30"` is normalized to `[45.0, 90.0, 135.0]` before any video processing begins.

## Extracting Frames at Absolute Timestamps

Once the video is available locally, [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) invokes `extract_at_timestamps()` (lines 78–88), passing the parsed seconds along with the active time window and resolution constraints.

```python
cue_frames, cue_meta = extract_at_timestamps(
    video_path,
    work / "frames",
    cue_timestamps,
    resolution=args.resolution,
    max_frames=max_frames,
    start_seconds=start_sec,
    end_seconds=end_sec,
)  # watch.py lines 78-88

```

Inside [`frames.py`](https://github.com/bradautomates/claude-video/blob/main/frames.py) (lines 324–389), this function performs three critical operations:

1. **Window Filtering**: It drops any timestamps outside the `[start, end]` range specified by `--start` or `--end`, recording them in `cue_meta['dropped_out_of_window']`.
2. **Cap-Aware Sampling**: If the request exceeds `--max-frames`, it **even-samples** the list while always preserving the first and last cues.
3. **Single-Frame Extraction**: For each valid timestamp, it executes an ffmpeg seek command (`-ss <t> -i … -frames:v 1`) and writes a JPEG prefixed with `cue_` (e.g., `cue_0000.jpg`).

The function returns metadata for each extracted frame and a summary dict indicating the engine type (`"timestamps"`), total counts, and any dropped points.

## Merging Cue Frames with Detail Frames

Cue frames are **reserved against the overall frame budget** to prevent the primary extraction logic from evicting them. After the standard frame extraction completes (whether scene-aware, keyframe, or uniform), [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) merges the two collections.

```python
if cue_frames:
    frames = merge_frames(frames, cue_frames)  # watch.py line 27

```

The `merge_frames()` utility concatenates both lists, re-indexes them chronologically, and ensures that transcript-driven cues appear in their correct temporal positions relative to the detail frames. This guarantees that a cue at `2:30` remains visually accessible even if the primary sampler would not have chosen that specific second.

## Command-Line Usage Examples

Grab three exact moments from a YouTube video using balanced detail mode:

```bash
python -m skills.watch.scripts.watch \
    "https://youtu.be/abc123" \
    --detail balanced \
    --timestamps "0:45,1:30,2:15"

```

Process a local file with a hard frame cap and custom resolution, mixing integer seconds and formatted times:

```bash
python -m skills.watch.scripts.watch \
    "/path/to/video.mp4" \
    --detail efficient \
    --resolution 1024 \
    --max-frames 30 \
    --timestamps "30,1:05,90"

```

In both cases, the output reports the **Cue frames** count (e.g., `- **Cue frames:** 3 …`), and the working directory contains `cue_0000.jpg`, `cue_0001.jpg`, and so on alongside the standard detail frames.

## Summary

- **`--timestamps`** accepts comma-separated time strings in `SS`, `MM:SS`, or `HH:MM:SS` format.
- The `parse_timestamps()` function in [`frames.py`](https://github.com/bradautomates/claude-video/blob/main/frames.py) normalizes inputs into a sorted, de-duplicated list of float seconds.
- `extract_at_timestamps()` filters cues to the active window, samples them evenly if caps are exceeded, and extracts single frames via ffmpeg seeks.
- Cue frames are merged via `merge_frames()` in [`watch.py`](https://github.com/bradautomates/claude-video/blob/main/watch.py) and are reserved against the global `--max-frames` budget.
- Timestamps reference the **absolute source timeline**, ensuring consistent visual moments regardless of any `--start` or `--end` trimming.

## Frequently Asked Questions

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

The parser supports raw seconds (`45`), minutes and seconds (`1:30`), and full clock time (`02:15:30`). All formats can be mixed in a single comma-separated string, and the resulting values are automatically sorted and deduplicated.

### Do timestamps respect the `--start` and `--end` window?

Timestamps are interpreted against the **source timeline**, not the trimmed window. If a timestamp falls outside the range defined by `--start` or `--end`, it is reported in `cue_meta['dropped_out_of_window']` and excluded from extraction, ensuring the absolute time reference remains consistent.

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

When the cue count exceeds the frame cap, `extract_at_timestamps()` performs even sampling across the requested times while always preserving the first and last timestamps. This guarantees representative coverage without exceeding the budget.

### How are cue frames different from regular detail frames?

Cue frames are extracted via direct ffmpeg seeks at absolute times and are prefixed with `cue_` in the output directory. Unlike detail frames—which may be selected by scene detection or uniform sampling—cues are **reserved** during the merge process, ensuring they cannot be displaced by the primary extraction algorithm.