How --timestamps Extracts Specific Moments from Video in Claude-Video
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, where the CLI argument is converted into a list of floating-point seconds.
cue_timestamps = parse_timestamps(args.timestamps) # watch.py line 81
The heavy lifting occurs in 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
floatvalues 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 invokes extract_at_timestamps() (lines 78–88), passing the parsed seconds along with the active time window and resolution constraints.
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 (lines 324–389), this function performs three critical operations:
- Window Filtering: It drops any timestamps outside the
[start, end]range specified by--startor--end, recording them incue_meta['dropped_out_of_window']. - Cap-Aware Sampling: If the request exceeds
--max-frames, it even-samples the list while always preserving the first and last cues. - Single-Frame Extraction: For each valid timestamp, it executes an ffmpeg seek command (
-ss <t> -i … -frames:v 1) and writes a JPEG prefixed withcue_(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 merges the two collections.
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:
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:
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
--timestampsaccepts comma-separated time strings inSS,MM:SS, orHH:MM:SSformat.- The
parse_timestamps()function inframes.pynormalizes 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()inwatch.pyand are reserved against the global--max-framesbudget. - Timestamps reference the absolute source timeline, ensuring consistent visual moments regardless of any
--startor--endtrimming.
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.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →