video-processing-editing

FFmpeg automation for cutting, trimming, concatenating, and exporting videos with audio mixing and platform optimization. Supports cutting, trimming, concatenation, transitions, effects, and color grading through FFmpeg CLI automation Handles audio mixing, normalization, and synchronization; subtitle burning and soft-subtitle handling Provides platform-specific export presets for YouTube, Instagram, Twitter, TikTok, and web delivery with bitrate and resolution optimization Batch processing and parallel job execution for large-scale video production pipelines Not suitable for real-time editing UIs, 3D compositing, or motion graphics work

INSTALLATION
npx skills add https://github.com/erichowens/some_claude_skills --skill video-processing-editing
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Video Processing & Editing

Expert in FFmpeg-based video editing, processing automation, and export optimization for modern content creation workflows.

When to Use

Use for:

  • Automated video editing pipelines (script-to-video)
  • Cutting, trimming, concatenating clips
  • Adding transitions, effects, overlays
  • Audio mixing and normalization
  • Subtitle/caption handling
  • Export optimization for platforms
  • Batch video processing
  • Color grading and correction

NOT for:

  • Real-time video editing UI (use DaVinci Resolve/Premiere)
  • 3D compositing (use After Effects/Blender)
  • Motion graphics animation (use After Effects)
  • Basic screen recording (use OBS)

Technology Selection

Video Editing Tools

Tool

Speed

Features

Use Case

FFmpeg

Very Fast

CLI automation

Production pipelines

MoviePy

Medium

Python API

Programmatic editing

PyAV

Fast

Low-level control

Custom processing

DaVinci Resolve

Slow

Full NLE

Manual editing

Decision tree:

Need automation? → FFmpeg

Need Python API? → MoviePy

Need frame-level control? → PyAV

Need manual editing? → DaVinci Resolve

Common Anti-Patterns

Anti-Pattern 1: Not Using Keyframe-Aligned Cuts

Novice thinking: "Just cut the video at any timestamp"

Problem: Causes artifacts, black frames, and playback issues.

Wrong approach:

# ❌ Cut at arbitrary timestamp (not keyframe-aligned)

ffmpeg -i input.mp4 -ss 00:01:23.456 -to 00:02:45.678 -c copy output.mp4

# Result: Black frames, artifacts, sync issues

Why wrong:

  • Video codecs use keyframes (I-frames) every 2-10 seconds
  • Non-keyframe cuts require re-encoding
  • Using -c copy (stream copy) without keyframe alignment breaks playback
  • GOP (Group of Pictures) structure depends on keyframes

Correct approach 1: Re-encode for precise cuts

# ✅ Re-encode for frame-accurate cutting

ffmpeg -i input.mp4 -ss 00:01:23.456 -to 00:02:45.678 \

  -c:v libx264 -crf 18 -preset medium \

  -c:a aac -b:a 192k \

  output.mp4

# Frame-accurate, but slower (re-encoding)

Correct approach 2: Keyframe-aligned stream copy

# ✅ Fast cutting with keyframe alignment

# Step 1: Find keyframes near cut points

ffprobe -select_streams v -show_frames -show_entries frame=pkt_pts_time,key_frame \

  -of csv input.mp4 | grep ",1$" | awk -F',' '{print $2}'

# Step 2: Cut at nearest keyframes (fast, no re-encoding)

ffmpeg -i input.mp4 -ss 00:01:22.000 -to 00:02:46.000 -c copy output.mp4

# Blazing fast, no quality loss, but not frame-accurate

Correct approach 3: Two-pass for best of both worlds

# ✅ Fast seek + precise cut

ffmpeg -ss 00:01:20.000 -i input.mp4 \

  -ss 00:00:03.456 -to 00:01:25.678 \

  -c:v libx264 -crf 18 -preset medium \

  -c:a aac -b:a 192k \

  output.mp4

# -ss BEFORE -i: Fast seek to keyframe (no decode)

# -ss AFTER -i: Precise trim (only decode needed portion)

Performance comparison:

Method

Time (1-hour video)

Accuracy

Quality

Stream copy (arbitrary)

2s

❌ Broken

❌ Artifacts

Stream copy (keyframe)

2s

±2s

✅ Perfect

Re-encode (simple)

15min

✅ Frame

⚠️ Quality loss

Two-pass (optimal)

3min

✅ Frame

✅ Perfect

Timeline context:

  • 2010: FFmpeg required full re-encoding for cuts
  • 2015: -c copy added for stream copying
  • 2020: Two-pass cutting became best practice
  • 2024: Hardware acceleration (NVENC) makes re-encoding viable

