Skill: ivangdavila/video (version 1.0.1)

--- name: Video slug: video version: 1.0.1 description: Process, edit, and optimize videos for any platform with compression, format conversion, captioning, and repurposing workflows. changelog: Declare required binaries (ffmpeg, ffprobe), add requirements section with optional deps, add explicit scope metadata: {"clawdbot":{"emoji":"🎬","requires":{"bins":["ffmpeg","ffprobe"]},"os":["linux","darwin","win32"]}} --- ## Requirements **Required:** - `ffmpeg` / `ffprobe` — core video processing **Optional:** - `whisper` — local transcription for captions - `realesrgan` — AI upscaling ## Quick Reference | Situation | Load | |-----------|------| | Platform specs (YouTube, TikTok, Instagram) | `platforms.md` | | FFmpeg commands by task | `commands.md` | | Quality/compression settings | `quality.md` | | Workflow by use case | `workflows.md` | ## Core Capabilities | Task | Method | |------|--------| | Convert/compress | FFmpeg (see `commands.md`) | | Generate captions | Whisper → SRT/VTT | | Change aspect ratio | Crop, pad, or smart reframe | | Clean audio | Normalize, denoise, enhance | | Batch operations | Process entire folders in one run | ## Execution Pattern 1. **Clarify target** — What platform? What format? File size limit? 2. **Check source** — `ffprobe` for codec, resolution, duration, audio 3. **Process** — FFmpeg for transformation 4. **Verify** — Confirm output meets specs before delivering 5. **Deliver** — Provide file to user ## Common Requests → Actions | User says | Agent does | |-----------|------------| | "Make this work for TikTok" | Reframe to 9:16, check duration ≤3min, compress | | "Add subtitles" | Whisper → SRT → burn-in or deliver separately | | "Compress for WhatsApp" | Target <64MB, H.264, AAC | | "Extract audio" | `-vn -acodec mp3` or `-acodec copy` | | "Make a GIF" | Extract frames, optimize palette, loop | | "Split into clips" | Cut at timestamps with `-ss` and `-t` | ## Quality Rules - **Always re-encode audio to AAC** for maximum compatibility - **Use `-movflags +faststart`** for web playback - **CRF 23** is good default for H.264 (lower = better, bigger) - **Check before delivering** — verify duration, file size, playability ## Platform Quick Reference | Platform | Aspect | Max Duration | Max Size | |----------|--------|--------------|----------| | TikTok | 9:16 | 3 min | 287MB | | Instagram Reels | 9:16 | 90s | 250MB | | YouTube Shorts | 9:16 | 60s | No limit | | YouTube | 16:9 | 12h | 256GB | | WhatsApp | Any | 3 min | 64MB | ## Scope This skill: - Processes video files user explicitly provides - Runs FFmpeg commands on user request - Does NOT access files without user instruction - Does NOT upload to external services automatically

path: commands.md
content: # FFmpeg Commands by Task

## Inspect Video
```bash
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
```

---

## Convert Format
```bash
# To MP4 (universal)
ffmpeg -i input.mov -c:v libx264 -c:a aac output.mp4

# Keep original quality (copy streams)
ffmpeg -i input.mkv -c copy output.mp4
```

---

## Compress
```bash
# Good quality, smaller file
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4

# Aggressive compression (WhatsApp)
ffmpeg -i input.mp4 -vf "scale=720:-2" -c:v libx264 -crf 28 -c:a aac -b:a 96k output.mp4

# Target specific file size (50MB)
ffmpeg -i input.mp4 -c:v libx264 -b:v 800k -c:a aac -b:a 96k output.mp4
```

---

## Change Aspect Ratio
```bash
# 16:9 → 9:16 (center crop)
ffmpeg -i input.mp4 -vf "crop=ih*9/16:ih" output.mp4

# 16:9 → 9:16 (letterbox with blur)
ffmpeg -i input.mp4 -vf "split[original][copy];[copy]scale=1080:1920,boxblur=20[bg];[bg][original]overlay=(W-w)/2:(H-h)/2" output.mp4

# 16:9 → 1:1 (square with padding)
ffmpeg -i input.mp4 -vf "scale=1080:1080:force_original_aspect_ratio=decrease,pad=1080:1080:(ow-iw)/2:(oh-ih)/2:black" output.mp4
```

---

## Trim/Cut
```bash
# Cut from 00:30 to 01:30
ffmpeg -i input.mp4 -ss 00:00:30 -to 00:01:30 -c copy output.mp4

# First 60 seconds
ffmpeg -i input.mp4 -t 60 -c copy output.mp4

# Remove first 10 seconds
ffmpeg -i input.mp4 -ss 10 -c copy output.mp4
```

