From video-editing
Extract one or more time-range segments from a video. Use when the user says "cut from 1:30 to 3:45", "trim the first 30 seconds", "extract these segments", "split this clip at 5:00". Stream-copies losslessly by default; offers a frame-accurate re-encode mode when the cut must be exact. Multiple segments are written as separate files (or optionally stitched in one pass).
npx claudepluginhub danielrosehill/claude-code-plugins --plugin video-editingThis skill is limited to using the following tools:
Extract precise time ranges from a video. Replaces the legacy `cut-video-segment` command.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
Extract precise time ranges from a video. Replaces the legacy cut-video-segment command.
| Field | Default |
|---|---|
| Source | required |
| Segments | required: one or more start..end ranges (e.g. 00:01:30..00:03:45) or a JSON array [{start, end, label?}, ...] |
| Output dir | default: same dir as source (or <project>/exports/ when run inside a project) |
| Mode | copy (lossless, stream-copy) — precise (re-encode for frame-accurate cuts) |
| Stitch | no (one file per segment) — yes (concatenate all segments into a single output) |
SRC="$(realpath "$INPUT")"
DUR=$(ffprobe -v error -show_entries format=duration -of default=nw=1:nk=1 "$SRC")
to_seconds() {
awk -F: '{
n = NF
if (n == 3) print $1*3600 + $2*60 + $3
else if (n == 2) print $1*60 + $2
else print $1
}' <<<"$1"
}
For each segment: convert start/end to seconds; reject if start >= end, if start < 0, or if end > DUR. Report which segments were rejected and abort.
copy (default)Stream-copy each segment. Fast, lossless, but cuts land on the nearest keyframe (typically within 1–2s of the requested mark).
i=0
for seg in "${SEGMENTS[@]}"; do
read s e <<<"$seg"
OUT="$OUTDIR/$(basename "${SRC%.*}")_seg_$(printf '%02d' $i)${EXT}"
ffmpeg -y -ss "$s" -to "$e" -i "$SRC" -c copy -avoid_negative_ts make_zero "$OUT"
i=$((i+1))
done
-ss before -i enables fast seek; combined with -c copy this is the lossless path.
preciseFrame-accurate cuts via re-encode. -ss goes after -i to force decode-side seek.
ffmpeg -y -i "$SRC" -ss "$s" -to "$e" \
-c:v libx264 -crf 18 -preset medium \
-c:a aac -b:a 192k \
"$OUT"
If a render profile name was supplied (from render-profiles.json), build the encoder args from that profile instead.
If STITCH=yes:
LIST=$(mktemp)
for f in "${SEGMENT_OUTPUTS[@]}"; do printf "file '%s'\n" "$f" >> "$LIST"; done
ffmpeg -y -f concat -safe 0 -i "$LIST" -c copy "$OUTDIR/$(basename "${SRC%.*}")_stitched${EXT}"
If the segments were produced via precise mode they share encoder params and concat-copy works. For copy mode + stitch, fall back to a re-encode through render-from-library if stream-copy concat fails.
For each output:
ffprobe -v error -show_entries format=duration,size -of default=nw=1 "$OUT"
Compare actual duration to requested (end - start). In copy mode, mention the keyframe-snap drift if it's >0.5s.
Print a table of segment outputs with their durations and sizes. Offer follow-ups (burn-graphics to overlay a label on each, render-from-library to stitch in a richer way, audio-analysis per segment).
_seg_00, _seg_01, …); supply a label per segment in the JSON form to get human-readable names instead.00:00:00..-00:00:N (use ffprobe duration) before validation.merge-videos command's job), use render-from-library instead.add-watermark command's job), use burn-graphics instead.