MpegFlowBlogBack to home
← Recipes·Loudness normalize·audio operations

Loudness-normalize audio with FFmpeg (EBU R128, ATSC A/85)

Normalize audio loudness to broadcast targets — EBU R128 (-23 LUFS) for European broadcast, ATSC A/85 (-24 LUFS) for North America. Single-pass and two-pass loudnorm filter usage.

ByMpegFlow Engineering Team·FFmpeg recipe
·3 variants·May 9, 2026

When to use this

You loudness-normalize audio for broadcast delivery (EU broadcasters require EBU R128 compliance, NA broadcasters require ATSC A/85), multi-source content where different sources have different loudness (compilations, podcasts, news inserts), and any delivery context where viewers shouldn't reach for the volume knob between assets. Loudness normalization isn't the same as peak normalization — peak normalization equalizes the loudest sample, loudness normalization equalizes perceptual loudness across the whole asset using the LUFS standard. For broadcast you want loudness normalization.

Command variants

Single-pass EBU R128 (-23 LUFS, European broadcast)
ffmpeg -i input.mp4 \
  -af "loudnorm=I=-23:LRA=7:TP=-2" \
  -c:v copy \
  output.mp4

Good enough for most use cases. ~5-10% deviation from target. Audio re-encoded; video stream-copy.

Single-pass ATSC A/85 (-24 LUFS, North American broadcast)
ffmpeg -i input.mp4 \
  -af "loudnorm=I=-24:LRA=6:TP=-2" \
  -c:v copy \
  output.mp4

ATSC A/85 standard. Slightly tighter LRA than EBU.

Two-pass (broadcast-grade accuracy)
# Pass 1: measure
ffmpeg -i input.mp4 -af loudnorm=I=-23:LRA=7:TP=-2:print_format=json -f null -

# Output gives JSON with measured_I, measured_LRA, measured_TP, measured_thresh, target_offset.
# Use those values in pass 2:
ffmpeg -i input.mp4 \
  -af "loudnorm=I=-23:LRA=7:TP=-2:measured_I=-26.21:measured_LRA=8.5:measured_TP=-1.2:measured_thresh=-37.4:offset=0.05:linear=true" \
  -c:v copy \
  output.mp4

Production / broadcast delivery accuracy. ~1% deviation from target. Required for EBU R128 contractual delivery.

What each parameter does

  • I=-23 / I=-24

    Integrated loudness target in LUFS. -23 LUFS is EBU R128 (Europe), -24 LUFS is ATSC A/85 (North America). YouTube/Netflix/Spotify use different targets (-14 LUFS).

  • LRA=7

    Loudness Range. EBU R128 requires LRA ≤ 7 LU; ATSC A/85 requires LRA ≤ 6 LU. Limits the dynamic range to prevent fatigue.

  • TP=-2

    True peak ceiling in dBTP. -2 dBTP prevents inter-sample clipping that decoders / DACs introduce. -1 dBTP is acceptable for some use cases.

  • measured_*

    Pass-1 values fed into pass-2 for linear normalization. Required for two-pass mode.

  • linear=true

    Linear normalization mode (vs dynamic). Required for two-pass; preserves the original dynamic range while shifting the integrated loudness.

  • -c:v copy

    Stream-copy video. Loudness normalization is audio-only; never re-encode video as a side-effect.

What this outputs

Audio normalized to target LUFS with controlled true-peak. Single-pass deviates ~5-10% from target (good enough for streaming); two-pass deviates ~1% from target (required for broadcast contractual delivery). Video stream is unchanged.

Pitfalls

  1. Single-pass loudnorm is convenient but inaccurate. EBU R128 broadcast contracts often specify "Integrated Loudness within ±0.5 LU of -23 LUFS" — single-pass typically misses this. Always two-pass for contractual delivery.
  2. Wrong target for the platform: -23 LUFS for streaming feels too quiet (Spotify/YouTube/Netflix all use -14 LUFS). Match the target to the delivery platform, not the broadcast standard.
  3. Dynamic mode (default) compresses audio toward the target, changing the perceived sound. Linear mode preserves the dynamic but shifts the level. Production delivery typically wants linear.
  4. Inter-sample peaks vs sample peaks: TP measures inter-sample (true peak); standard peak meters measure sample peaks. -2 dBTP is more conservative than -2 dBFS sample peak.
  5. Loudnorm processes the entire file in memory for two-pass mode. Very long audio (>4 hours) may need chunked processing.
  6. Re-encoding video alongside audio normalization wastes compute. Always use -c:v copy.

At production scale

Audio normalization is fast at scale — typically 5-10% of the equivalent video re-encoding cost. Two-pass loudnorm doubles the audio processing time but is necessary for broadcast delivery. At >100K assets/month with broadcast-grade normalization, the audio processing cost is meaningful but still small relative to video compute. The pattern that scales: loudness-normalize once at the master encoding stage, stream-copy the audio to all subsequent renditions in the ABR ladder.

How MpegFlow handles this

MpegFlow models loudness normalization as a parameterized DAG stage with the LUFS target as a per-job input. The two-pass measure-then-correct pattern is wrapped as a single stage that the platform manages internally. Audit log records the measured-I and target-I values so contractual delivery can be verified.

Topics
  • FFmpeg
  • audio
  • loudness
  • ebu-r128
  • Broadcast
  • audio-operations
See also
  • Recipe
    Extract Audio From Video
  • Architecture
    Broadcast Grade Vod Transcoding
Running this at scale?

Get the orchestration layer for free.

The loudness normalize command above is the easy part. The queue, retries, audit trail, encoder-version pinning, and multi-tenant security around it are what every video team rebuilds from scratch. We did the rebuild — design partners run it free during beta.

Apply More recipes
© 2026 MpegFlow, Inc. · Trust & complianceAll systems nominal·StatusPrivacy