可変フレームレート(VFR)とは、フレーム間の時間が固定されていない動画のことです。ソースは一定の間隔ではなく、何かが変化したときにフレームを記録します。画面録画ソフト、スマホのカメラ、ゲームキャプチャツールの多くは、しばしばVFRを生成します。録画には効率的ですが、「音がズレる」問題の非常に多くの割合を占める隠れた根本原因でもあります。一定の音声クロックが、さまよう映像クロックに揃い続けられないからです。多くの編集ソフトやプレイヤーは固定フレームレート(CFR)を前提としており、VFRを正しく扱えないこともあります。本記事では ffprobe でVFRを 検出 し、FFmpegでCFRに 変換 する方法を示します。
動作確認: FFmpeg 8.1
この記事でわかること
- VFRとCFRとは何か、なぜVFRが音ズレを起こすのか
ffprobeでr_frame_rateとavg_frame_rateを比較してVFRの疑いを見分ける方法(ヒューリスティック)-fps_mode cfrと目標レートでVFRをCFRに変換する方法- FFmpeg 8.x では
-fps_modeを使うこと(旧来の-vsyncも動くが非推奨)
音ズレやドリフトでここに来た場合、CFRへの変換がまさに「決定打」になることがよくあります。音ズレが徐々に進行する問題を直す と 変換後に音ズレする原因と解決法 も参照してください。
VFR と CFR
| 種類 | フレームのタイミング | 典型的なソース | 編集ソフト/プレイヤーとの相性 |
|---|---|---|---|
| VFR(可変) | フレームごとに間隔が変わる | 画面/スマホ/ゲーム録画 | 誤処理されがち、ドリフトしうる |
| CFR(固定) | 一定間隔(例: 1/30秒ごと) | 放送、ほとんどのエンコーダ | 広く対応 |
CFRでは、すべてのフレームが予測可能な時刻に位置するため、一定の音声クロックが映像にロックし続けます。VFRではフレーム間隔がさまよい、固定レートを前提とするツールが徐々に音声をズラしていきます。これがクリップ全体で悪化するドリフトとして現れます。
手順①: ffprobe でVFRを検出する
VFRを「疑う」手早い方法は、報告される2つのレート、r_frame_rate と avg_frame_rate(ファイル全体の平均)を比較することです。ここで r_frame_rate が何かを正しく理解しておくことが重要です。これは FFmpegが推測した基準レート——ストリーム内のすべてのタイムスタンプを表現できる最小のレート(最小公倍数に近い値)であって、「実際の」あるいは意図されたフレームレートではありません。したがって r_frame_rate と avg_frame_rate が食い違うのは、そのファイルがVFRかもしれないという「ヒューリスティック(手がかり)」であって、それだけでは証拠になりません。真のCFRファイルでは、両者は通常等しいかほぼ等しくなります。
ファイルをざっと調べます。
ffprobe -hide_banner input.mp4
ストリームの概要で、FFmpegは 30 fps や 29.97 tbr といった値を表示します。2つのレートを明示的に読むには、映像ストリームの r_frame_rate と avg_frame_rate フィールドを見ます。両者が食い違っていれば、そのファイルがVFRである強い手がかりと捉え、変換する前に確認しましょう。
# 例示的な比較(コマンドではありません)
r_frame_rate = 60/1 <- FFmpegの基準レート推測値(最小公倍数に近い)
avg_frame_rate = 47/1 <- 実際の平均。異なる => VFRを疑う
近い・同一ならCFRを示唆し、目立った差はVFRのサインです。「疑う」だけでなくVFRを確定するには、実際のフレームごとの長さが変動しているかを確認します——例えばフレームごとのタイムスタンプを調べます(ffprobe -show_frames / -show_packets で pkt_duration やタイムスタンプ間の差がどう変化するかを見る)。フレームの長さが実際に変動していればVFR、均一であれば、たとえ報告される2つのレートが食い違っていても実質的にCFRです。
手順②: 30 fps のCFRに変換する
変換するには、-fps_mode cfr で固定フレームレートに強制し、-r で目標レートを選びます。ソースの公称ケイデンスに合うレートを使います(画面/スマホ録画では一般的に30)。ここでは音声をそのままコピーするので、再エンコードされるのは映像だけです。
ffmpeg -i input.mp4 -fps_mode cfr -r 30 -c:v libx264 -c:a copy output.mp4
-fps_mode cfr— 出力を固定フレームレートに強制-r 30— 目標を毎秒30フレームに-c:v libx264— 映像を安定したタイムライン上に再エンコード(フレームタイミング変更に必須)-c:a copy— 音声をそのままコピー(無劣化)
CFRに強制するとき映像の再エンコードは避けられません。固定のケイデンスに合わせるため、FFmpegがフレームを複製・削除する必要があるからです。音声は通常コピーできます。
手順③: 60 fps のCFRに変換する(高品質)
動きの激しいコンテンツ(ゲームプレイ、速いアクション)で60 fpsと高品質を狙う場合は、レートを上げてCRFを下げます。ここでは音声をAACに再エンコードします。ソースの音声コーデックが出力コンテナに適さない場合の安全な選択です。
ffmpeg -i input.mp4 -fps_mode cfr -r 60 -c:v libx264 -crf 18 -c:a aac output.mp4
-r 60— 目標を毎秒60フレームに-crf 18— 既定より高品質(CRFが低いほど高品質・大きいファイル)-c:a aac— MP4との幅広い互換性のため音声をAACに再エンコード
目標レートは意図して選んでください。30 fpsのソースを60 fpsにエンコードしてもフレームが複製されるだけで実際の滑らかさは増しません。レートを上げる特別な理由がない限り、-r はソースが実際に出すものに合わせてください。
重要: -fps_mode と非推奨の -vsync
FFmpeg 8.x では正しいオプションは -fps_mode cfr です。古いチュートリアルでは -vsync cfr(または -vsync 1)を使っているのを今でも見かけます。その記法は今のところ まだ動作します が、-vsync は 非推奨 であり、将来のリリースで削除される可能性があります。新しいコマンドでは -fps_mode を優先してください。両者は同じ内部挙動に対応します——cfr は必要に応じてフレームを複製・削除することで固定フレームレートに強制します。
| オプション | FFmpeg 8.x での状態 | 使うべきか |
|---|---|---|
-fps_mode cfr | 現行、推奨 | はい |
-vsync cfr / -vsync 1 | 非推奨、まだ動作 | いいえ(旧来のみ) |
まとめ表
| 目的 | コマンド |
|---|---|
| VFRの疑い | ffprobe -hide_banner input.mp4(r_frame_rate と avg_frame_rate を比較) |
| CFR 30に変換、音声維持 | ffmpeg -i input.mp4 -fps_mode cfr -r 30 -c:v libx264 -c:a copy output.mp4 |
| CFR 60に変換、高品質 | ffmpeg -i input.mp4 -fps_mode cfr -r 60 -c:v libx264 -crf 18 -c:a aac output.mp4 |
VFR→CFRという枠組みではなく、単にfpsを変えたい場合は フレームレートを変更する を参照してください。
よくある質問
自分のファイルがVFRだと確実に判断するには?
r_frame_rate と avg_frame_rate の比較はあくまで「ヒューリスティック(手がかり)」です。r_frame_rate はFFmpegが推測した基準レート(最小公倍数に近い値)であり実際のフレームレートではないため、不一致はVFRを「示唆」するにすぎません。確定するには、実際のフレームごとの長さを調べます(例: ffprobe -show_frames / -show_packets でフレームごとのタイムスタンプを確認)。フレーム間隔が変動していれば真のVFR、均一であれば不一致があっても実質的にCFRです。画面・スマホ・ゲームの録画は、VFRであることの方がはるかに多いです。
なぜVFRは音ズレを起こすのですか?
音声は一定のサンプルクロックで再生されますが、VFRの映像フレームは不規則な間隔で到着します。一定レートを前提とするツールが徐々に両者をズラし、クリップ全体で悪化するドリフトを生みます。CFRに変換すれば音声がロックできる固定ケイデンスが得られます——音ズレが徐々に進行する問題を直す を参照。
VFRをCFRに変換するには映像の再エンコードが必要ですか?
はい。固定フレームレートに強制するには、固定ケイデンスに合わせてフレームを複製・削除する必要があり、映像の再エンコードを伴います。ただし音声は -c:a copy でコピーできることが多いです。
目標フレームレートは何にすべきですか?
-r はソースの公称レートに合わせてください——画面/スマホ録画なら通常30、ゲームプレイなら60です。30 fpsのソースを60 fpsにエンコードしてもフレームが複製されるだけで、実際の滑らかさは増しません。
-vsync と -fps_mode のどちらを使うべきですか?
-fps_mode cfr を使ってください。FFmpeg 8.x では -vsync は非推奨です。まだ動作しますが旧来扱いとすべきです。新しいコマンドでは -fps_mode を使ってください。
関連記事
Tested with FFmpeg 8.1 — verified with our command-check script
一次ソース: ffmpeg.org/ffmpeg.html / ffmpeg.org/ffmpeg-filters.html#aresample