How to Use FFmpeg Loudnorm for EBU R128

This guide explains how to use the FFmpeg loudnorm filter to achieve EBU R128 loudness normalization for your audio and video files. You will learn the difference between one-pass and two-pass normalization, the key parameters of the filter, and the exact command-line syntax required to target the standard -23 LUFS integration limit.

Understanding EBU R128 Targets

The EBU R128 broadcasting standard regulates audio delivery using specific loudness metrics rather than peak levels. The primary targets for standard compliance are: * Integrated Loudness (I): -23.0 LUFS (Loudness Units Full Scale) * Loudness Range (LRA): 18.0 LU * Maximum True Peak (TP): -1.0 dBTP (Decibels Relative to Full Scale)

The loudnorm filter in FFmpeg uses these parameters to dynamically adjust your audio to meet these standards.

One-Pass Loudness Normalization

One-pass normalization is fast and suitable for live streaming or quick processing. It estimates the loudness of the incoming audio on the fly.

To perform a one-pass normalization to EBU R128 standards, use the following command:

ffmpeg -i input.mp4 -filter:a loudnorm=I=-23:LRA=18:TP=-1.0 -c:v copy output.mp4

In this command: * I=-23 sets the target integrated loudness to -23 LUFS. * LRA=18 sets the target loudness range to 18 LU. * TP=-1.0 sets the maximum true peak to -1.0 dBTP. * -c:v copy copies the video stream without re-encoding, saving time.

For strict EBU R128 compliance, a two-pass approach is highly recommended. The first pass analyzes the entire audio file to gather precise statistics, and the second pass applies the normalization using those statistics to prevent compression artifacts or clipping.

Pass 1: Analyze the Audio

Run the analysis command to output the loudness metadata in JSON format:

ffmpeg -i input.mp4 -filter:a loudnorm=I=-23:LRA=18:TP=-1.0:print_format=json -f null -

This command will print a JSON block at the end of the console output that looks like this:

{
    "input_i" : "-15.30",
    "input_lra" : "11.20",
    "input_tp" : "0.50",
    "input_thresh" : "-25.80",
    "output_i" : "-23.00",
    "output_lra" : "10.10",
    "output_tp" : "-1.00",
    "output_thresh" : "-33.20",
    "normalization_type" : "dynamic",
    "target_offset" : "0.00"
}

Pass 2: Apply the Normalization

Copy the input_* values from the JSON output and plug them into the second pass command using the corresponding measured_* parameters:

ffmpeg -i input.mp4 -filter:a loudnorm=I=-23:LRA=18:TP=-1.0:measured_I=-15.30:measured_LRA=11.20:measured_TP=0.50:measured_thresh=-25.80:linear=true:print_format=summary -c:v copy output.mp4