動画を繋いだら、あるクリップだけ音が小さくて別のクリップで爆音になった — そんな経験はないだろうか?音量のバラつきは動画制作で最も多い不満の一つで、Redditのr/ffmpegやオーディオ系フォーラムでも定番の質問だ。
FFmpegの loudnorm フィルタを使えば、音声のラウドネスを EBU R128 規格に準拠した形で正規化できる。基本コマンドは ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11 output.mp4 — これだけでYouTubeやSpotifyに適した -16 LUFS に揃う。
この記事では、1パス・2パス正規化の使い分け、プラットフォーム別のラウドネス基準、ffmpeg-normalize を使ったバッチ処理まで、音声正規化に必要な知識をまとめる。
この記事でわかること
- loudnormフィルタの仕組みと各パラメータの意味
- 1パス vs 2パス正規化の使い分け
- YouTube・Spotify・Apple・TikTok・放送のラウドネス基準
- ffmpeg-normalizeによるバッチ処理
- loudnorm・volume・dynaudnorm・compandの違い
loudnormフィルタの基本
loudnorm フィルタは、ITU-R BS.1770アルゴリズム(K特性フィルタ+ゲーティング)で知覚ラウドネスを測定し、目標レベルにゲインを調整する。内部的には192kHzにアップサンプリングしてトゥルーピークを正確に検出し、100msルックアヘッドのリミッターで歪みを防ぐ。
1パス正規化(最もシンプル)
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11 output.mp4
各パラメータの意味はこうだ。
| パラメータ | 意味 | 範囲 | デフォルト |
|---|---|---|---|
I | 目標統合ラウドネス(LUFS) | -70.0〜-5.0 | -24.0 |
TP | 最大トゥルーピーク(dBTP) | -9.0〜0.0 | -2.0 |
LRA | 目標ラウドネスレンジ(LU) | 1.0〜50.0 | 7.0 |
1パスモードは ダイナミック(非線形)正規化 — AGCがリアルタイムにゲインを調整する。ファイル全体を読まずに処理できるので高速だが、2パスほどの精度はない。
ラウドネスを測定してから正規化する
正規化前に現在のラウドネスを確認するのは良い習慣だ。
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json -f null -
出力されるJSONの読み方:
{
"input_i": "-27.61",
"input_tp": "-4.47",
"input_lra": "18.06",
"input_thresh": "-39.20",
"output_i": "-16.58",
"output_tp": "-1.50",
"output_lra": "14.78",
"output_thresh": "-27.71",
"normalization_type": "dynamic",
"target_offset": "0.58"
}
input_i がソースの統合ラウドネス。目標値との差がどれだけあるかわかる。normalization_type が linear なら線形正規化、dynamic ならAGCが介入したことを示す。
2パス正規化で精度を上げる
2パス正規化は、まずファイル全体を測定し、その結果を使って正確な補正を行う。これにより リニア(線形)正規化 — ファイル全体に均一なゲインを適用し、元のダイナミクスを完全に保つことができる。
パス1: 測定
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json -f null - 2>&1
JSON出力の input_i、input_tp、input_lra、input_thresh、target_offset をメモしておく。
パス2: 適用
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11:measured_I=-27.61:measured_LRA=18.06:measured_TP=-4.47:measured_thresh=-39.20:offset=0.58:linear=true -ar 48000 output.mp4
measured_* パラメータに測定値を渡し、linear=true で線形正規化を指定する。
シェルスクリプトで2パスを自動化する
毎回JSONを手作業でパースするのは面倒だ。以下のスクリプトで自動化できる。
#!/bin/bash
# two-pass-normalize.sh — 音声を目標LUFSに正規化
INPUT="$1"
OUTPUT="$2"
TARGET_I=${3:--16}
TARGET_TP=${4:--1.5}
TARGET_LRA=${5:-11}
# パス1: 測定
JSON=$(ffmpeg -i "$INPUT" -af "loudnorm=I=$TARGET_I:TP=$TARGET_TP:LRA=$TARGET_LRA:print_format=json" -f null - 2>&1 | sed -n '/{/,/}/p')
# 測定値を抽出
measured_I=$(echo "$JSON" | grep '"input_i"' | sed 's/.*: "//;s/".*//')
measured_TP=$(echo "$JSON" | grep '"input_tp"' | sed 's/.*: "//;s/".*//')
measured_LRA=$(echo "$JSON" | grep '"input_lra"' | sed 's/.*: "//;s/".*//')
measured_thresh=$(echo "$JSON" | grep '"input_thresh"' | sed 's/.*: "//;s/".*//')
offset=$(echo "$JSON" | grep '"target_offset"' | sed 's/.*: "//;s/".*//')
# パス2: 適用
ffmpeg -i "$INPUT" -af "loudnorm=I=$TARGET_I:TP=$TARGET_TP:LRA=$TARGET_LRA:measured_I=$measured_I:measured_LRA=$measured_LRA:measured_TP=$measured_TP:measured_thresh=$measured_thresh:offset=$offset:linear=true" -ar 48000 "$OUTPUT"
使い方:
chmod +x two-pass-normalize.sh
./two-pass-normalize.sh input.mp4 output.mp4 -16 -1.5 11
Pythonでもっと高度な自動化をしたい場合は FFmpeg × Pythonバッチ処理入門 を参照してほしい。
プラットフォーム別ラウドネス基準
プラットフォームごとにラウドネスの基準が異なる。基準に合った音声を納品すれば、プラットフォーム側の自動正規化(アーティファクトの原因になる)を回避できる。
| プラットフォーム | 目標LUFS | トゥルーピーク | 備考 |
|---|---|---|---|
| YouTube | -14 LUFS | -1.5 dBTP | 再生時に自動正規化 |
| Spotify | -14 LUFS | -1 dBTP | ReplayGain方式 |
| Apple Music | -16 LUFS | -1 dBTP | Sound Check機能 |
| Apple Podcasts | -16 LUFS | -1 dBTP | Apple Musicと同基準 |
| Amazon Music | -14 LUFS | -2 dBTP | 音量を下げるのみ(上げない) |
| TikTok | 約-14 LUFS | -1 dBTP | 公式仕様なし、業界の通説 |
| Instagram Reels | 約-14 LUFS | -1 dBTP | MetaがxHE-AACで管理 |
| EBU R128(欧州放送) | -23 LUFS | -1 dBTP | 欧州放送基準 |
| ARIB TR-B32(日本放送) | -24 LKFS | 規定あり | 2012年運用開始。ARIB概要 |
出典: EBU Tech R128、各プラットフォーム開発者ドキュメント、業界測定値
すぐ使えるコマンド集
YouTube / Spotify / TikTok(-14 LUFS):
ffmpeg -i input.mp4 -af loudnorm=I=-14:TP=-1.5:LRA=11 output.mp4
Apple Music / Podcasts(-16 LUFS):
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1:LRA=11 output.mp4
放送(EBU R128、-23 LUFS):
ffmpeg -i input.mp4 -af loudnorm=I=-23:TP=-1:LRA=7 output.mp4
ffmpeg-normalizeで一括処理する
複数ファイルを正規化するなら、ffmpeg-normalize が便利だ。FFmpegのloudnormフィルタをラップしたPython CLIで、2パスをデフォルトで実行してくれる。
インストール
pip install ffmpeg-normalize
基本的な使い方
# 1ファイルを -16 LUFS に正規化(2パス、EBU R128)
ffmpeg-normalize input.mp4 -o output.mp4
# YouTube向け -14 LUFS
ffmpeg-normalize input.mp4 -o output.mp4 -t -14
# ディレクトリ内の全MP4を一括処理
ffmpeg-normalize *.mp4 -of normalized/ -ext mp4
プリセット(v1.36以降)
# ポッドキャスト(AESストリーミング規格)
ffmpeg-normalize input.wav -o output.wav --preset podcast
# 音楽(RMSベース)
ffmpeg-normalize input.wav -o output.wav --preset music
# ストリーミング動画
ffmpeg-normalize input.mp4 -o output.mp4 --preset streaming-video
アルバム正規化(v1.35以降)
トラック間の相対ラウドネスを保ちつつ、アルバム全体を目標レベルに揃える:
ffmpeg-normalize track1.wav track2.wav track3.wav -of album/ -ext wav --album
バッチ処理をPythonでさらにカスタマイズしたい場合は FFmpeg × Pythonバッチ処理入門 を参照してほしい。
他のフィルタとの違い
「loudnormとvolumeどっちを使えばいい?」— Stack Overflowやオーディオ系フォーラムで絶えず出る質問だ。FFmpegには音声調整用のフィルタがいくつかある。それぞれの使い分けを整理する。
| フィルタ | 方式 | 適する場面 | 特徴 |
|---|---|---|---|
| loudnorm | EBU R128知覚ラウドネス | 配信・放送・ポッドキャスト | 最も正確。内部で192kHzアップサンプリング |
| volume | 固定ゲイン | 単純な音量調整 | ラウドネス非考慮。クリップの可能性あり |
| dynaudnorm | チャンク単位の動的ゲイン | 会話・インタビュー | loudnormの約4倍高速。規格非準拠 |
| compand | ダイナミックレンジ圧縮 | 強い圧縮効果 | 歪みリスクあり。構文が複雑 |
volumeフィルタを使うべき場面
単純に音量を上げ下げするだけなら、volume の方がシンプルで速い。
# 6dB上げる
ffmpeg -i input.mp4 -af volume=6dB output.mp4
# 3dB下げる
ffmpeg -i input.mp4 -af volume=-3dB output.mp4
事前に volumedetect でピーク・平均音量を測定しておくと確実だ。
ffmpeg -i input.mp4 -af volumedetect -f null -
FFmpegの基本的な音声コマンドについては FFmpegの使い方とコマンド一覧 の音声セクションも参考にしてほしい。
dynaudnormを使うべき場面
dynaudnorm はチャンクごと(デフォルト約8秒)にゲインを調整する。loudnormより高速で、小さい声を聞き取りやすくするのに向いているが、規格には準拠しない。
ffmpeg -i input.mp4 -af dynaudnorm=f=200:g=5 output.mp4
f= フレーム長(ミリ秒、デフォルト500)g= ガウシアンフィルタサイズ(デフォルト31)
よくある質問(FAQ)
Q: LUFSとLKFSの違いは?
同じ測定値。LUFS(Loudness Units Full Scale)はEBUの用語、LKFS(Loudness K-weighted Full Scale)はITUの用語。-14 LUFS = -14 LKFS。
Q: 正規化後に音が小さくなるのはなぜ?
ラウドネス正規化はピークではなく知覚ラウドネスを基準にする。ダイナミックレンジが狭い(圧縮された)音源はピークが高くても知覚ラウドネスは低い。正規化後にピークが下がっても、知覚上の音量は目標値に揃っている。
Q: エンコード前と後、どちらで正規化すべき?
エンコード前。非可逆圧縮後にゲインをかけると劣化した音声にさらに処理を重ねることになる。可能な限り高品質なソースを正規化してからエンコードしよう。
Q: 映像を再エンコードせずに音声だけ正規化できる?
できる。映像はコピー、音声だけ再エンコードすればいい:
ffmpeg -i input.mp4 -c:v copy -af loudnorm=I=-16:TP=-1.5:LRA=11 -c:a aac -b:a 192k output.mp4
Q: 出力のサンプルレートは何にすべき?
動画なら48kHz。音楽のみならソースに合わせる。loudnormは内部で192kHzにアップサンプリングするため、-ar 48000 を指定しないと意図しないサンプルレートになることがある。
Q: サラウンド音声(5.1/7.1)にも使える?
使える。ただしモノラルコンテンツがステレオコンテナに入っている場合は dual_mono=true を設定すること。シングルチャンネル再生を考慮した測定になる。
Q: 結果を検証するには?
出力ファイルに対してloudnormを測定モードで実行する:
ffmpeg -i output.mp4 -af loudnorm=print_format=json -f null -
input_i が目標値と一致していれば正規化は成功。±0.5 LUの誤差は正常範囲だ。
まとめ
よく使う正規化コマンドの一覧:
| やりたいこと | コマンドの核 |
|---|---|
| -16 LUFSにサクッと正規化 | loudnorm=I=-16:TP=-1.5:LRA=11 |
| YouTube/Spotify(-14 LUFS) | loudnorm=I=-14:TP=-1.5:LRA=11 |
| Apple Podcasts(-16 LUFS) | loudnorm=I=-16:TP=-1:LRA=11 |
| 放送(EBU R128) | loudnorm=I=-23:TP=-1:LRA=7 |
| 測定のみ(出力なし) | loudnorm=print_format=json -f null - |
| 映像保持+音声正規化 | -c:v copy -af loudnorm=... -c:a aac |
| 一括正規化 | ffmpeg-normalize *.mp4 -of out/ -ext mp4 |
loudnormフィルタは1パスで手軽に、2パスで精密に音声を正規化できる。大量ファイルを処理するなら ffmpeg-normalize が効率的だ。規格準拠が不要で単純に音量を上げ下げしたいだけなら volume フィルタで十分。
国内シェアNo.1のエックスサーバーが提供する高性能VPS
- NVMe SSD・AMD EPYC搭載の高速サーバー
- 2GBプラン 月額990円〜(3コア / 50GB SSD)
- 初期費用無料
関連記事: