この記事でわかること

  • 動画ファイル(.mp4)に BGM(.mp3 など)を重ねる基本コマンド
  • 元の音声を残す/消すパターンの使い分け
  • BGM だけ音量を 30% に下げて声をクリアに保つ方法
  • BGM が動画より短い・長いときの対処(apadaloopshortest
  • BGM のフェードイン・フェードアウト
  • イントロ/メイン/アウトロの 3 トラックを 1 本の BGM につなぐ方法
  • ナレーションに合わせて BGM を自動で下げるダッキング
  • ストリームマップの落とし穴と回避策
  • 複数動画への一括 BGM 適用(バッチ)

テスト済みバージョン: FFmpeg 8.1 で確認済み 対象 OS: Windows / macOS / Linux


動画に BGM を重ねる基本コマンド

もっとも実用的な「動画の音声 + BGM」の合成は amix フィルタで行います。-c:a copy では音声を再エンコードできないため必ず外し、AAC などで再エンコードします。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[0:a][1:a]amix=inputs=2:duration=shortest:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

ポイントは 3 つです。-filter_complex で 2 入力をマージし、-map 0:v:0 で動画ストリームを残し、-map "[aout]" で合成済み音声を選びます。映像は再エンコ不要なので -c:v copy で高速に処理できます。

amix の主要オプション

オプション既定値説明
inputs2合成する入力の本数
durationlongestlongestshortestfirst から長さを決定
dropout_transition2入力が終わった瞬間の音量フェード時間(秒)
weights1 1各入力の重み(音量比)。後述の volume と併用可
normalize11 のとき出力をクリップ防止のため自動正規化

amix と amerge の違い

両者を混同しがちですが目的が異なります。

フィルタ用途出力
amix同じチャンネル数で音を重ねる(合算)入力と同じチャンネル数
amergeチャンネルを結合(モノラル 2 本→ステレオ)入力チャンネル数の合計

「動画 + BGM」は重ねたいので amix を使うのが正解です。amerge を使うと L/R が分離して片チャンネルだけ BGM、もう片方が音声、という意図しない結果になります。


元の音声を BGM で置き換える

元の音声を捨てて BGM だけにしたい場合は、-an で動画の音声を破棄し、BGM のみマップします。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -map 0:v:0 -map 1:a:0 -c:v copy -c:a aac -b:a 192k -shortest output.mp4

-shortest は短い方の入力長で出力を打ち切るオプションで、BGM が動画より長くても自動で揃います。-c:a aac を省くと MP3 ストリームのまま MP4 に入って再生互換性が落ちることがあるため、明示的に AAC に変換するのが安全です。


音量バランスの調整

「BGM がうるさくて声が聞こえない」が最大の悩みです。volume フィルタを amix の前段に挟み、BGM だけ音量を下げます。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[1:a]volume=0.3[bgm];[0:a][bgm]amix=inputs=2:duration=shortest:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

volume=0.3 は 30% の音量(約 -10dB)です。実用的な目安は次の通り。

シーン元音声BGM
解説・チュートリアル1.00.15〜0.25
Vlog(環境音残し)0.70.30〜0.40
サイレント映像にBGM(無音)1.0
音楽メインの映像0.201.0

dB 単位で指定したい場合は volume=-12dB のように書けます。amix は既定で normalize=1(自動正規化)が効くため、意図した比率にならないときは normalize=0 を追加してください。

単一入力で BGM ミックスを検証する

検証用にコピー音源で同じ手順を確かめるには、asplit で 1 本を 2 本に分けてミックスします。

ffmpeg -i input.mp3 -filter_complex "[0:a]asplit=2[a1][a2];[a1]volume=0.3[bgm];[a2]volume=1.0[voice];[bgm][voice]amix=inputs=2:duration=longest:dropout_transition=0[out]" -map "[out]" -c:a libmp3lame output.mp3

asplit=2 で同じ音を 2 本に複製し、片方だけ音量を下げて amix する練習用パターンです。実プロジェクトでは 2 入力に置き換えて使います。


BGM が動画より短い・長い場合の対処

動画 60 秒・BGM 30 秒のように長さが合わないとき、選択肢は 4 つあります。

状況対処フィルタ効果
BGM が短い → 無音で埋めたいapad末尾を無音で延長
BGM が短い → ループで埋めたいaloopBGM をループ再生
BGM が長い → 動画に合わせたいamix=duration=shortest または -shortest短い方で打ち切り
BGM 終端をきれいに切りたいatrim + afade任意秒で切ってフェードアウト

BGM をループで動画長まで延ばす

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[1:a]aloop=loop=-1:size=2e+09[loop];[0:a][loop]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

aloop=loop=-1 で無限ループ、size=2e+09 でループバッファを十分大きく確保します。duration=first で動画(1 本目)の長さに揃えます。

BGM 末尾を無音で埋める

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[1:a]apad[pad];[0:a][pad]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

apad は引数なしで「無限の無音を末尾に追加」します。amix 側で duration=first を指定しているので動画長で自動的に止まります。

単一入力で apad の動作を確認

ffmpeg -i input.mp3 -af "apad=pad_dur=5,atrim=0:25" output.mp3

20 秒の音源に 5 秒の無音を足し、atrim=0:25 で 25 秒に整えます。BGM の長さ調整ロジックを単独で確認したい場合に便利です。


BGM のフェードイン / フェードアウト

BGM を突然鳴らすと聞き手に違和感を与えます。afade で開始 2 秒・終了 3 秒のフェードを入れましょう。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[1:a]volume=0.3,afade=t=in:st=0:d=2,afade=t=out:st=57:d=3[bgm];[0:a][bgm]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

afade=t=out:st=57:d=3 は「57 秒目から 3 秒かけてフェードアウト」の意味で、動画 60 秒なら末尾までに 0 まで下がります。-shortest を併用するなら st を動画長より少し前に取るのがコツです。

単一入力で BGM フェードチェーンを検証

ffmpeg -i input.mp3 -af "volume=0.3,afade=t=in:st=0:d=2,afade=t=out:st=15:d=5" output.mp3

20 秒の音源に対し、開始 2 秒のフェードイン+15 秒目から 5 秒のフェードアウトを 1 行で適用するチェーン例です。詳しくは 音声フェードイン・フェードアウト を参照。


複数の BGM をつなぐ(イントロ・メイン・アウトロ)

3 つの BGM を順番につないで 1 本にしたい場合は concat フィルタの音声モードを使います。

ffmpeg -i intro.mp3 -i main.mp3 -i outro.mp3 \
  -filter_complex "[0:a][1:a][2:a]concat=n=3:v=0:a=1[bgm]" \
  -map "[bgm]" -c:a libmp3lame combined_bgm.mp3

n=3 は入力本数、v=0:a=1 は「映像 0・音声 1」という意味です。出来上がった combined_bgm.mp3 を本記事の他のコマンドの bgm.mp3 として使えば、イントロ→メイン→アウトロを動画に重ねられます。

単一入力で concat の動作を体験

ffmpeg -i input.mp3 -filter_complex "[0:a]asplit=3[a1][a2][a3];[a1]atrim=0:5,asetpts=PTS-STARTPTS[s1];[a2]atrim=0:10,asetpts=PTS-STARTPTS[s2];[a3]atrim=0:5,asetpts=PTS-STARTPTS[s3];[s1][s2][s3]concat=n=3:v=0:a=1[out]" -map "[out]" -c:a libmp3lame output.mp3

1 本の音源を 5 秒・10 秒・5 秒に切って再連結する練習例です。asetpts=PTS-STARTPTS で各セグメントのタイムスタンプを 0 にリセットしているのがポイントで、これを忘れると concat が音飛びを起こします。


元動画の音声を自動でダッキング

ナレーションが聞こえやすいように、声が出ている瞬間だけ BGM を自動で下げる「サイドチェインコンプレッサー」を使います。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[0:a]aformat=fltp:44100:stereo[voice];[1:a]aformat=fltp:44100:stereo,volume=0.5[bgm];[bgm][voice]sidechaincompress=threshold=0.02:ratio=6:attack=200:release=1000[ducked];[ducked][voice]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

仕組みは「声が来る → コンプレッサーが BGM を圧縮 → 声が止まる → BGM が元に戻る」です。詳しい解説とパラメータの意味は sidechaincompress でナレーション時に BGM を自動で下げる を参照してください。


ストリーミングマップの落とし穴

-filter_complex を使うと、FFmpeg は自動マッピングを完全に無効化します。-map を書かないと「音声が無い動画」「BGM だけの動画」が出来上がる失敗が起こりがちです。

パターン結果
-map 0:v:0 -map "[aout]"✅ 動画 + 合成音声(正解)
-map "[aout]" のみ❌ 音声だけの出力(映像が消える)
-map 0 のみ❌ 元の音声がそのまま、BGM が反映されない
何もマップしない❌ filter_complex 出力は無視され、最初の v/a が選ばれる
# 間違い
ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[0:a][1:a]amix=inputs=2:duration=shortest[aout]" \
  -c:v copy -c:a aac output.mp4

上記は -map を書いていないため、[aout] が捨てられて元の音声がそのまま出力されます。-filter_complex を使ったら -map は必須と覚えましょう。


バッチ処理:複数動画に同じ BGM

ディレクトリ内の .mp4 全部に同じ BGM を当てる Bash スクリプト例です。

for f in *.mp4; do
  ffmpeg -i "$f" -i bgm.mp3 \
    -filter_complex "[1:a]volume=0.3,afade=t=in:st=0:d=2[bgm];[0:a][bgm]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
    -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k "out/${f%.mp4}_bgm.mp4"
done

Windows PowerShell なら Get-ChildItem *.mp4 | ForEach-Object { ffmpeg ... } の形に置き換えます。映像は -c:v copy なので 100 本でも数分で終わるのが利点です。


トラブルシューティング

出力に音が無い

-filter_complex を使ったのに -map "[aout]" を書き忘れていないか確認してください。-c:a copy を残していると音声フィルタの結果がコピーされず無音になることもあります。

BGM がクリップ(音割れ)する

amix の自動正規化が効きすぎて低い、または逆に重ねた結果がクリップしている場合は次のように調整します。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[0:a]volume=0.8[v];[1:a]volume=0.3[bgm];[v][bgm]amix=inputs=2:duration=first:dropout_transition=0:normalize=0[aout],alimiter=limit=0.95[lim]" \
  -map 0:v:0 -map "[lim]" -c:v copy -c:a aac -b:a 192k output.mp4

normalize=0 で自動正規化を切り、alimiter で 0.95(約 -0.5dB)にハードリミットを掛けるのが安全パターンです。最終出力の音圧を整えるなら 音量の正規化(loudnorm/LUFS) も検討してください。

動画と BGM が同期しない(だんだんズレる)

入力のサンプルレートが異なると amix 後にドリフトが生じます。aformat=fltp:44100:stereo で揃えてから amix に渡すと安定します。

ffmpeg -i input.mp4 -i bgm.mp3 \
  -filter_complex "[0:a]aformat=fltp:44100:stereo[v];[1:a]aformat=fltp:44100:stereo,volume=0.3[bgm];[v][bgm]amix=inputs=2:duration=first:dropout_transition=0[aout]" \
  -map 0:v:0 -map "[aout]" -c:v copy -c:a aac -b:a 192k output.mp4

よくある質問

BGM が大きすぎて声が聞こえない

volume=0.20.3amix の手前で掛けるのが第一歩。それでも被るなら自動ダッキング(sidechaincompress)を使ってください。

BGM が動画の長さに合わない

短いなら aloop でループ、長いなら amix=duration=first または -shortest で動画長に切ります。両方の併用も可能です。

自動でダッキングしたい

sidechaincompress でナレーション時に BGM を自動で下げる で詳細パラメータと自然なアタック/リリースの設定例を解説しています。

元の音声を残したい?消したい?

残すなら amix、消すなら -an で破棄して BGM だけマップ。素材の環境音を活かしたい Vlog では残し、BGM 一発勝負の MV では消す、と使い分けます。

BGM が片チャンネルだけになる

amerge を使ったり、モノラル BGM をそのまま重ねるとチャンネル割り当てが崩れます。aformat=fltp:44100:stereo で強制ステレオ化し、amix を使ってください。

ロイヤリティフリー BGM の入手先

YouTube オーディオライブラリ(YouTube Studio から無料)、Pixabay Music、DOVA-SYNDROME、甘茶の音楽工房などが定番です。利用規約と帰属表示の要否を必ず確認しましょう。


関連記事


動作確認: ffmpeg 8.1 / Windows 11 一次ソース: ffmpeg.org/ffmpeg-filters.html#amix