mcpField
C
claude-video-edit

claude-video-edit

github.com/agricidanielCreative & media3145 installsUpdated 29w ago
Repository

About claude-video-edit

claude-video-edit is a skill that guides video editing operations with FFmpeg and related scripts. It covers common editing tasks, from trimming and transitions to color work, stabilization, and privacy blurring.

Key features

  1. 01Lossless and frame-accurate trimming
  2. 02Split and concatenate clips
  3. 03Change speed, crop, scale, and rotate
  4. 04Add overlays, text, and transitions
  5. 05Color correction and LUT grading
  6. 06Stabilization and privacy blur

Use cases

  1. 01Trim clips with or without re-encoding
  2. 02Create segments or combine video files
  3. 03Add a title, watermark, or picture-in-picture
  4. 04Blur a region or stabilize shaky footage

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/agricidaniel/claude-video --skill claude-video-edit

After installing, type/claude-video-editin Claude Code to confirm it loaded.

Details

From the project README

claude-video-edit — Video Editing Operations

Pre-Flight

Before every operation that writes a file:

  1. Run bash scripts/preflight.sh "$INPUT" "$OUTPUT"
  2. If it fails, stop and report the error to the user
  3. For encoding operations, run bash scripts/detect_gpu.sh to choose encoder

Operations

Trimming

Lossless trim (keyframe-aligned, instant, no re-encode):

ffmpeg -n -ss HH:MM:SS -i "$INPUT" -t DURATION -c copy "$OUTPUT"

Note: -ss BEFORE -i for fast seeking. Duration in seconds or HH:MM:SS.

Frame-accurate trim (re-encodes, precise to any frame):

ffmpeg -n -i "$INPUT" -ss HH:MM:SS -t DURATION -c:v libx264 -crf 20 -c:a aac "$OUTPUT"

Note: -ss AFTER -i for frame accuracy. Use when precision matters.

Remove first/last N seconds:

  • Remove first 10s: -ss 10 -c copy
  • Remove last 10s: get duration with ffprobe, then trim to duration - 10
Splitting

Split at specific time:

ffmpeg -n -i "$INPUT" -t 60 -c copy part1.mp4
ffmpeg -n -i "$INPUT" -ss 60 -c copy part2.mp4

Split into equal segments:

ffmpeg -n -i "$INPUT" -f segment -segment_time 300 -c copy -reset_timestamps 1 "segment_%03d.mp4"

Split at scene boundaries (load references/analyze.md for PySceneDetect):

scenedetect -i "$INPUT" detect-adaptive -t 3.0 split-video
Concatenation

Same codec (no re-encode):

printf "file '%s'\n" file1.mp4 file2.mp4 file3.mp4 > /tmp/concat_list.txt
ffmpeg -n -f concat -safe 0 -i /tmp/concat_list.txt -c copy "$OUTPUT"
rm /tmp/concat_list.txt

Different codecs (re-encodes):

ffmpeg -n -i file1.mp4 -i file2.mp4 -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1" "$OUTPUT"
Speed Changes

Speed up 2x (with audio pitch correction):

ffmpeg -n -i "$INPUT" -vf "setpts=0.5*PTS" -af "atempo=2.0" "$OUTPUT"

Slow down 0.5x:

ffmpeg -n -i "$INPUT" -vf "setpts=2.0*PTS" -af "atempo=0.5" "$OUTPUT"

Speed factors: For atempo, valid range is 0.5–100.0. For extreme changes, chain: atempo=2.0,atempo=2.0 = 4x.

Frame interpolation slow-motion (AI-generated intermediate frames):

ffmpeg -n -i "$INPUT" -vf "minterpolate=fps=60:mi_mode=mci:mc_mode=aobmc:vsbmc=1" "$OUTPUT"

Warning: Very slow (~0.05x realtime). Best for short clips.

Cropping, Scaling, Rotation

Crop (width:height:x:y):

ffmpeg -n -i "$INPUT" -vf "crop=640:480:100:50" "$OUTPUT"

