Claudest convert-video

install
source · Clone the upstream repo
git clone https://github.com/gupsammy/Claudest
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/gupsammy/Claudest "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/claude-content/skills/convert-video" ~/.claude/skills/gupsammy-claudest-convert-video && rm -rf "$T"
manifest: plugins/claude-content/skills/convert-video/SKILL.md
source content

Video Convert

Identify the operation type first, then apply the matching pattern below. For multi-operation requests (e.g., trim + resize + convert), chain all filters in a single ffmpeg invocation — avoid intermediate files.

Process

  1. Identify the operation(s) from the user's request.
  2. Probe codec when converting formats; probe dimensions when resizing. Speed, rotation, flip, and frame extraction do not require probing.
  3. Construct the command using the appropriate pattern.
  4. Confirm with the user before running.
  5. Run and report output file path and size.

Operation Patterns

Format Conversion

Probe codec first — determines whether

-c copy
is safe:

ffprobe -v quiet -show_streams "$INPUT" | grep codec_name
# Remux: same codec, different container (e.g., H.264 MKV → MP4) — instant, lossless:
ffmpeg -i input.mkv -c copy output.mp4

# Re-encode: different codec required:
ffmpeg -i input.avi -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4

Trimming

# Fast trim without re-encoding (-ss before -i = container-level seek):
ffmpeg -ss 00:01:30 -to 00:03:45 -i "$INPUT" -c copy "$OUTPUT"

# Re-encoding trim (use when -c copy causes A/V sync issues near keyframes):
ffmpeg -ss 00:01:30 -to 00:03:45 -i "$INPUT" -c:v libx264 -crf 23 -c:a copy "$OUTPUT"

Always try

-c copy
first. Fall back to re-encoding only if the user reports sync issues or the cut must land on a non-keyframe boundary.

Speed Change

# 2x speed:
ffmpeg -i "$INPUT" -filter:v "setpts=0.5*PTS" -filter:a "atempo=2.0" "$OUTPUT"

# 0.5x slow-motion:
ffmpeg -i "$INPUT" -filter:v "setpts=2.0*PTS" -filter:a "atempo=0.5" "$OUTPUT"

setpts
factor =
1 / speed_multiplier
.
atempo
range is 0.5–2.0 — chain for higher multiples:
atempo=2.0,atempo=2.0
achieves 4x. For silent video, omit
-filter:a
entirely.

Resize / Scale

Probe dimensions first:

ffprobe -v quiet -show_streams "$INPUT" | grep -E "width|height"

# Scale to width, auto height (-2 ensures H.264-compatible even height):
ffmpeg -i "$INPUT" -vf "scale=1280:-2" -c:a copy "$OUTPUT"

# Fit within bounding box without upscaling:
ffmpeg -i "$INPUT" \
  -vf "scale='min(1280,iw)':'min(720,ih)':force_original_aspect_ratio=decrease,pad=ceil(iw/2)*2:ceil(ih/2)*2" \
  -c:a copy "$OUTPUT"

Rotation / Flip

# 90° clockwise:         ffmpeg -i "$INPUT" -vf "transpose=1" "$OUTPUT"
# 90° counter-clockwise: ffmpeg -i "$INPUT" -vf "transpose=2" "$OUTPUT"
# 180°:                  ffmpeg -i "$INPUT" -vf "transpose=1,transpose=1" "$OUTPUT"
# Horizontal flip:       ffmpeg -i "$INPUT" -vf "hflip" "$OUTPUT"
# Vertical flip:         ffmpeg -i "$INPUT" -vf "vflip" "$OUTPUT"

Frame Extraction

# Single frame at timestamp:
ffmpeg -ss 00:00:10 -i "$INPUT" -frames:v 1 -q:v 2 output.jpg

# One frame every N seconds:
ffmpeg -i "$INPUT" -vf "fps=1/$N" -q:v 2 frames/frame_%04d.jpg

-q:v 2
is near-maximum JPEG quality. Use
-q:v 1
for the highest quality setting.

Key Decisions

  • Never upscale — add
    force_original_aspect_ratio=decrease
    when fitting to a bounding box.
  • For multi-filter operations, chain with commas in a single
    -vf
    ; but
    -filter:v
    and
    -filter:a
    must remain separate flags.
  • Use
    -c:a copy
    in all re-encode operations unless the audio format itself needs to change.
  • If ffprobe reveals a
    rotate
    metadata tag on the stream, use
    -vf "transpose=..."
    to bake rotation into pixels —
    -c copy
    preserves the metadata flag without rotating the actual frame data, which confuses many players.