
ffmpeg-normalize
CLIBatch-normalizes audio and video loudness to standards like EBU R128, with presets for podcasts, music and streaming video; handy for evening out course recordings, podcasts and videos before publishing. Needs FFmpeg and Python 3.10+.
ffmpeg-normalize
A utility for batch-normalizing audio using ffmpeg.
This program normalizes media files to a certain loudness level using the EBU R128 loudness normalization procedure. It can also perform RMS-based normalization (where the mean is lifted or attenuated), or peak normalization to a certain target level.
✨ Features
- EBU R128 loudness normalization — Two-pass by default, with an option for one-pass dynamic normalization
- RMS-based normalization — Adjust audio to a specific RMS level
- Peak normalization — Adjust audio to a specific peak level
- Selective audio stream normalization — Normalize specific audio streams or only default streams
- Skip files already at target — Avoid re-encoding files already within a threshold of the target level
- Before/after summary — Print a table of input and output levels and the applied gain for all files with
--print-summary - Self-documenting output — Optionally record the effective encoder settings as an
ENCODER_SETTINGStag - Video file support — Process video files while preserving video streams
- Docker support — Run via Docker container
- Python API — Use programmatically in your Python projects
- Shell completions — Available for bash, zsh, and fish
- Album Batch normalization – Process files jointly, preserving relative loudness
🚀 Quick Start
- Install a recent version of ffmpeg and Python 3.10 or higher
- Run
pip3 install ffmpeg-normalizeandffmpeg-normalize /path/to/your/file.mp4, alternatively installuvand runuvx ffmpeg-normalize /path/to/your/file.mp4 - Done! 🎧 (the normalized file will be called
normalized/file.mkv)
🆕 What's New
-
Version 1.42.0 can optionally write an
ENCODER_SETTINGStag on each normalized audio stream via--write-encoder-settings. The tag holds an ffmpeg-command-equivalent string — the audio codec, bitrate, sample rate and channels, plus the normalization filter including the measured loudnorm values — so a normalized file documents how it was produced. This is a Matroska/WebM convention and has no effect with--metadata-disable.Example:
ffmpeg-normalize input.wav -c:a libopus -b:a 128k --write-encoder-settings -o output.mkv -
Version 1.41.0 automatically picks the correct output audio codec for the output container, so you no longer need to specify
-c:a/--audio-codecunless you want to override the default. PCM is chosen for containers that support it; others will use teh default that ffmpeg picks. See the usage guide for details. -
Version 1.40.0 can optionally skip files that are already at the target level via
--threshold(e.g.--threshold 0.5, disabled by default). Such files are copied through unchanged instead of being re-encoded. The--print-statsoutput now includes a per-filestatus(normalized,skipped, orerror, plus anerrormessage on failure), and the exit code is non-zero if any file failed to process, so a script can tell what happened to each file.Example:
ffmpeg-normalize input.flac -nt peak -t 0 -c:a flac --print-stats -o output.flac -
Version 1.39.0 preserves the input bit depth by default when encoding to formats like FLAC, so 16-bit input stays 16-bit without needing
-e "-sample_fmt s16". Use--no-keep-bit-depthto opt out. It also adds--keep-mtimeto copy the input file's modification time to the output, which is useful for preserving when a track was added to a music library.Example:
ffmpeg-normalize input.flac -nt peak -t 0 -c:a flac --keep-mtime -o output.flac -
Version 1.38.0 writes the normalized output directly to the destination without using temporary files
-
Version 1.36.0 introduces presets with
--preset! Save and reuse your favorite normalization configurations for different use cases. Comes with three built-in presets:podcast(AES standard),music(RMS-based batch normalization), andstreaming-video(video content). Create custom presets too!Example:
ffmpeg-normalize input.mp3 --preset podcastapplies the podcast preset (EBU R128, -16 LUFS) to your file. Learn more in the presets guide.
-
Version 1.35.0 has batch/album normalization with
--batch. It preserves relative loudness between files! Perfect for music albums where you want to shift all tracks by the same amount.Example:
ffmpeg-normalize album/*.flac --batch -nt rms -t -20shifts the entire album so the average RMS is -20 dB, preserving the original relative loudness as mastered.
-
Version 1.34.0 brings selective audio stream normalization! You can now:
-
Normalize specific audio streams with
-as/--audio-streams(e.g.,-as 1,2to normalize only streams 1 and 2) -
Normalize only default audio streams with
--audio-default-only(useful for files with multiple language tracks) -
Keep other streams unchanged with
--keep-other-audio(copy non-selected streams without normalization)Example:
ffmpeg-normalize input.mkv -as 1 --keep-other-audionormalizes stream 1 and copies all other audio streams unchanged.
-
Other recent additions:
- Shell completions (v1.31.0) — Tab completion for bash, zsh, and fish shells. See the installation guide for setup instructions.
--lower-onlyoption — Prevent audio from increasing in loudness, only lower it if needed (works with all normalization types).
See the full changelog for all updates.
📓 Documentation
Check out our documentation for more info!
🤝 Contributors
The only reason this project exists in its current form is because @benjaoming's initial PRs. Thanks for everyone's support!
関連リソース

claude-code-video-toolkit
SkillA video production workspace for Claude Code: scripting, AI voiceover, music, generated visuals and Remotion rendering to MP4, with explainer and product-demo templates. The full workflow needs the cloned repo and Node.js 18+; AI generation needs your own cloud GPU (e.g. Modal's free tier).
digitalsamba/claude-code-video-toolkit2.3k
FFmpeg
CLICommand-line toolkit for transcoding, cutting, joining, frame extraction and streaming of audio and video, including ffmpeg, ffprobe and ffplay. A core dependency for agents handling media. The GitHub repo is the official mirror.
FFmpeg/FFmpeg65.3k
ffmpeg-skill
SkillLocal FFmpeg video editing skill: ask in plain language to cut and join clips, remove silence, reframe to vertical, add subtitles, normalize loudness and export to TikTok, Reels or YouTube specs, fully offline with no API key. Needs ffmpeg and Python 3; also usable as an MCP.
kajisho5/ffmpeg-skill2k
OpenMontage
SkillOpen-source agentic video production: open Claude Code or Codex in the cloned repo, describe the video, and the agent handles research, script, voiceover, footage, subtitles and editing, confirming storyboard and cost first. Needs Python, Node.js and FFmpeg; free assets work without API keys.
calesthio/OpenMontage68.8k
video-use
SkillBrowser Use's video editing skill: put raw footage in a folder and chat with Claude Code or Codex to get a finished cut, with filler words and pauses removed, color grading, burned-in subtitles, animations and per-cut self-checks. Needs ffmpeg, Python (uv) and an ElevenLabs API key.
browser-use/video-use29.1k
Vox Director
SkillFrom a single topic, the agent writes a storyboard, generates paper-cutout collage visuals, motion, narration, music and subtitles, and assembles a Vox-style explainer or ad with ffmpeg, checking with you on storyboard and style. Needs a prepaid Atlas Cloud API key, ffmpeg and Python.
Alisa0808/vox-director2.3k