---

## Merge Clips
```bash
# Create list file
echo "file 'clip1.mp4'" > list.txt
echo "file 'clip2.mp4'" >> list.txt
echo "file 'clip3.mp4'" >> list.txt

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

---

## Extract Audio
```bash
# To MP3
ffmpeg -i input.mp4 -vn -acodec libmp3lame -q:a 2 output.mp3

# To AAC (keep quality)
ffmpeg -i input.mp4 -vn -acodec copy output.aac
```

---

## Add/Remove Audio
```bash
# Remove audio
ffmpeg -i input.mp4 -an -c:v copy output.mp4

# Replace audio
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -map 0:v -map 1:a output.mp4
```

---

## Add Subtitles
```bash
# Burn into video
ffmpeg -i input.mp4 -vf "subtitles=captions.srt" output.mp4

# Styled subtitles
ffmpeg -i input.mp4 -vf "subtitles=captions.srt:force_style='FontSize=24,PrimaryColour=&HFFFFFF&'" output.mp4
```

---

## Create GIF
```bash
# Generate palette (better colors)
ffmpeg -i input.mp4 -vf "fps=10,scale=480:-1:flags=lanczos,palettegen" palette.png

# Create GIF with palette
ffmpeg -i input.mp4 -i palette.png -filter_complex "fps=10,scale=480:-1:flags=lanczos[x];[x][1:v]paletteuse" output.gif
```

---

## Extract Frames/Thumbnails
```bash
# One frame at specific time
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 thumbnail.jpg

# One frame per second
ffmpeg -i input.mp4 -vf "fps=1" frame_%04d.jpg

# Best quality frame extraction
ffmpeg -i input.mp4 -ss 00:00:05 -vframes 1 -q:v 2 thumbnail.jpg
```

---

## Stabilize
```bash
# Analyze
ffmpeg -i input.mp4 -vf vidstabdetect -f null -

# Apply stabilization
ffmpeg -i input.mp4 -vf vidstabtransform output.mp4
```

---

## Speed Change
```bash
# 2x speed
ffmpeg -i input.mp4 -vf "setpts=0.5*PTS" -af "atempo=2.0" output.mp4

# 0.5x speed (slow motion)
ffmpeg -i input.mp4 -vf "setpts=2*PTS" -af "atempo=0.5" output.mp4
```

---

## Rotate
```bash
# 90° clockwise
ffmpeg -i input.mp4 -vf "transpose=1" output.mp4

# 90° counter-clockwise
ffmpeg -i input.mp4 -vf "transpose=2" output.mp4

# 180°
ffmpeg -i input.mp4 -vf "transpose=1,transpose=1" output.mp4
```

---

## Add Watermark
```bash
# Bottom right corner
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=W-w-10:H-h-10" output.mp4

# With opacity
ffmpeg -i input.mp4 -i logo.png -filter_complex "[1:v]format=rgba,colorchannelmixer=aa=0.5[logo];[0:v][logo]overlay=W-w-10:H-h-10" output.mp4
```

---

## Resolution/Scale
```bash
# To 1080p (maintain aspect)
ffmpeg -i input.mp4 -vf "scale=1920:1080:force_original_aspect_ratio=decrease" output.mp4

# To 720p
ffmpeg -i input.mp4 -vf "scale=-2:720" output.mp4
```

---

## Audio Enhancement
```bash
# Normalize volume
ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" output.mp4

# Remove background noise (basic)
ffmpeg -i input.mp4 -af "highpass=f=200,lowpass=f=3000" output.mp4
```

---

## Frame Rate Conversion
```bash
# Change to 30fps
ffmpeg -i input.mp4 -r 30 -c:a copy output.mp4

# Change to 24fps (cinematic)
ffmpeg -i input.mp4 -r 24 -c:a copy output.mp4

# 60fps to 30fps (smoother)
ffmpeg -i input.mp4 -vf "fps=30" -c:a copy output.mp4
```

---

## Brightness/Contrast
```bash
# Increase brightness
ffmpeg -i input.mp4 -vf "eq=brightness=0.1" output.mp4

# Increase contrast
ffmpeg -i input.mp4 -vf "eq=contrast=1.2" output.mp4

