32blogby Studio Mitsu

FFmpegで音声を正規化する方法【loudnorm完全ガイド】

FFmpegのloudnormフィルタで音声を正規化する方法を解説。1パス・2パスのEBU R128正規化、YouTube/Spotify等のLUFS基準、バッチ処理まで網羅。

by omitsu13 min read
FFmpegCLIaudionormalizationencodingcommands

当記事にはアフィリエイト広告が含まれています

目次

動画を繋いだら、あるクリップだけ音が小さくて別のクリップで爆音になった — そんな経験はないだろうか?音量のバラつきは動画制作で最も多い不満の一つで、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パス正規化(最もシンプル)

bash
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.07.0

1パスモードは ダイナミック(非線形)正規化 — AGCがリアルタイムにゲインを調整する。ファイル全体を読まずに処理できるので高速だが、2パスほどの精度はない。

ラウドネスを測定してから正規化する

正規化前に現在のラウドネスを確認するのは良い習慣だ。

bash
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json -f null -

出力されるJSONの読み方:

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_typelinear なら線形正規化、dynamic ならAGCが介入したことを示す。

2パス正規化で精度を上げる

2パス正規化は、まずファイル全体を測定し、その結果を使って正確な補正を行う。これにより リニア(線形)正規化 — ファイル全体に均一なゲインを適用し、元のダイナミクスを完全に保つことができる。

パス1: 測定

bash
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json -f null - 2>&1

JSON出力の input_iinput_tpinput_lrainput_threshtarget_offset をメモしておく。

パス2: 適用

bash
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を手作業でパースするのは面倒だ。以下のスクリプトで自動化できる。

bash
#!/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"

使い方:

bash
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 dBTPReplayGain方式
Apple Music-16 LUFS-1 dBTPSound Check機能
Apple Podcasts-16 LUFS-1 dBTPApple Musicと同基準
Amazon Music-14 LUFS-2 dBTP音量を下げるのみ(上げない)
TikTok約-14 LUFS-1 dBTP公式仕様なし、業界の通説
Instagram Reels約-14 LUFS-1 dBTPMetaがxHE-AACで管理
EBU R128(欧州放送)-23 LUFS-1 dBTP欧州放送基準
ARIB TR-B32(日本放送)-24 LKFS規定あり2012年運用開始。ARIB概要

出典: EBU Tech R128、各プラットフォーム開発者ドキュメント、業界測定値

すぐ使えるコマンド集

YouTube / Spotify / TikTok(-14 LUFS):

bash
ffmpeg -i input.mp4 -af loudnorm=I=-14:TP=-1.5:LRA=11 output.mp4

Apple Music / Podcasts(-16 LUFS):

bash
ffmpeg -i input.mp4 -af loudnorm=I=-16:TP=-1:LRA=11 output.mp4

放送(EBU R128、-23 LUFS):

bash
ffmpeg -i input.mp4 -af loudnorm=I=-23:TP=-1:LRA=7 output.mp4

ffmpeg-normalizeで一括処理する

複数ファイルを正規化するなら、ffmpeg-normalize が便利だ。FFmpegのloudnormフィルタをラップしたPython CLIで、2パスをデフォルトで実行してくれる。

インストール

bash
pip install ffmpeg-normalize

基本的な使い方

bash
# 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以降)

bash
# ポッドキャスト(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以降)

トラック間の相対ラウドネスを保ちつつ、アルバム全体を目標レベルに揃える:

bash
ffmpeg-normalize track1.wav track2.wav track3.wav -of album/ -ext wav --album

バッチ処理をPythonでさらにカスタマイズしたい場合は FFmpeg × Pythonバッチ処理入門 を参照してほしい。

他のフィルタとの違い

「loudnormとvolumeどっちを使えばいい?」— Stack Overflowやオーディオ系フォーラムで絶えず出る質問だ。FFmpegには音声調整用のフィルタがいくつかある。それぞれの使い分けを整理する。

フィルタ方式適する場面特徴
loudnormEBU R128知覚ラウドネス配信・放送・ポッドキャスト最も正確。内部で192kHzアップサンプリング
volume固定ゲイン単純な音量調整ラウドネス非考慮。クリップの可能性あり
dynaudnormチャンク単位の動的ゲイン会話・インタビューloudnormの約4倍高速。規格非準拠
compandダイナミックレンジ圧縮強い圧縮効果歪みリスクあり。構文が複雑

volumeフィルタを使うべき場面

単純に音量を上げ下げするだけなら、volume の方がシンプルで速い。

bash
# 6dB上げる
ffmpeg -i input.mp4 -af volume=6dB output.mp4

# 3dB下げる
ffmpeg -i input.mp4 -af volume=-3dB output.mp4

事前に volumedetect でピーク・平均音量を測定しておくと確実だ。

bash
ffmpeg -i input.mp4 -af volumedetect -f null -

FFmpegの基本的な音声コマンドについては FFmpegの使い方とコマンド一覧 の音声セクションも参考にしてほしい。

dynaudnormを使うべき場面

dynaudnorm はチャンクごと(デフォルト約8秒)にゲインを調整する。loudnormより高速で、小さい声を聞き取りやすくするのに向いているが、規格には準拠しない。

bash
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: 映像を再エンコードせずに音声だけ正規化できる?

できる。映像はコピー、音声だけ再エンコードすればいい:

bash
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を測定モードで実行する:

bash
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 フィルタで十分。

XServer VPS

国内シェアNo.1のエックスサーバーが提供する高性能VPS

  • NVMe SSD・AMD EPYC搭載の高速サーバー
  • 2GBプラン 月額990円〜(3コア / 50GB SSD)
  • 初期費用無料

関連記事: