フレームレート変更 — -r オプションと fps フィルタの使い分け
動画のフレームレート(fps)を変更する場面はさまざまです。30fps の素材を 24fps に落として映画的な雰囲気にしたい、60fps の動画を Webm 向けに 30fps に圧縮したい、1fps でタイムラプスを作りたい、といったケースが代表的です。FFmpeg では主に -r オプションと -vf fps フィルタの 2 つの方法があり、用途によって使い分けることが推奨されています。本記事ではその違いと実践的なコマンド例を、ffmpeg 6.1 で確認済みの内容で解説します。
動作確認: ffmpeg 6.1.1 / Ubuntu 24.04
1. 現在のフレームレートを確認する(ffprobe)
変換前に元ファイルのフレームレートを確認しましょう。
ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate,avg_frame_rate -of default=noprint_wrappers=1 input.mp4
出力例:
r_frame_rate=30/1
avg_frame_rate=30/1
r_frame_rate はコンテナのメタデータに記録されたフレームレート、avg_frame_rate は実際のフレーム数から計算した平均フレームレートです。可変フレームレート(VFR)動画では両者が異なる場合があります。
2. -r オプション(出力フレームレート指定)
-r は出力側に付けることでフレームレートを指定します。
ffmpeg -i input.mp4 -r 30 -c:v libx264 -crf 23 -c:a copy output.mp4
公式ドキュメントでは、出力オプションとしての -r を “Duplicate or drop frames right before encoding them to achieve constant output frame rate fps.” と説明しています。つまり、フレームをエンコード直前に複製または削除することで目標フレームレートを実現します。
3. -vf fps フィルタ(より精確な制御)
ffmpeg -i input.mp4 -vf fps=30 -c:v libx264 -crf 23 -c:a copy output.mp4
fps フィルタはフィルタグラフの一部として動作し、フレームのタイムスタンプを参照しながらフレームを出力します。
4. -r と fps フィルタの違いと使い分け
両者は似ていますが、動作に重要な違いがあります。
| 比較項目 | -r(出力オプション) | -vf fps=N(フィルタ) |
|---|---|---|
| 処理タイミング | エンコード直前 | フィルタグラフ内(より早い段階) |
| タイムスタンプ参照 | 限定的 | フレームのタイムスタンプを参照 |
| 他フィルタとの組み合わせ | そのまま可能 | フィルタチェーンに組み込める |
| VFR(可変フレームレート)素材 | 動作が不安定になる場合あり | より安定した変換が期待できる |
一般的な推奨:単純なフレームレート変換では -vf fps=N が精確な動作をする場合が多く、特に可変フレームレート素材では fps フィルタの使用が安定した結果をもたらすことがあります。-r はシンプルな用途や他のオプションと組み合わせる際に便利です。
5. フレームレートを下げる(フレーム削除)
60fps の動画を 30fps に変換する例です。
ffmpeg -i input.mp4 -vf fps=30 -c:v libx264 -crf 23 -c:a copy output.mp4
フレームレートを下げる場合、fps フィルタは指定されたレートに合わせて余分なフレームを削除します。この処理ではフレーム補間(中間フレームの生成)は行いません。単純にフレームを間引きます。
6. フレームレートを上げる(フレーム複製)
24fps の動画を 60fps に変換する例です。
ffmpeg -i input.mp4 -vf fps=60 -c:v libx264 -crf 23 -c:a copy output.mp4
フレームレートを上げる場合、fps フィルタは既存フレームを複製することで目標レートを達成します。この方法では新たな中間フレームは生成されません(動きの滑らかさは元の素材のままです)。本格的なフレーム補間(モーション推定による中間フレーム生成)には minterpolate フィルタなど別の手法が必要です。
7. フレームレート変換の具体的なユースケース
60fps → 30fps(Web配信向け)
ffmpeg -i input.mp4 -vf fps=30 -c:v libx264 -crf 23 -c:a copy output.mp4
29.97fps → 25fps(PAL 規格向け)
ffmpeg -i input.mp4 -vf fps=25 -c:v libx264 -crf 23 -c:a copy output.mp4
30fps → 24fps(映画的な見た目)
ffmpeg -i input.mp4 -vf fps=24 -c:v libx264 -crf 23 -c:a copy output.mp4
8. タイムラプスへの応用:-vf fps=1
連番画像をタイムラプス動画に変換する場合、元の画像を 1 秒 1 枚のスライドショーとして読み込んで高フレームレートで出力するのが一般的です。ただし、連番画像 (img%03d.png など) を扱うコマンドは CI ルールにより text ブロックに記載します。
ffmpeg -framerate 1 -i img%03d.png -c:v libx264 -r 30 -pix_fmt yuv420p output.mp4
-framerate 1:入力画像を 1fps で読み込む(1 枚 = 1 秒)-r 30:出力を 30fps にする(1 枚が 30 フレームに複製される)-pix_fmt yuv420p:広い互換性のためのピクセルフォーマット指定
すでに動画になっているファイルから 1fps のサムネイル動画を生成する場合は:
ffmpeg -i input.mp4 -vf fps=1 -c:v libx264 -crf 23 output.mp4
これにより、元動画から 1 秒ごとに 1 フレームを抽出した低フレームレートの動画が生成されます。
9. フレームレートと音声の同期
フレームレートを変更しても音声のタイムスタンプは独立しているため、通常は自動的に同期が保たれます。しかし、大幅なフレームレート変更(例:1fps への変換)を行う場合は音声の扱いに注意が必要です。タイムラプス変換など映像の時間軸を変える処理では、-an(音声なし)で音声を除去するか、意図した音声処理を明示的に指定することを推奨します。
関連記事
動作確認: ffmpeg 6.1.1 / Ubuntu 24.04 (GitHub Actions runner)
一次ソース: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-filters.html / ffmpeg.org/ffmpeg-codecs.html