# Both (dark video fix)
ffmpeg -i input.mp4 -vf "eq=brightness=0.1:contrast=1.2:saturation=1.1" output.mp4
```

---

## Add Text Overlay
```bash
# Simple text
ffmpeg -i input.mp4 -vf "drawtext=text='My Title':fontsize=48:fontcolor=white:x=(w-text_w)/2:y=50" output.mp4

# With background box
ffmpeg -i input.mp4 -vf "drawtext=text='Subscribe':fontsize=36:fontcolor=white:box=1:boxcolor=black@0.5:boxborderw=5:x=50:y=h-100" output.mp4

# Multi-line (use \n)
ffmpeg -i input.mp4 -vf "drawtext=text='Line 1\nLine 2':fontsize=32:fontcolor=white:x=50:y=50" output.mp4
```

---

## Blur/Censor Regions
```bash
# Blur specific area (x, y, width, height)
ffmpeg -i input.mp4 -vf "delogo=x=100:y=100:w=200:h=100:show=0" output.mp4

# Pixelate region
ffmpeg -i input.mp4 -vf "crop=200:100:100:100,scale=20:10,scale=200:100[blur];[0:v][blur]overlay=100:100" output.mp4

# Full face blur (requires face detection - use with external tool)
# For manual: identify face coordinates per scene, apply delogo or boxblur
```

---

## Create Audiogram (Waveform Visualization)
```bash
# Audio waveform video
ffmpeg -i audio.mp3 -filter_complex "[0:a]showwaves=s=1280x720:mode=line:rate=25:colors=white[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy audiogram.mp4

# Circular waveform
ffmpeg -i audio.mp3 -filter_complex "[0:a]avectorscope=s=1280x720:draw=dot:scale=cbrt[v]" -map "[v]" -map 0:a audiogram.mp4
```


path: platforms.md
content: # Platform Specifications

## YouTube

| Type | Aspect | Resolution | Max Duration | Max Size |
|------|--------|------------|--------------|----------|
| Standard | 16:9 | 1920x1080 (or 4K) | 12 hours | 256GB |
| Shorts | 9:16 | 1080x1920 | 60 seconds | 256GB |

**Recommended:** H.264, AAC, 30/60fps, `-movflags +faststart`

---

## TikTok

| Aspect | Resolution | Duration | Max Size |
|--------|------------|----------|----------|
| 9:16 | 1080x1920 | 3 min (web), 10 min (some) | 287MB (iOS), 500MB (web) |

**Recommended:** H.264, AAC, 30fps, bitrate 2-5 Mbps

---

## Instagram

| Type | Aspect | Resolution | Duration | Max Size |
|------|--------|------------|----------|----------|
| Reels | 9:16 | 1080x1920 | 90 seconds | 250MB |
| Feed | 1:1 or 4:5 | 1080x1080/1350 | 60 seconds | 250MB |
| Stories | 9:16 | 1080x1920 | 15 sec each | 250MB |

**Recommended:** H.264, AAC, 30fps

---

## LinkedIn

| Type | Aspect | Resolution | Duration | Max Size |
|------|--------|------------|----------|----------|
| Feed | 16:9, 1:1, 4:5 | 1080p | 10 minutes | 5GB |

**Recommended:** H.264, AAC, keep under 200MB for reliability

---

## Twitter/X

| Aspect | Resolution | Duration | Max Size |
|--------|------------|----------|----------|
| 16:9, 1:1 | 1280x720 min | 2:20 | 512MB |

**Recommended:** H.264, AAC, 40fps max

---

## WhatsApp

| Max Size | Notes |
|----------|-------|
| 64MB | Compress aggressively, H.264 baseline profile |

**Compression target:** CRF 28-32, 720p, AAC 128kbps

---

## Facebook

| Type | Aspect | Resolution | Duration | Max Size |
|------|--------|------------|----------|----------|
| Feed | 16:9, 1:1, 4:5, 9:16 | 1080p | 240 min | 10GB |
| Reels | 9:16 | 1080x1920 | 90 seconds | 4GB |

---

## Discord

| Max Size | Notes |
|----------|-------|
| 25MB free, 100MB Nitro | Compress heavily for free tier |

---

## Quick Platform Flags

```bash
# YouTube optimized
-c:v libx264 -preset slow -crf 18 -c:a aac -b:a 192k -movflags +faststart

# TikTok/Reels (9:16, compressed)
-vf "scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2" -c:v libx264 -crf 23 -c:a aac -b:a 128k