Anti-Pattern 2: Re-encoding Unnecessarily

Novice thinking: "Apply all edits in one FFmpeg command"

Problem: Multiple re-encodings cause cumulative quality loss.

Wrong approach:

# ❌ Re-encode for each operation (quality degradation)

# Operation 1: Trim

ffmpeg -i input.mp4 -ss 00:01:00 -to 00:05:00 \

  -c:v libx264 -crf 23 temp1.mp4

# Operation 2: Add audio

ffmpeg -i temp1.mp4 -i audio.mp3 -c:v libx264 -crf 23 \

  -map 0:v -map 1:a temp2.mp4

# Operation 3: Add subtitles

ffmpeg -i temp2.mp4 -vf subtitles=subs.srt \

  -c:v libx264 -crf 23 output.mp4

# Result: 3x re-encoding = significant quality loss

Why wrong:

  • Each re-encode is lossy (even with high CRF)
  • Cumulative quality loss (generation loss)
  • 3x encoding time
  • Wasted disk I/O

Correct approach 1: Chain operations in single command

# ✅ Single-pass encoding with all operations

ffmpeg -ss 00:01:00 -i input.mp4 -i audio.mp3 \

  -to 00:04:00 \

  -vf "subtitles=subs.srt" \

  -map 0:v -map 1:a \

  -c:v libx264 -crf 18 -preset medium \

  -c:a aac -b:a 192k \

  output.mp4

# Single re-encode, all operations applied at once

Correct approach 2: Use stream copy when possible

# ✅ Lossless operations with stream copy

# Trim (stream copy)

ffmpeg -i input.mp4 -ss 00:01:00 -to 00:05:00 -c copy temp.mp4

# Add audio (stream copy video, encode audio)

ffmpeg -i temp.mp4 -i audio.mp3 \

  -map 0:v -map 1:a \

  -c:v copy -c:a aac -b:a 192k \

  temp2.mp4

# Burn subtitles (must re-encode video)

ffmpeg -i temp2.mp4 -vf subtitles=subs.srt \

  -c:v libx264 -crf 18 -preset medium \

  -c:a copy \

  output.mp4

# Only 1 video re-encode (for subtitles)

Quality comparison:

Method

Encoding Passes

Quality (VMAF)

Time

3x re-encode (CRF 23)

3

82/100

45min

Single pass (CRF 23)

1

91/100

15min

Stream copy + 1 encode

1

95/100

18min

All stream copy

0

100/100

30s

Anti-Pattern 3: Ignoring Color Space Conversions

Novice thinking: "Just concatenate videos together"

Problem: Color shifts, mismatched brightness, broken playback.

Wrong approach:

# ❌ Concatenate videos with different color spaces

# clip1.mp4: BT.709 (HD), yuv420p

# clip2.mp4: BT.601 (SD), yuvj420p (full range)

# clip3.mp4: BT.2020 (HDR), yuv420p10le

# Create concat list

echo "file 'clip1.mp4'" > list.txt

echo "file 'clip2.mp4'" >> list.txt

echo "file 'clip3.mp4'" >> list.txt

# Concatenate without color normalization

ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

# Result: Color shifts between clips, broken HDR metadata

Why wrong:

  • Different color spaces (BT.601 vs BT.709 vs BT.2020)
  • Different pixel formats (yuv420p vs yuvj420p)
  • Different color ranges (limited vs full)
  • Metadata conflicts

Correct approach:

# ✅ Normalize color space before concatenation

# Step 1: Analyze color space of each clip

ffprobe -v error -select_streams v:0 \

  -show_entries stream=color_space,color_transfer,color_primaries,pix_fmt \

  -of default=noprint_wrappers=1 clip1.mp4

# Step 2: Normalize all clips to common color space

# Target: BT.709 (HD), yuv420p, limited range

# Normalize clip1 (already BT.709)

ffmpeg -i clip1.mp4 -c copy clip1_normalized.mp4

# Normalize clip2 (BT.601 SD → BT.709 HD)

ffmpeg -i clip2.mp4 \

  -vf "scale=in_range=full:out_range=limited,colorspace=bt709:iall=bt601:fast=1" \

  -color_primaries bt709 \

  -color_trc bt709 \

  -colorspace bt709 \

  -c:v libx264 -crf 18 -preset medium \

  -c:a copy \

  clip2_normalized.mp4

# Normalize clip3 (BT.2020 HDR → BT.709 SDR)

ffmpeg -i clip3.mp4 \

  -vf "zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=limited,format=yuv420p" \

  -color_primaries bt709 \

  -color_trc bt709 \

  -colorspace bt709 \

  -c:v libx264 -crf 18 -preset medium \

  -c:a copy \

  clip3_normalized.mp4

# Step 3: Concatenate normalized clips

echo "file 'clip1_normalized.mp4'" > list.txt

echo "file 'clip2_normalized.mp4'" >> list.txt

echo "file 'clip3_normalized.mp4'" >> list.txt

ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4

Color space guide:

Standard

Color Space

Transfer

Primaries

Use Case

BT.601

SD

bt470bg

bt470bg

Old SD content

BT.709

HD

bt709

bt709

Modern HD/FHD

BT.2020

UHD/HDR

smpte2084

bt2020

4K HDR

sRGB

Web

iec61966-2-1

bt709

Web delivery

Anti-Pattern 4: Poor Audio Sync

Novice thinking: "Video and audio are separate, just overlay them"

Problem: Lip sync issues, audio drift, broken playback.

Wrong approach:

# ❌ Replace audio without sync consideration

ffmpeg -i video.mp4 -i audio.mp3 \

  -map 0:v -map 1:a \

  -c:v copy -c:a copy \

  output.mp4

# Problems:

# - Audio duration ≠ video duration

# - No audio stretching/compression

# - Drift over time

Why wrong:

  • Audio and video have different durations
  • No timebase synchronization
  • No drift correction
  • Ignores original audio sync

Correct approach 1: Stretch/compress audio to match video

# ✅ Adjust audio speed to match video duration

# Get durations

VIDEO_DUR=$(ffprobe -v error -show_entries format=duration \

  -of default=noprint_wrappers=1:nokey=1 video.mp4)

AUDIO_DUR=$(ffprobe -v error -show_entries format=duration \

  -of default=noprint_wrappers=1:nokey=1 audio.mp3)

# Calculate speed ratio

RATIO=$(echo "$VIDEO_DUR / $AUDIO_DUR" | bc -l)

# Stretch audio to match video (with pitch correction)

ffmpeg -i video.mp4 -i audio.mp3 \

  -filter_complex "[1:a]atempo=${RATIO}[a]" \

  -map 0:v -map "[a]" \

  -c:v copy -c:a aac -b:a 192k \

  output.mp4

Correct approach 2: Precise offset and trim

# ✅ Sync audio with offset and trim

# Audio starts 0.5s late, trim to match video

ffmpeg -i video.mp4 -itsoffset 0.5 -i audio.mp3 \

  -map 0:v -map 1:a \

  -shortest \

  -c:v copy -c:a aac -b:a 192k \

  output.mp4

# -itsoffset: Delay audio by 0.5s

# -shortest: Trim to shortest stream

Correct approach 3: Mix multiple audio tracks with sync

# ✅ Mix dialogue, music, effects with precise timing

ffmpeg -i video.mp4 -i dialogue.wav -i music.mp3 -i sfx.wav \

  -filter_complex "

    [1:a]adelay=0|0[dlg];

    [2:a]volume=0.3,adelay=500|500[mus];

    [3:a]adelay=1200|1200[sfx];

    [dlg][mus][sfx]amix=inputs=3:duration=first[a]

  " \

  -map 0:v -map "[a]" \

  -c:v copy -c:a aac -b:a 256k \

  output.mp4

# adelay: Precise millisecond timing

# amix: Mix multiple audio streams

# volume: Normalize levels

Audio sync checklist:

□ Verify video and audio durations match

□ Use -shortest to prevent excess audio

□ Apply adelay for precise timing offsets

□ Use atempo for speed adjustment (maintains pitch)

□ Set audio bitrate appropriately (128k-256k)

□ Test lip sync at beginning, middle, end

Anti-Pattern 5: Wrong Codec/Bitrate for Platform

Novice thinking: "One export settings for everything"

Problem: Wasted bandwidth, poor quality, rejected uploads, compatibility issues.

Wrong approach:

# ❌ Export everything at 4K 50 Mbps

ffmpeg -i input.mp4 \

  -c:v libx264 -b:v 50M -s 3840x2160 \

  -c:a aac -b:a 320k \

  output.mp4

# For Instagram story: 2 GB file, rejected (max 100 MB)

# For YouTube: Could use 10 Mbps and look identical

# For Twitter: Exceeds bitrate limits

Why wrong:

  • Platform-specific size/bitrate limits
  • Over-encoding wastes bandwidth
  • Wrong resolution for platform
  • Incompatible codecs

Correct approach: Platform-optimized exports

YouTube (recommended settings):

# ✅ YouTube 1080p upload

ffmpeg -i input.mp4 \

  -c:v libx264 -preset slow -crf 18 \

  -s 1920x1080 -r 30 \

  -pix_fmt yuv420p \

  -color_primaries bt709 -color_trc bt709 -colorspace bt709 \

  -movflags +faststart \

  -c:a aac -b:a 192k -ar 48000 \

  youtube_1080p.mp4

# YouTube 4K upload

ffmpeg -i input.mp4 \

  -c:v libx264 -preset slow -crf 18 \

  -s 3840x2160 -r 60 \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 256k -ar 48000 \

  youtube_4k.mp4

Instagram (Stories, Reels, Feed):

# ✅ Instagram Story (9:16, max 100 MB, 15s)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1080x1920 -r 30 -t 15 \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 128k \

  instagram_story.mp4

# ✅ Instagram Reel (9:16, max 90s)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1080x1920 -r 30 -t 90 \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 128k \

  instagram_reel.mp4

# ✅ Instagram Feed (1:1 or 4:5)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1080x1080 -r 30 \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 128k \

  instagram_feed.mp4

Twitter/X:

# ✅ Twitter video (max 512 MB, 2:20)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1280x720 -r 30 -t 140 \

  -maxrate 5000k -bufsize 10000k \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 128k \

  twitter.mp4

TikTok:

# ✅ TikTok (9:16, max 287 MB, 10 min)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1080x1920 -r 30 -t 600 \

  -pix_fmt yuv420p \

  -movflags +faststart \

  -c:a aac -b:a 128k \

  tiktok.mp4

Web (HTML5 video):

# ✅ Web optimized (fast load, broad compatibility)

ffmpeg -i input.mp4 \

  -c:v libx264 -preset medium -crf 23 \

  -s 1920x1080 -r 30 \

  -pix_fmt yuv420p \

  -profile:v baseline -level 3.0 \

  -movflags +faststart \

  -c:a aac -b:a 128k -ar 48000 \

  web.mp4

Platform specs table:

Platform

Max Size

Max Duration

Resolution

FPS

Bitrate

Codec

YouTube

Unlimited

Unlimited

8K

60

Auto

H.264/VP9

Instagram Story

100 MB

15s

1080x1920

30

~5 Mbps

H.264

Instagram Reel

1 GB

90s

1080x1920

30

~8 Mbps

H.264

Twitter

512 MB

2:20

1920x1080

60

5 Mbps

H.264

TikTok

287 MB

10min

1080x1920

30

~4 Mbps

H.264

LinkedIn

5 GB

10min

1920x1080

30

5 Mbps

H.264

Web

Varies

Varies

1920x1080

30

2-5 Mbps

H.264

Export optimization checklist:

□ Use -movflags +faststart for web (progressive download)

□ Use -pix_fmt yuv420p for broad compatibility

□ Set -r 30 for most platforms (avoid variable framerate)

□ Use -preset slow for final exports (better quality)

□ Use -preset ultrafast for drafts

□ Apply -maxrate and -bufsize for streaming

□ Test playback on target platform before bulk export

Production Checklist

□ Align cuts to keyframes (or two-pass seek)

□ Chain operations in single FFmpeg command

□ Normalize color spaces before concatenating

□ Verify audio/video sync (test at multiple points)

□ Use platform-specific export presets

□ Apply -movflags +faststart for web delivery

□ Set proper color metadata (bt709 for HD)

□ Test output file on target platform

□ Keep lossless intermediate files (ProRes, FFV1)

□ Use hardware acceleration for batch jobs (NVENC, VideoToolbox)

When to Use vs Avoid

Scenario

Appropriate?

Automated video pipeline (script → video)

✅ Yes - FFmpeg automation

Batch process 100 videos

✅ Yes - parallel FFmpeg jobs

Trim/cut clips programmatically

✅ Yes - precise cutting

Add subtitles to videos

✅ Yes - burn or soft subs

Color grade footage

⚠️ Limited - basic only

Multi-cam editing

❌ No - use DaVinci Resolve

Motion graphics

❌ No - use After Effects

Real-time preview editing

❌ No - use Premiere/Resolve

References

  • /references/ffmpeg-guide.md - Complete FFmpeg command reference
  • /references/timeline-editing.md - Timeline concepts, multi-track editing
  • /references/export-optimization.md - Platform-specific export settings

Scripts

  • scripts/video_editor.py - Cut, trim, concatenate, transitions, effects
  • scripts/batch_processor.py - Parallel batch video processing

This skill guides: Video editing | FFmpeg | Timeline editing | Transitions | Export optimization | Audio mixing | Color grading | Automated video production

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card