video-processing-editing について
動画制作者や自動化ワークフロー向けの、FFmpegを中心とする動画処理スキルです。キーフレームを考慮したカット、再エンコードの抑制、配信先に合わせた出力設定を扱います。
主な機能
- 01動画のカット、結合、バッチ処理
- 02エフェクト、トランジション、オーバーレイの追加
- 03音声のミックス、同期、正規化
- 04字幕処理と色補正
- 05配信先に合わせた書き出し最適化
活用シーン
- 01スクリプトから動画を作る処理の自動化
- 02クリップの正確なカットや結合
- 03ソーシャルプラットフォーム向け動画の一括書き出し
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill video-processing-editingインストール後、Claude Code で/video-processing-editingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.claude-plugin/plugin.jsondemo/index.htmlreferences/export-optimization.mdffmpeg-guide.mdtimeline-editing.mdscripts/quality_assessment.pymotion_graphics.pybatch_processor.pyaudio_mixer.pythumbnail_generator.pytimelapse_creator.pyvideo_editor.py詳細
動画処理と編集
最新のコンテンツ制作ワークフローに向けた、FFmpeg ベースの動画編集、処理の自動化、書き出しの最適化に精通しています。
使用するタイミング
✅ 次の場合に使用します:
- 動画編集パイプラインの自動化(スクリプトから動画を作成)
- クリップのカット、トリミング、結合
- トランジション、エフェクト、オーバーレイの追加
- オーディオのミキシングとノーマライズ
- 字幕・キャプションの処理
- プラットフォーム向けの書き出し最適化
- 動画の一括処理
- カラーグレーディングと色補正
❌ 次の場合には使用しません:
- リアルタイムの動画編集 UI(DaVinci Resolve/Premiere を使用)
- 3D コンポジット(After Effects/Blender を使用)
- モーショングラフィックスアニメーション(After Effects を使用)
- 基本的な画面録画(OBS を使用)
技術の選択
動画編集ツール
| ツール | 速度 | 機能 | 用途 |
|---|---|---|---|
| FFmpeg | 非常に高速 | CLI による自動化 | 本番環境のパイプライン |
| MoviePy | 中程度 | Python API | プログラムによる編集 |
| PyAV | 高速 | 低レベル制御 | カスタム処理 |
| DaVinci Resolve | 低速 | フル機能の NLE | 手動編集 |
判断フロー:
Need automation? → FFmpeg
Need Python API? → MoviePy
Need frame-level control? → PyAV
Need manual editing? → DaVinci Resolve
よくあるアンチパターン
アンチパターン 1:キーフレームに合わせてカットしない
初心者の考え:「動画は任意のタイムスタンプでカットすればよい」
問題:アーティファクト、黒いフレーム、再生の問題が発生します。
誤った方法:
# ❌ 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
誤りの理由:
- 動画コーデックは 2~10 秒ごとにキーフレーム(I フレーム)を使用します
- キーフレーム以外でカットする場合は再エンコードが必要です
- キーフレームに合わせずに
-c copy(ストリームコピー)を使用すると、再生に問題が生じます - GOP(Group of Pictures)構造はキーフレームに依存します
正しい方法 1:正確にカットするために再エンコードする
# ✅ 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)
正しい方法 2:キーフレームに合わせてストリームコピーする
# ✅ 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
正しい方法 3:両方の利点を活かす 2 パス方式
# ✅ 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)
パフォーマンスの比較:
| 方法 | 所要時間(1 時間の動画) | 精度 | 品質 |
|---|---|---|---|
| ストリームコピー(任意の位置) | 2 秒 | ❌ 破損 | ❌ アーティファクト |
| ストリームコピー(キーフレーム位置) | 2 秒 | ±2 秒 | ✅ 完璧 |
| 再エンコード(シンプル) | 15 分 | ✅ フレーム単位 | ⚠️ 品質低下 |
| 2 パス方式(最適) | 3 分 | ✅ フレーム単位 | ✅ 完璧 |
時代背景:
- 2010 年:FFmpeg でカットするには全体の再エンコードが必要でした
- 2015 年:ストリームコピー用に
-c copyが追加されました - 2020 年:2 パス方式によるカットがベストプラクティスになりました
- 2024 年:ハードウェアアクセラレーション(NVENC)により再エンコードが実用的になりました
アンチパターン 2:不要な再エンコード
初心者の考え:「すべての編集を 1 つの FFmpeg コマンドで適用する」
問題:複数回の再エンコードによって、品質が累積的に低下します。
誤った方法:
# ❌ 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
誤りの理由:
- 再エンコードは毎回、非可逆圧縮になります(CRF が高くても同様です)
- 品質が累積的に低下します(世代劣化)
- エンコード時間が 3 倍になります
- ディスク I/O が無駄になります
正しい方法 1:単一のコマンドで処理を連結する
# ✅ 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
正しい方法 2:可能な場合はストリームコピーを使用する
# ✅ 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)
品質の比較:
| 方法 | エンコード回数 | 品質(VMAF) | 時間 |
|---|---|---|---|
| 3 回再エンコード(CRF 23) | 3 | 82/100 | 45 分 |
| 1 回でエンコード(CRF 23) | 1 | 91/100 | 15 分 |
| ストリームコピー+1 回エンコード | 1 | 95/100 | 18 分 |
| すべてストリームコピー | 0 | 100/100 | 30 秒 |
アンチパターン 3:色空間変換を無視する
初心者の考え:「動画をそのまま連結すればよい」
問題:色ずれ、明るさの不一致、再生の不具合が発生します。
誤った方法:
# ❌ 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
誤りの理由:
- 色空間が異なります(BT.601、BT.709、BT.2020)
- ピクセルフォーマットが異なります(yuv420p、yuvj420p)
- 色域が異なります(リミテッドレンジ、フルレンジ)
- メタデータが競合します
正しい方法:
# ✅ 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
色空間ガイド:
| 規格 | 色空間 | 伝達特性 | 原色 | 用途 |
|---|---|---|---|---|
| BT.601 | SD | bt470bg | bt470bg | 古い SD コンテンツ |
| BT.709 | HD | bt709 | bt709 | 現代の HD/FHD |
| BT.2020 | UHD/HDR | smpte2084 | bt2020 | 4K HDR |
| sRGB | Web | iec61966-2-1 | bt709 | Web 配信 |
アンチパターン 4:音声同期の不備
初心者の考え方:「映像と音声は別々のものだから、重ねればよい」
問題点:リップシンクのずれ、音声のドリフト、再生の不具合が発生します。
誤った方法:
# ❌ 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
誤りの理由:
- 音声と映像の長さが異なります
- タイムベースの同期がありません
- ドリフト補正がありません
- 元の音声同期を無視しています
正しい方法 1:映像に合わせて音声を伸縮させます
# ✅ 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
正しい方法 2:オフセットとトリミングを正確に調整します
# ✅ 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
正しい方法 3:同期を保ちながら複数の音声トラックをミックスします
# ✅ 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
音声同期チェックリスト:
□ 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
アンチパターン 5:プラットフォームに合わないコーデック/ビットレート
初心者の考え方:「すべてに同じエクスポート設定を使えばよい」
問題点:帯域幅の無駄遣い、画質の低下、アップロードの拒否、互換性の問題が発生します。
誤った方法:
# ❌ 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
誤りの理由:
- プラットフォームごとにファイルサイズやビットレートの上限が異なります
- 過剰なエンコードは帯域幅を無駄にします
- プラットフォームに合わない解像度です
- コーデックに互換性がありません
正しい方法:プラットフォームに最適化したエクスポート
YouTube(推奨設定):
# ✅ 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(ストーリーズ、リール、フィード):
# ✅ 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 動画):
# ✅ 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
プラットフォーム仕様表:
| プラットフォーム | 最大サイズ | 最大再生時間 | 解像度 | FPS | ビットレート | コーデック |
|---|---|---|---|---|---|---|
| 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 |
| 512 MB | 2:20 | 1920x1080 | 60 | 5 Mbps | H.264 | |
| TikTok | 287 MB | 10min | 1080x1920 | 30 | ~4 Mbps | H.264 |
| 5 GB | 10min | 1920x1080 | 30 | 5 Mbps | H.264 | |
| Web | Varies | Varies | 1920x1080 | 30 | 2-5 Mbps | H.264 |
エクスポート最適化チェックリスト:
□ 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
制作チェックリスト
□ 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)
使用する場合と避ける場合
| シナリオ | 適切かどうか |
|---|---|
| 自動動画パイプライン(スクリプト → 動画) | ✅ はい - FFmpeg による自動化 |
| 100 本の動画を一括処理 | ✅ はい - FFmpeg の並列ジョブ |
| クリップをプログラムでトリミング/カット | ✅ はい - 正確なカット |
| 動画に字幕を追加 | ✅ はい - 字幕の焼き込みまたはソフト字幕 |
| 映像のカラーグレーディング | ⚠️ 制限あり - 基本的なもののみ |
| マルチカメラ編集 | ❌ いいえ - DaVinci Resolve を使用 |
| モーショングラフィックス | ❌ いいえ - After Effects を使用 |
| リアルタイムプレビューでの編集 | ❌ いいえ - Premiere/Resolve を使用 |
参考資料
/references/ffmpeg-guide.md- FFmpeg コマンドの完全なリファレンス/references/timeline-editing.md- タイムラインの概念、マルチトラック編集/references/export-optimization.md- プラットフォーム別のエクスポート設定
スクリプト
scripts/video_editor.py- カット、トリミング、連結、トランジション、エフェクトscripts/batch_processor.py- 並列バッチ動画処理
このスキルの対象:動画編集 | FFmpeg | タイムライン編集 | トランジション | エクスポート最適化 | 音声ミキシング | カラーグレーディング | 動画制作の自動化