動画ファイルが大きすぎてアップロードできない、ストレージを圧迫している、そんな悩みをFFmpegで一発解決する。
この記事では CRF・ビットレート指定・2パスエンコード・プリセット という4つのアプローチを僕が丁寧に解説し、用途ごとに使うべき設定をまとめた。コマンドをコピーして即使えるレベルを目指した。
動画圧縮の基本概念
動画圧縮を理解するには、まず「品質」と「ファイルサイズ」のトレードオフを押さえておく必要がある。
動画エンコードには主に2つのアプローチがある。
- 可変ビットレート(VBR) — 複雑な場面には多くのビットを使い、単純な場面では少なくする。同じ品質をより小さいサイズで実現できる
- 固定ビットレート(CBR) — 常に一定量のデータを使う。ストリーミングの帯域保証などに使われる
コーデックは H.264(libx264)と H.265(libx265)が現在の主流だ。H.265 は同じ品質で H.264 の約半分のファイルサイズになるが、エンコードに時間がかかり、古い機器での再生互換性が下がる。
FFmpegのコーデック指定は -c:v オプションで行う。-c:v libx264 が H.264、-c:v libx265 が H.265 だ。
CRF(固定品質)で圧縮する
CRF(Constant Rate Factor)は 品質を固定してファイルサイズをコーデックに任せる 方式だ。「とにかく品質を保ちたい」という場面に最適で、FFmpegユーザーが最もよく使う方法でもある。
H.264 での CRF 圧縮:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a copy output.mp4
H.265 での CRF 圧縮(さらに小さくしたい場合):
ffmpeg -i input.mp4 -c:v libx265 -crf 28 -c:a copy output.mp4
品質を上げたい(ファイルサイズが増える)場合は CRF を下げる。例えば映像が繊細な画面の多い動画なら CRF 18 を試してみよう。逆に SNS 投稿など画質をそこまで重視しない場合は CRF 30〜35 まで上げるとファイルを大幅に削減できる。
ビットレート指定で圧縮する
ビットレート指定は ファイルサイズや転送帯域を厳密にコントロールしたい ときに使う。「最終的に何 MB にしたい」という目標がある場合はこちらが向いている。
ビットレートは映像時間 × ビットレート ÷ 8 でおよそのファイルサイズを算出できる。例えば 60 秒の動画を 2Mbps でエンコードすると約 15MB になる。
映像を 2Mbps に指定してエンコード:
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -c:a copy output.mp4
音声も含めてターゲットを指定する場合:
ffmpeg -i input.mp4 -c:v libx264 -b:v 1800k -c:a aac -b:a 192k output.mp4
ビットレート指定には注意点もある。シーンの複雑さに関わらず同じビットレートを使うため、単純な場面では品質が余り、複雑な場面では品質が不足することがある。CRF と比べて制御しにくいので、明確なサイズ制約がない場合は CRF を優先する方が結果がいい。
2パスエンコードで最適化する
2パスエンコードは まず動画を解析してから本番エンコードする 2段階の方式だ。ビットレート指定と組み合わせることで、より効率的にビットを配分できる。特に長い動画や配信用途で品質を最大化したいときに有効だ。
1パス目(解析のみ、映像ファイルは生成されない):
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -an -f null /dev/null
2パス目(本番エンコード):
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 -c:a aac -b:a 192k output.mp4
H.265 の場合は -c:v libx265 -x265-params pass=1 のように書く。
2パスエンコードはエンコード時間が倍になるが、同じビットレートでより高い品質を得られる。厳密なファイルサイズ制限がある DVD 配布や業務用途で特に効果的だ。日常的な圧縮用途なら CRF で十分なケースがほとんどだ。
プリセットで速度と品質を調整する
FFmpeg の libx264/libx265 には プリセット という設定がある。エンコード速度と圧縮効率のバランスを一発で変えられる便利な仕組みだ。
プリセットの種類(速い順):
ultrafast → superfast → veryfast → faster → fast → medium(デフォルト)→ slow → slower → veryslow
プリセットを指定したエンコード:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow -c:a copy output.mp4
プリセットの効果を体感するには、同じ動画で複数のプリセットを比較してみるのが一番だ:
for preset in fast medium slow veryslow; do
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset $preset -c:a copy output_${preset}.mp4
done
実用的な選び方は、普段の圧縮作業には medium(デフォルト)か slow、時間に余裕があって品質を追求したいなら veryslow、リアルタイム処理や大量バッチ処理なら fast or veryfast がちょうどいい。僕は普段 slow を使っている。
用途別の最適設定
用途に合わせたコマンドをそのまま使えるようにまとめた。
| 用途 | コーデック | CRF | プリセット | 備考 |
|---|---|---|---|---|
| Web 配信 | H.264 | 23 | slow | 互換性重視 |
| SNS(X / Instagram) | H.264 | 28〜30 | medium | ファイルサイズ優先 |
| アーカイブ保存 | H.265 | 24 | veryslow | 長期保存は H.265 |
| モバイル向け | H.264 | 26 | fast | 低解像度と組み合わせ |
Web 配信向け (互換性重視):
ffmpeg -i input.mp4 \
-c:v libx264 -crf 23 -preset slow \
-c:a aac -b:a 128k \
-movflags +faststart \
output_web.mp4
-movflags +faststart は moov atom をファイル先頭に移動させ、ダウンロード完了前に再生開始できるようにする Web 配信の必須オプションだ。
SNS 投稿向け (ファイルサイズ最優先):
ffmpeg -i input.mp4 \
-c:v libx264 -crf 30 -preset medium \
-vf "scale=1280:-2" \
-c:a aac -b:a 96k \
output_sns.mp4
長期アーカイブ向け (H.265 で最小化):
ffmpeg -i input.mp4 \
-c:v libx265 -crf 24 -preset veryslow \
-c:a aac -b:a 128k \
output_archive.mp4
モバイル向け (解像度縮小 + 軽量化):
ffmpeg -i input.mp4 \
-c:v libx264 -crf 26 -preset fast \
-vf "scale=720:-2" \
-c:a aac -b:a 96k \
output_mobile.mp4
よくある失敗と対処法
失敗 1: 圧縮したのにファイルが大きくなった
元の動画より大きな CRF やビットレートを指定すると、エンコードのオーバーヘッドで逆にサイズが増えることがある。元ファイルが既に圧縮済みの場合、これは特に起こりやすい。対策としては -c copy でコーデックをコピーするか、ビットレートを元動画のビットレート以下に設定する。
失敗 2: 画面が緑や黒になる
フォーマットの互換性問題で発生することが多い。-pix_fmt yuv420p を追加すると解決するケースが多い:
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -pix_fmt yuv420p -c:a copy output.mp4
失敗 3: 音声が劣化している
失敗 4: エンコードが異常に遅い
veryslow プリセットや 4K 以上の解像度、H.265 を組み合わせるとエンコードに数時間かかることがある。GPU エンコードを使うと劇的に速くなる:
# NVIDIA GPU (NVENC) を使う場合
ffmpeg -i input.mp4 -c:v h264_nvenc -crf 23 -c:a copy output.mp4
ただし GPU エンコードは CPU エンコードより圧縮効率がやや落ちる点は覚えておこう。
まとめ
FFmpeg の動画圧縮は用途に合った方式を選ぶことが大切だ。
- 品質重視なら CRF — 数値を決めたらあとはFFmpegに任せる
- サイズ指定が必要なら 2パス — ビットレート上限がある配信に
- 速度を変えたいならプリセット —
slowとveryslowで品質向上 - Web 配信には
-movflags +faststart— 忘れがちだが重要
FFmpegの基本的な使い方をまだ押さえていない場合は FFmpeg 基本コマンド入門 を先に読んでほしい。また、動画を品質劣化なしにカットしたい場合は FFmpeg でロスレスカット も参考になる。