# WhatsApp (max compression)
-vf "scale=720:-2" -c:v libx264 -crf 28 -preset fast -c:a aac -b:a 96k
```


path: quality.md
content: # Video Quality Guide

## CRF (Constant Rate Factor) — H.264

| CRF | Quality | Use Case |
|-----|---------|----------|
| 18 | Visually lossless | Archive, master copies |
| 20 | Excellent | YouTube uploads |
| 23 | Good (default) | General purpose |
| 26 | Acceptable | Smaller files needed |
| 28 | Noticeable degradation | WhatsApp, aggressive compression |
| 30+ | Poor | Only if desperate for size |

**Rule:** Lower CRF = better quality, larger file

---

## Preset Speed vs Quality

| Preset | Encoding Speed | File Size | Quality |
|--------|---------------|-----------|---------|
| ultrafast | Fastest | Largest | Lowest |
| fast | Fast | Large | Lower |
| medium | Balanced | Medium | Medium |
| slow | Slow | Smaller | Higher |
| veryslow | Very slow | Smallest | Highest |

**Recommendation:** Use `slow` for final exports, `fast` for tests/drafts

---

## Audio Quality

| Bitrate | Quality | Use Case |
|---------|---------|----------|
| 64 kbps | Low | Voice only, heavy compression |
| 96 kbps | Acceptable | Mobile, small files |
| 128 kbps | Good | Standard distribution |
| 192 kbps | High | YouTube, podcasts |
| 256+ kbps | Excellent | Music, professional |

**Always use AAC** for maximum compatibility

---

## Resolution vs Bitrate Guidelines

| Resolution | Minimum Bitrate | Recommended |
|------------|-----------------|-------------|
| 720p | 1.5 Mbps | 3-5 Mbps |
| 1080p | 3 Mbps | 5-10 Mbps |
| 1440p (2K) | 6 Mbps | 10-15 Mbps |
| 2160p (4K) | 13 Mbps | 20-35 Mbps |

---

## File Size Estimation

Rough formula: `File Size (MB) ≈ (Video Bitrate + Audio Bitrate) × Duration (seconds) / 8 / 1000`

**Quick targets:**
- 60 sec × 5 Mbps ≈ 37 MB
- 60 sec × 2 Mbps ≈ 15 MB
- 60 sec × 1 Mbps ≈ 7.5 MB

---

## When to Use Two-Pass Encoding

Use for **target bitrate/file size** requirements:

```bash
# Pass 1 (analysis)
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -pass 1 -f null /dev/null

# Pass 2 (encode)
ffmpeg -i input.mp4 -c:v libx264 -b:v 1M -pass 2 output.mp4
```

**When:**
- Strict file size limits (WhatsApp, email)
- Broadcast/platform specs require exact bitrate

---

## Essential Flags

| Flag | Purpose |
|------|---------|
| `-movflags +faststart` | Web playback (move moov atom to start) |
| `-pix_fmt yuv420p` | Maximum compatibility |
| `-profile:v main` or `baseline` | Older device support |
| `-level 4.0` | Broad compatibility (up to 1080p) |

---

## Quality Checklist Before Delivery

- [ ] File plays in VLC and QuickTime
- [ ] Duration matches expected
- [ ] File size under platform limit
- [ ] Audio audible and synced
- [ ] No artifacts or corruption at start/end
- [ ] Correct aspect ratio displays

---

## Common Problems and Fixes

**File too large:**
- Increase CRF (23 → 26)
- Reduce resolution (1080p → 720p)
- Use two-pass with target bitrate

**Won't play on some devices:**
- Add `-pix_fmt yuv420p`
- Use `-profile:v baseline -level 3.0`

**Audio out of sync:**
- Re-encode both streams (don't copy)
- Use `-async 1` or `-af aresample=async=1`

**Playback starts slow:**
- Add `-movflags +faststart`


path: workflows.md
content: # Video Workflows by Use Case

## Content Creator (YouTube → Shorts/TikTok)

### Full Workflow
1. **Analyze** long-form video with ffprobe
2. **Identify** best moments (user provides timestamps OR analyze audio peaks)
3. **Extract** clips: `ffmpeg -ss START -t DURATION`
4. **Reframe** to 9:16 with smart crop or blur background
5. **Add captions** via Whisper → burn-in with styling
6. **Optimize** for platform (see `platforms.md`)
7. **Batch export** all clips in one operation

### Quick Commands
```bash
# Extract vertical clip with captions
ffmpeg -i long_video.mp4 -ss 00:05:30 -t 60 \
  -vf "crop=ih*9/16:ih,subtitles=captions.srt:force_style='FontSize=28'" \
  -c:v libx264 -crf 23 -c:a aac short.mp4
