惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
C
Check Point Blog
B
Blog RSS Feed
G
Google Developers Blog
H
Help Net Security
博客园 - Franky
Blog — PlanetScale
Blog — PlanetScale
H
Hackread – Cybersecurity News, Data Breaches, AI and More
量子位
Recent Announcements
Recent Announcements
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
DataBreaches.Net
小众软件
小众软件
T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
T
Tailwind CSS Blog
J
Java Code Geeks
MyScale Blog
MyScale Blog
雷峰网
雷峰网
有赞技术团队
有赞技术团队
博客园 - 聂微东

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How to Normalize Audio with FFmpeg (Volume, Loudnorm, and...
Javid Jamae · 2026-05-20 · via DEV Community

Javid Jamae

Originally published at ffmpeg-micro.com

FFmpeg audio normalization trips up even experienced developers. The loudnorm filter alone has 6 parameters, a two-pass workflow that requires parsing JSON from stderr, and behavior that changes depending on whether you feed it MP4, WAV, or MKV. Most guides skip the hard parts.

This post covers three approaches to fixing audio levels with FFmpeg: simple volume scaling, broadcast-standard loudnorm normalization (EBU R128), and a cloud API that handles it without installing anything.

Quick answer: normalize audio to -16 LUFS with FFmpeg

ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

This applies EBU R128 loudnorm normalization targeting -16 LUFS (the standard for streaming platforms). The -c:v copy flag passes video through untouched so only the audio gets re-encoded.

Approach 1: Simple volume adjustment with the volume filter

The volume filter is the simplest way to change audio levels. It multiplies every sample by a fixed factor.

Halve the volume:

ffmpeg -i input.mp4 -af "volume=0.5" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

Double the volume:

ffmpeg -i input.mp4 -af "volume=2.0" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

Adjust by decibels (more precise):

ffmpeg -i input.mp4 -af "volume=6dB" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

The volume filter is predictable but dumb. It doesn't analyze the source audio first, so you can easily clip loud sections or amplify noise in quiet ones. For consistent levels across multiple files, you need actual normalization.

Approach 2: EBU R128 normalization with loudnorm

The loudnorm filter implements the EBU R128 broadcast standard. Instead of blindly scaling amplitude, it measures perceived loudness (LUFS) and adjusts dynamically.

Single-pass normalization (good enough for most cases):

ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

What the parameters mean:

  • I=-16 sets the target integrated loudness to -16 LUFS. YouTube uses -14, Spotify uses -14, podcasts typically use -16 to -19.
  • TP=-1.5 sets the true peak ceiling to -1.5 dBTP. This prevents clipping on lossy codecs like AAC and MP3 that can overshoot 0 dB during decoding.
  • LRA=11 sets the loudness range to 11 LU. This controls how much dynamic range the output keeps.

Two-pass normalization (more accurate):

Pass 1 - Analyze and capture stats:

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

Enter fullscreen mode Exit fullscreen mode

Pass 2 - Apply the measured values:

ffmpeg -i input.mp4 -af "loudnorm=I=-16:TP=-1.5:LRA=11:measured_I=-19.6:measured_TP=-5.9:measured_LRA=0.6:measured_thresh=-29.6:offset=0.1:linear=true" -c:v copy output.mp4

Enter fullscreen mode Exit fullscreen mode

Which approach should you use?

Scenario Best approach Why
Quick fix on one file volume filter Simple, predictable, no analysis needed
Batch normalize for a platform loudnorm single-pass EBU R128 standard, good enough for streaming
Mastering or archival quality loudnorm two-pass Most accurate, preserves dynamics
Automated pipeline Cloud FFmpeg API No installation, scales with your workflow

Common pitfalls

Forgetting -c:v copy and re-encoding the entire video. Without it, FFmpeg re-encodes the video stream too. This takes 10-50x longer.

Using volume instead of loudnorm for batch processing. The volume filter applies the same gain to every file. loudnorm measures each file and targets a consistent output level.

Setting the true peak ceiling to 0 dBTP. Lossy codecs generate intersample peaks during decoding that can exceed the encoded peak by 1-3 dB.

Running loudnorm on already-normalized audio. Double-normalizing compresses dynamics further each pass. Check levels first.

FAQ

What LUFS level should I target for YouTube?
YouTube normalizes all audio to -14 LUFS. Targeting -14 means YouTube won't touch your audio. -16 is close enough that the difference is barely audible.

Can I normalize audio without re-encoding the video?
Yes. Use -c:v copy to pass the video stream through unchanged. Only the audio gets re-encoded.

What is the difference between loudnorm and dynaudnorm?
loudnorm targets a specific LUFS level per the EBU R128 standard. dynaudnorm adjusts volume frame-by-frame and can introduce pumping artifacts. For most use cases, loudnorm is the right choice.