変換後だけ音がズレる場合は、まず元動画と出力を同じプレーヤーで比べ、冒頭・中間・末尾のズレを記録します。原因の候補は、ファイル形式、再生環境、編集した時刻、欠落したPTS、音声のタイムスタンプなどです。VFRであること自体は異常ではありません。

まず記録すること

確認 分かること
元動画と出力を同じプレーヤーで再生 変換による変化か、プレーヤー差かを切り分ける
冒頭・中間・末尾の同じ動作と音を比較 一定の遅れか、徐々に増えるズレか
別のプレーヤーでも確認 特定の再生環境に限る問題か
実行したコマンドと警告を残す トリム、速度変更、時刻補正の影響を追える

会話の口元や手をたたく瞬間など、対応する映像と音が分かる場面を使います。元動画自体にズレがある場合と、変換で新たに生じた場合を分けてください。記録を他人に見せる際は、ログ内のファイル名・ユーザー名・保存先を伏せます。

一定のズレには固定の音声遅延の補正、末尾ほど増えるズレには音声ドリフトの切り分けも参照できます。

再エンコードして比較する

ストリームコピーは映像・音声をデコードせずに再多重化します。ただし時刻が常にそのままの数値で保存されるわけではなく、時間単位の変換や開始時刻の調整が関係します。「コピーでズレた」だけで元のタイムスタンプが壊れていたとは判断できません。

次は映像と音声を再エンコードする比較用の例です。原本を残し、出力名が既存ファイルと重ならないようにします。

ffmpeg -i input.mp4 -c:v libx264 -crf 20 -c:a aac output.mp4

CRF 20はこの例の設定値で、無劣化の保証ではありません。再エンコードも入力の時刻を利用するため、既存のズレが自動的に消えるわけではありません。結果を3地点で比べ、改善しなければ原因を再確認します。

音声サンプルと音声の時刻が合っていない場合

音声のタイムスタンプとサンプル数の不整合が確認できた場合は、映像をコピーしたまま aresample による補填・切り詰めを試せます。

ffmpeg -i input.mp4 -af aresample=async=1 -c:v copy output.mp4

async=1 は音声自身のタイムスタンプに合わせる処理です。映像の口元を認識して音を合わせる機能ではなく、誤った時刻に合わせても直りません。補填や切り詰めで音の内容が変わることがあるため、無音や途切れも確認します。

欠落したPTSを補う場合

+genpts はDTSがある場合に欠落したPTSを生成する指定です。すでに存在する誤った時刻をすべて修復するものでも、撮影時の正しい同期を推定するものでもありません。

ffmpeg -fflags +genpts -i input.mp4 -c copy output.mp4

入力側のオプションなので -i の前に置きます。再エンコードはしませんが、コンテナやビットストリームの表現が変わることがあり、出力が元ファイルとバイト単位で一致する保証はありません。

VFRを扱えない編集先に合わせる場合

VFRはフレーム間隔が変わる正常な記録方式です。対応するコンテナとプレーヤーなら同期を保てます。利用先がCFRを要求する場合に、フレームを重複・間引きして一定間隔へ変換する方法を検討します。

ffmpeg -i input.mp4 -fps_mode cfr -r 30 -c:v libx264 -c:a aac output.mp4

30fpsは一例です。29.97fpsの素材を扱うなど、入力と用途に合わせて目標を選んでください。CFR化は映像のフレーム配置を変えるもので、音声の固定遅延や収録機器のクロック差を必ず補正するわけではありません。

r_frame_rate と avg_frame_rate の差は調査の手掛かりであり、単独ではVFRの確定診断になりません。フレームごとの時刻間隔も調べます。VFRとCFRの確認手順を参照してください。

直らないとき

  • 設定を一度に重ねず、原本から1種類ずつ比較用出力を作る。
  • 変換前に切り出しや倍速処理をした場合は、その段階からズレていないか確認する。
  • 短い試験だけで直ったとせず、実際に渡す全編の音と映像を確認する。
  • 他人へ相談する際は、再現用の非機密クリップとコマンド、3地点のズレ量を用意する。元の私的な映像や生ログを不用意に公開しない。

参考資料

一次資料: FFmpegの同期・ストリームコピー、aresample、fflags / genpts。