```

---

## Social Media Manager (Multi-Platform Distribution)

### Batch Process for All Platforms
1. Start with master video (highest quality, 16:9)
2. Export variants in parallel:
   - YouTube: Keep 16:9, add `-movflags +faststart`
   - Instagram Reels: 9:16 reframe, ≤90 sec, ≤250MB
   - LinkedIn: 16:9 or 1:1, ≤200MB recommended
   - TikTok: 9:16, ≤3 min, ≤287MB
3. Generate captions file once, apply to all
4. Add watermark to all versions

### Batch Script Pattern
```bash
for format in "youtube:1920:1080" "tiktok:1080:1920" "instagram:1080:1080"; do
  IFS=: read name w h <<< "$format"
  ffmpeg -i master.mp4 -vf "scale=$w:$h:force_original_aspect_ratio=decrease,pad=$w:$h:(ow-iw)/2:(oh-ih)/2" \
    -c:v libx264 -crf 23 output_$name.mp4
done
```

---

## Educator (Screen Recordings → Course Content)

### Processing Pipeline
1. **Capture** screen recording (OBS, QuickTime)
2. **Enhance audio**: Normalize, remove background noise
3. **Generate transcript**: Whisper → clean up → SRT
4. **Add chapters**: Split by topic or auto-detect silence gaps
5. **Optimize for LMS**: Check platform requirements (Udemy, Teachable)
6. **Compress for mobile**: 720p version for bandwidth-limited students

### Key Commands
```bash
# Normalize audio
ffmpeg -i lecture.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:v copy normalized.mp4

# Remove silence >2 seconds
# (Requires silenceremove filter or external tool)

# Split at chapter marks
ffmpeg -i lecture.mp4 -ss 00:00:00 -t 00:15:00 -c copy chapter1.mp4
```

---

## Marketer (Ad Variants)

### A/B Testing Workflow
1. Create master ad (30-60 sec)
2. Generate variants:
   - **Length**: 6s, 15s, 30s, 60s versions
   - **Hooks**: Different first 3 seconds
   - **CTAs**: Different end cards
3. Export for each platform with correct specs
4. Create GIFs for email campaigns

### Multi-Length Export
```bash
# Extract key durations
for dur in 6 15 30; do
  ffmpeg -i master_ad.mp4 -t $dur -c:v libx264 -crf 23 ad_${dur}s.mp4
done
```

---

## Personal Use (Quick Fixes)

### Compress for Sharing
```bash
# WhatsApp (under 64MB)
ffmpeg -i video.mp4 -vf "scale=720:-2" -c:v libx264 -crf 28 -c:a aac -b:a 96k whatsapp.mp4
```

### Fix Orientation
```bash
# If video plays sideways
ffmpeg -i wrong.mp4 -vf "transpose=1" fixed.mp4
```

### Trim Quickly
```bash
# Remove first 5 sec and last 10 sec
duration=$(ffprobe -v error -show_entries format=duration -of csv=p=0 input.mp4)
end=$(echo "$duration - 10" | bc)
ffmpeg -i input.mp4 -ss 5 -t $end -c copy trimmed.mp4
```

---

## Filmmaker (Professional Workflow)

### Proxy Workflow
1. Ingest raw footage
2. Generate proxies: `scale=1280:-2 -c:v libx264 -crf 23`
3. Edit with proxies
4. Conform to original for final export

### Batch LUT Application
```bash
# Apply LUT to all clips
for f in *.mp4; do
  ffmpeg -i "$f" -vf "lut3d=my_look.cube" -c:a copy "graded_$f"
done
```

### Upscale Archive Footage
```bash
# Using Real-ESRGAN (external tool)
realesrgan-ncnn-vulkan -i old_footage.mp4 -o upscaled.mp4 -s 2
```

---

## Captioning Workflow (Universal)

### Full Pipeline
```bash
# 1. Extract audio
ffmpeg -i video.mp4 -vn -acodec pcm_s16le -ar 16000 audio.wav

# 2. Transcribe with Whisper
whisper audio.wav --model medium --output_format srt

# 3. Burn subtitles into video
ffmpeg -i video.mp4 -vf "subtitles=audio.srt" captioned.mp4

# 4. Or deliver SRT separately for platform upload
```

### Styled Captions (TikTok/Reels style)
```bash
ffmpeg -i video.mp4 -vf "subtitles=captions.srt:force_style='FontName=Arial Bold,FontSize=32,PrimaryColour=&H00FFFFFF,OutlineColour=&H00000000,Outline=2,Alignment=2'" output.mp4
```


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)