音と映像のズレが最初から最後まで同じ量なら、自動補正に頼らず、ずらす量を自分で指定するのが確実です。FFmpeg では、adelay で音声に遅れを足す方法と、-itsoffset で映像か音声のどちらかの時間をずらす方法があり、ズレの向きで使い分けます。-async を含むほかの方法はFFmpegで音ズレを修正する方法を参照してください。
音声遅延の種類
音ズレは、大きく 2 種類に分かれます。
| パターン | 症状 | 原因例 |
|---|---|---|
| 音声が映像より 遅れている | 口の動きより音があとから聞こえる | マイクの遅延、録画の設定 |
| 音声が映像より 早い | 音が聞こえてから口が動く | キャプチャデバイスの遅延差 |
方法 1: adelay — 音声に遅延を追加する
音声が映像より 早すぎる ときに、音声を遅らせて合わせます。adelay は、動画にBGMを追加・ミックスするときに、効果音やナレーションが始まるタイミングをずらすのにも使えます。
ステレオ音声に 500ms の遅延を追加する
ffmpeg -i input.mp4 \
-af "adelay=500|500" \
-c:v copy \
output.mp4
500|500 は、左チャンネルと右チャンネルにそれぞれ 500ms の遅れを付ける指定です。
モノラル音声の場合
ffmpeg -i input.mp3 \
-af "adelay=300" \
output.mp3
adelay パラメータ詳細
adelay=delays[|delays...]
- 遅らせる量は、チャンネルごとにパイプ(
|)で区切って指定します。 - 単位はミリ秒(ms)です。
0は遅延なしです。
# 2チャンネル(ステレオ)に異なる遅延
ffmpeg -i input.mp4 -af "adelay=200|400" -c:v copy output.mp4
# 5.1chに対応する場合(6チャンネル)
ffmpeg -i input.mp4 -af "adelay=300|300|300|300|300|300" -c:v copy output.mp4
方法 2: -itsoffset — 入力ファイルのタイムスタンプをずらす
-itsoffset は、そのあとに書いた入力ファイルのタイムスタンプ(再生する時刻)をずらします。同じファイルをもう一度入力として読み込み、映像と音声を別々の入力から取ると、片方だけをずらせます。
音声を 0.5秒 遅らせる(映像より音声が早い場合)
ffmpeg -i input.mp4 -itsoffset 0.5 -i input.mp4 \
-map 0:v -map 1:a \
-c:v copy -c:a copy \
output.mp4
0:v:1本目の入力の映像(タイムスタンプはそのまま)1:a:2本目の入力の音声(0.5秒ずらしたもの)
音声を 0.5秒 早める(音声が映像より遅れている場合)
ffmpeg -itsoffset 0.5 -i input.mp4 -i input.mp4 \
-map 0:v -map 1:a \
-c:v copy -c:a copy \
output.mp4
今度は映像(0:v)のほうに -itsoffset をかけます。映像の再生開始が 0.5秒 遅れるので、相対的に音声が 0.5秒 早くなります。
方法 3: atrim で音声の頭を切り詰める
音声が映像より遅れているときは、音声の頭を切り詰めて合わせる方法もあります。
ffmpeg -i input.mp4 \
-vf "setpts=PTS-STARTPTS" \
-af "atrim=start=0.3,asetpts=PTS-STARTPTS" \
-c:v libx264 \
output.mp4
atrim=start=0.3 で音声の最初の 0.3 秒を切り捨てるので、音声が 0.3 秒前にずれます。
ffprobe で音声遅延を確認する
ffprobe -v quiet -print_format json -show_streams input.mp4 2>&1 | grep "start_time"
映像ストリームと音声ストリームの start_time の差が、ズレの量の目安になります。ただし、録画機器の遅れのように中身そのものがずれている場合は start_time に差が出ないので、再生して確かめてください。
タイムスタンプを 0 から始める(-avoid_negative_ts)
映像と音声の start_time がずれているファイルに次のコマンドを使うと、最初のタイムスタンプが 0 になるように、すべてのストリームが同じ量だけずれます。
ffmpeg -i input.mp4 -c:v copy -c:a copy -avoid_negative_ts make_zero output.mp4
映像と音声の start_time の差はそのまま残るので、このコマンドで音ズレは直りません。差の分だけずらしたいときは、方法 2 の -itsoffset を使います。
実用的なワークフロー
ステップ 1: ズレを確認する
VLC などの動画プレイヤーで再生し、映像と音声が何秒ずれているかを確かめます。
ステップ 2: 方向を判断する
- 口が先に動き、音があとから聞こえる:音声が遅れています。
adelayは使わず、-itsoffsetで映像を遅らせます。 - 音が先に聞こえ、口があとから動く:音声が早すぎます。
adelayで音声を遅らせます。
ステップ 3: コマンドを実行する
# 例: 音声が300ms早い場合 (adelayで音声を遅らせる)
ffmpeg -i input.mp4 -af "adelay=300|300" -c:v copy output.mp4
NG例
NG例: adelayにステレオファイルで単一チャンネル値を指定
ffmpeg -i input.mp4 -af "adelay=500" -c:v copy output.mp4
ステレオのファイルに adelay=500 のように値を一つだけ指定すると、左チャンネルだけに効いて、右チャンネルはずれたまま残ることがあります。値はチャンネルの数だけ指定してください。
注意点
adelayは音声を遅らせるだけのフィルタで、早めることはできません。- 音声を早めたいときは、
-itsoffsetかatrimを使います。 -c:a copyは音声を再エンコードしないので、音質は落ちません。ただし、adelayを使うときは再エンコードが必要です。
関連フィルタ
よくある質問
長い動画ほど音ズレが進むのはなぜ?
録画機器で映像と音声の時計がわずかにずれていた場合や、VFR(可変フレームレート)の動画を CFR(固定フレームレート)前提のソフトで扱った場合に起きることがあります。タイムスタンプが正しい VFR の動画なら、ストリームコピーしただけでズレがたまることはありません。ソフトで扱うとずれる場合は、先に CFR に変換すると直ることがあります。
-itsoffset は何をする?
直後に書いた入力ファイルの、すべてのストリームのタイムスタンプを、ほかの入力に対してずらします。-itsoffset 0.5 -i audio.aac なら、音声が 500ms 遅れます。負の値にすると逆向きにずれます。
オフセットを自動検出したい
axcorrelate フィルタは、2つの音声の相関を -1〜1 の値の音声として出力するだけで、ずれの量(lag)は表示しません。ずれの量は、この記事のワークフローのように再生して確かめます。
Bluetooth による遅延も直せる?
直せません。Bluetooth の遅延は、再生するときにその機器で起きるもので、機器によって量も違います。プレーヤーや機器の設定(音声の遅延やリップシンクの調整)で直してください。1台の機器に合わせてファイルをずらすと、ほかの機器でずれます。
トリムするとオフセットが変わる?
変わりません。映像と音声を同じ位置で切れば、一定のズレはそのまま残ります。ただし -c copy では映像をキーフレームの位置からしか始められないので、正確に切りたいときは再エンコードしてください。