Scale (keep aspect ratio, even dimensions):

ffmpeg -n -i "$INPUT" -vf "scale=1280:-2:flags=lanczos" "$OUTPUT"

Scale to exact size with padding (letterbox):

ffmpeg -n -i "$INPUT" -vf "scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2:black" "$OUTPUT"

Rotate 90° clockwise: -vf "transpose=1" Rotate 90° counter-clockwise: -vf "transpose=2" Rotate 180°: -vf "transpose=1,transpose=1" Arbitrary angle: -vf "rotate=PI/6:fillcolor=black" Flip horizontal: -vf "hflip" | Vertical: -vf "vflip"

Overlays and Watermarks

Image watermark (bottom-right with 10px margin):

ffmpeg -n -i "$INPUT" -i logo.png -filter_complex "overlay=W-w-10:H-h-10" "$OUTPUT"

Picture-in-picture (small video in corner):

ffmpeg -n -i "$INPUT" -i pip.mp4 -filter_complex "[1:v]scale=320:180[pip];[0:v][pip]overlay=10:10" "$OUTPUT"

Text overlay:

ffmpeg -n -i "$INPUT" -vf "drawtext=text='My Title':fontsize=48:fontcolor=white:x=(w-tw)/2:y=50:fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:box=1:[email protected]:boxborderw=8" "$OUTPUT"

Timed text (show between 5s and 15s):

-vf "drawtext=text='Hello':enable='between(t,5,15)':fontsize=36:fontcolor=white:x=10:y=10"
Green Screen (Chromakey)
ffmpeg -n -i greenscreen.mp4 -i background.mp4 -filter_complex \
  "[0:v]chromakey=0x00FF00:0.1:0.2[fg];[1:v][fg]overlay" "$OUTPUT"

Adjust color hex, similarity (0.1), and blend (0.2) for best results.

Video Stabilization

Two-pass process using vidstab:

# Pass 1: Analyze motion
ffmpeg -i "$INPUT" -vf vidstabdetect=shakiness=5:accuracy=15:result=/tmp/transforms.trf -f null -

# Pass 2: Apply stabilization + sharpening
ffmpeg -n -i "$INPUT" -vf "vidstabtransform=smoothing=10:input=/tmp/transforms.trf,unsharp=5:5:0.8:5:5:0.3" "$OUTPUT"

rm /tmp/transforms.trf

shakiness 1-10 (how shaky is source), smoothing (higher = smoother camera, may crop edges).

Transitions

Cross-fade between two clips (44+ transition types available):

ffmpeg -n -i first.mp4 -i second.mp4 -filter_complex \
  "xfade=transition=fade:duration=2:offset=5" "$OUTPUT"

Available xfade transitions: fade, dissolve, wipeleft, wiperight, wipeup, wipedown, slideleft, slideright, slideup, slidedown, circlecrop, rectcrop, distance, fadeblack, fadewhite, radial, smoothleft, smoothright, smoothup, smoothdown, circleopen, circleclose, vertopen, vertclose, horzopen, horzclose, diagtl, diagtr, diagbl, diagbr, hlslice, hrslice, vuslice, vdslice, pixelize, squeezeh, squeezev, zoomin, fadegrays, wipetl, wipetr, wipebl, wipebr, coverleft, coverright, coverup, coverdown, revealleft, revealright, revealup, revealdown.

Fade in/out:

# Fade in first 2 seconds
ffmpeg -n -i "$INPUT" -vf "fade=t=in:st=0:d=2" -af "afade=t=in:st=0:d=2" "$OUTPUT"

# Fade out last 2 seconds (get duration first with ffprobe)
ffmpeg -n -i "$INPUT" -vf "fade=t=out:st=OFFSET:d=2" -af "afade=t=out:st=OFFSET:d=2" "$OUTPUT"
Color Correction

Load references/filters.md for the full filter catalog. Quick reference:

  • Brightness/contrast: -vf "eq=brightness=0.06:contrast=1.2:saturation=1.3"
  • Tone curves preset: -vf "curves=preset=lighter" (also: darker, increase_contrast, vintage, etc.)
  • Color balance: -vf "colorbalance=rs=0.3:gs=-0.1:bs=0.0"
  • 3D LUT: -vf "lut3d=file=my_lut.cube"
  • Grayscale: -vf "colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3"
  • Blur: -vf "gblur=sigma=10"
  • Sharpen: -vf "unsharp=5:5:1.0:5:5:0.0"
  • Denoise: -vf "hqdn3d=4:3:6:4.5" (fast) or -vf "nlmeans=s=3.5:p=7:r=15" (best quality)
Contact Sheet / Thumbnail Grid
ffmpeg -n -i "$INPUT" -vf "select=not(mod(n\,100)),scale=320:180,tile=4x4" -frames:v 1 contact_sheet.png
Extract Single Frame
ffmpeg -n -ss 00:01:30 -i "$INPUT" -frames:v 1 -q:v 2 thumbnail.jpg
Privacy Blur (Face/Region Censoring)

Blur entire face region (static coordinates — use ffprobe or MediaPipe to find face bounding box):

ffmpeg -n -i "$INPUT" -vf "delogo=x=200:y=100:w=150:h=150" "$OUTPUT"

Box blur a region (more control):

ffmpeg -n -i "$INPUT" -filter_complex \
  "[0:v]crop=150:150:200:100,boxblur=10[blur];[0:v][blur]overlay=200:100" "$OUTPUT"

Blur with time range (only blur between 5s and 15s):

ffmpeg -n -i "$INPUT" -filter_complex \
  "[0:v]split[main][copy];[copy]crop=150:150:200:100,boxblur=10[blur];[main][blur]overlay=200:100:enable='between(t,5,15)'" "$OUTPUT"

Full-frame blur (for B-roll background):

ffmpeg -n -i "$INPUT" -vf "boxblur=20:5" "$OUTPUT"

For AI-powered face detection + tracking blur across frames, use python3 scripts/face_tracker.py with MediaPipe BlazeFace (CPU, no VRAM needed). The face_tracker outputs bounding boxes per frame that can drive the overlay blur coordinates.

LUT Color Grading

Apply a .cube LUT file:

ffmpeg -n -i "$INPUT" -vf "lut3d=file=my_grade.cube" "$OUTPUT"

Apply with intensity control (blend between original and graded):

ffmpeg -n -i "$INPUT" -filter_complex \
  "[0:v]split[a][b];[b]lut3d=file=my_grade.cube[graded];[a][graded]blend=all_mode=normal:all_opacity=0.7" "$OUTPUT"

Common LUT sources: Download .cube files from sites like lutify.me, filtergrade.com, or create custom LUTs in DaVinci Resolve. Place LUT files alongside the project or use absolute paths.

Supported formats: .cube (most common), .3dl, .dat, .m3d

Motion Tracking Text Overlay

Static text that follows a position (manual keyframes):

ffmpeg -n -i "$INPUT" -vf "drawtext=text='Label':fontsize=24:fontcolor=white:\
x='if(lt(t,5),100+t*20,200)':y='if(lt(t,5),50+t*10,100)':\
fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf:\
box=1:[email protected]:boxborderw=4" "$OUTPUT"

Text with expression-based movement (smooth sine wave):

ffmpeg -n -i "$INPUT" -vf "drawtext=text='Moving Text':fontsize=36:fontcolor=white:\
x='w/2-tw/2+50*sin(t*2)':y='h/2-th/2+30*cos(t*2)':\
fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" "$OUTPUT"

For complex tracking (follow a face or object through a video), combine scripts/face_tracker.py bounding box output with per-frame drawtext coordinates. Export face centers from the tracker, then generate a drawtext filter with frame-by-frame x/y expressions.

Output Naming Convention

When user doesn't specify output name, derive it from input:

  • video.mp4 → video_trimmed.mp4, video_stabilized.mp4, video_2x.mp4, etc.
  • For batch: video_001.mp4, video_002.mp4, etc.

Comments

Markdown supported