FFmpegで動画を圧縮するなら、CRFモードが最適解だ。 ffmpeg -i input.mp4 -c:v libx264 -crf 23 -preset slow -c:a copy output.mp4 — これだけで品質を保ったまま大幅にファイルサイズを削減できる。
ただし「とりあえずCRF」で済まないケースもある。この記事では CRF・ビットレート指定・2パスエンコード・プリセット の4つのアプローチを解説する。32blogの動画素材で実際にベンチマークした経験から言うと、「適当に圧縮する」のと「正しく圧縮する」のでは同じ画質でもファイルサイズに60%近い差が出ることがある。用途別のコピペ可能なコマンドも記事後半にまとめた。
動画圧縮の基本概念
動画圧縮を理解するには、まず「品質」と「ファイルサイズ」のトレードオフを押さえておく必要がある。
動画エンコードには主に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エンコードガイドでも推奨されている方法だ。
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 を使っている。veryslow や H.265 を頻繁に使うなら、さくらのVPS や XServer VPS にエンコードを任せると手元の PC を占有せずに済む。
用途別の最適設定
用途に合わせたコマンドをそのまま使えるようにまとめた。
| 用途 | コーデック | 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 -rc vbr -cq 23 -c:a copy output.mp4
ただし GPU エンコードは CPU エンコードより圧縮効率がやや落ちる点は覚えておこう。詳しくは FFmpegをGPUで高速化する完全ガイド を参照してほしい。
ローカル PC のリソースを圧縮作業に取られたくない場合は、VPS にエンコード専用サーバーを立てる方法もある。veryslow や H.265 のような重い設定でも、VPS に投げれば作業中の PC が重くならない。
国内シェアNo.1のエックスサーバーが提供する高性能VPS
- NVMe SSD・AMD EPYC搭載の高速サーバー
- 2GBプラン 月額990円〜(3コア / 50GB SSD)
- 初期費用無料
よくある質問
CRFの最適な値は?
コンテンツと目的によって変わる。汎用的な圧縮なら H.264 で CRF 23、H.265 で CRF 28 がデフォルトで、まずはこの値から試すのがいい。スクリーンキャプチャやアニメーションは CRF 18〜20 が向いている。SNS 投稿など画質をそこまで重視しないなら CRF 30〜35 でも十分だ。
CRFとビットレート指定、どちらを使うべき?
品質重視ならCRF、ファイルサイズに上限があるならビットレート指定だ。CRF はシーンの複雑さに応じてデータ量を自動調整してくれるので、ほとんどの場面で CRF のほうがいい結果になる。「Discordの25MB制限に収めたい」のような場合だけビットレート指定(2パス)を使えばいい。
FFmpegで無劣化の圧縮はできる?
再エンコードする以上、完全な無劣化にはならない。ただし -c:v copy を使えば映像データに手を加えず、コンテナ変換やトリミングだけを行える。カット編集なら FFmpegでロスレスカット の記事が参考になる。
特定のファイルサイズに圧縮するには?
目標ビットレートを計算する:目標サイズ(ビット) ÷ 動画の秒数 = 目標ビットレート。例えば 120 秒の動画を 50MB に収めるなら 50 × 8 × 1024 ÷ 120 ≒ 3,413kbps → -b:v 3400k で 2パスエンコードする。
H.264とH.265、どちらを選ぶ?
H.265 は同画質で約半分のファイルサイズだが、エンコードは 2〜5 倍遅く、再生できない端末もある。Web 配信や SNS には H.264、長期保存やメディアサーバー用途には H.265 がおすすめだ。AV1 も含めた比較は AV1 vs H.265 vs H.264 比較ガイド を参照。
GPU エンコードは CPU より優れている?
GPU エンコード(NVENC, QSV, AMF)は 5〜10 倍速いが、同じ見た目の品質ならファイルサイズは CPU より大きくなる。リアルタイムエンコードや大量バッチ処理など速度重視の場面向き。圧縮効率を最大化するなら CPU の slow や veryslow プリセットに軍配が上がる。
-movflags +faststart って何?
MP4 のメタデータ(moov atom)をファイル末尾から先頭に移動するオプションだ。これにより、ブラウザやプレーヤーがファイルを全部ダウンロードする前に再生を開始できる。Web で公開する動画には必ず付けよう。
圧縮前に元動画のビットレートを確認するには?
ffprobe -v quiet -show_entries format=bit_rate -of default=noprint_wrappers=1 input.mp4 で確認できる。元のビットレートを知っておくと、圧縮後にファイルが大きくなる事故を防げる。
まとめ
FFmpeg の動画圧縮は用途に合った方式を選ぶことが大切だ。
- 品質重視なら CRF — 数値を決めたらあとはFFmpegに任せる
- サイズ指定が必要なら 2パス — ビットレート上限がある配信に
- 速度を変えたいならプリセット —
slowとveryslowで品質向上 - Web 配信には
-movflags +faststart— 忘れがちだが重要
FFmpegの基本的な使い方をまだ押さえていない場合は FFmpeg 基本コマンド入門 を先に読んでほしい。また、動画を品質劣化なしにカットしたい場合は FFmpeg でロスレスカット も参考になる。
この記事のCRFコマンドを毎回入力するのが面倒なら、ffmpeg-quick を使えば npx ffmpeg-quick compress input.mp4 の一発で済む。--dry-run オプションで実際のFFmpegコマンドも確認できる。
関連記事: