ffmpeg-normalize 1.28.1__tar.gz → 1.28.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/CHANGELOG.md +18 -0
  2. {ffmpeg-normalize-1.28.1/ffmpeg_normalize.egg-info → ffmpeg-normalize-1.28.3}/PKG-INFO +99 -48
  3. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/README.md +80 -47
  4. ffmpeg-normalize-1.28.3/ffmpeg_normalize/_version.py +1 -0
  5. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3/ffmpeg_normalize.egg-info}/PKG-INFO +99 -48
  6. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/requires.txt +3 -1
  7. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/setup.py +1 -1
  8. ffmpeg-normalize-1.28.1/ffmpeg_normalize/_version.py +0 -1
  9. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/LICENSE +0 -0
  10. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/__init__.py +0 -0
  11. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/__main__.py +0 -0
  12. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_cmd_utils.py +0 -0
  13. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_errors.py +0 -0
  14. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_ffmpeg_normalize.py +0 -0
  15. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_logger.py +0 -0
  16. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_media_file.py +0 -0
  17. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/_streams.py +0 -0
  18. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize/py.typed +0 -0
  19. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/SOURCES.txt +0 -0
  20. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/dependency_links.txt +0 -0
  21. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/entry_points.txt +0 -0
  22. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/not-zip-safe +0 -0
  23. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/ffmpeg_normalize.egg-info/top_level.txt +0 -0
  24. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/setup.cfg +0 -0
  25. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/test/out.mp4 +0 -0
  26. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/test/test.mp4 +0 -0
  27. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/test/test.py +0 -0
  28. {ffmpeg-normalize-1.28.1 → ffmpeg-normalize-1.28.3}/test/test.wav +0 -0
@@ -1,6 +1,24 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v1.28.3 (2024-08-16)
5
+
6
+ * Make colorama dependency windows-only.
7
+
8
+ * Update.
9
+
10
+ * Update badges.
11
+
12
+ * Docs: add @kanjieater as a contributor.
13
+
14
+
15
+ ## v1.28.2 (2024-06-22)
16
+
17
+ * Provide an entrypoint for the Docker image.
18
+
19
+ * Add docker push (#261)
20
+
21
+
4
22
  ## v1.28.1 (2024-05-15)
5
23
 
6
24
  * Fix assignment of audio statistics, fixes #257.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ffmpeg-normalize
3
- Version: 1.28.1
3
+ Version: 1.28.3
4
4
  Summary: Normalize audio via ffmpeg
5
5
  Home-page: https://github.com/slhck/ffmpeg-normalize
6
6
  Author: Werner Robitza
@@ -25,13 +25,13 @@ License-File: LICENSE
25
25
 
26
26
  # ffmpeg-normalize
27
27
 
28
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
29
- [![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
30
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
31
-
32
28
  [![PyPI version](https://img.shields.io/pypi/v/ffmpeg-normalize.svg)](https://pypi.org/project/ffmpeg-normalize)
29
+ ![Docker Image Version](https://img.shields.io/docker/v/slhck/ffmpeg-normalize?sort=semver&label=Docker%20image)
30
+ ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/slhck/ffmpeg-normalize/python-package.yml)
33
31
 
34
- [![Python package](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml)
32
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
33
+ [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-)
34
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
35
35
 
36
36
  A utility for batch-normalizing audio using ffmpeg.
37
37
 
@@ -53,9 +53,9 @@ Read on for more info.
53
53
  - [Requirements](#requirements)
54
54
  - [ffmpeg](#ffmpeg)
55
55
  - [Installation](#installation)
56
- - [Docker Build](#docker-build)
57
- - [Usage](#usage)
58
- - [Description](#description)
56
+ - [Usage with Docker](#usage-with-docker)
57
+ - [High LeveL Introduction](#high-level-introduction)
58
+ - [Basic Usage](#basic-usage)
59
59
  - [Examples](#examples)
60
60
  - [Detailed Options](#detailed-options)
61
61
  - [File Input/Output](#file-inputoutput)
@@ -68,10 +68,11 @@ Read on for more info.
68
68
  - [Environment Variables](#environment-variables)
69
69
  - [API](#api)
70
70
  - [FAQ](#faq)
71
+ - [What options should I choose for the EBU R128 filter? What is linear and dynamic mode?](#what-options-should-i-choose-for-the-ebu-r128-filter-what-is-linear-and-dynamic-mode)
71
72
  - [The program doesn't work because the "loudnorm" filter can't be found](#the-program-doesnt-work-because-the-loudnorm-filter-cant-be-found)
72
73
  - [Should I use this to normalize my music collection?](#should-i-use-this-to-normalize-my-music-collection)
73
74
  - [Why are my output files MKV?](#why-are-my-output-files-mkv)
74
- - ["Could not write header for output file" error](#could-not-write-header-for-output-file-error)
75
+ - [I get a "Could not write header for output file" error](#i-get-a-could-not-write-header-for-output-file-error)
75
76
  - [The conversion does not work and I get a cryptic ffmpeg error!](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error)
76
77
  - [What are the different normalization algorithms?](#what-are-the-different-normalization-algorithms)
77
78
  - [Couldn't I just run `loudnorm` with ffmpeg?](#couldnt-i-just-run-loudnorm-with-ffmpeg)
@@ -86,7 +87,7 @@ Read on for more info.
86
87
 
87
88
  ## Requirements
88
89
 
89
- You need Python 3.8 or higher.
90
+ You need Python 3.8 or higher, and ffmpeg.
90
91
 
91
92
  ### ffmpeg
92
93
 
@@ -125,74 +126,61 @@ pip3 install ffmpeg-normalize
125
126
 
126
127
  Or download this repository, then run `pip3 install .`.
127
128
 
128
- ## Docker Build
129
- Download this repository and run
129
+ To later upgrade to the latest version, run `pip3 install --upgrade ffmpeg-normalize`.
130
130
 
131
- ```
132
- docker build -t ffmpeg-normalize .
133
- ```
131
+ ## Usage with Docker
134
132
 
135
- Run using Windows Powershell or Linux:
136
- ```
137
- docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
138
- ```
139
- This will mount your current folder to the /tmp directory inside the container
133
+ You can use the pre-built image from Docker Hub:
140
134
 
141
- Note: The container will run in interactive mode.
135
+ ```bash
136
+ docker run -v "$(pwd):/tmp" -it slhck/ffmpeg-normalize
137
+ ```
142
138
 
143
- Example Usage:
139
+ Alternatively, download this repository and run
144
140
 
145
- ```
146
- PS C:\yonkers> docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
147
- / # cd /tmp
148
- /tmp # ls
149
- 01. Goblin.mp3
150
- /tmp # ffmpeg-normalize "01. Goblin.mp3" -f -c:a libmp3lame -b:a 320k --target-level -13 --output "01. Goblin normalized.mp3"
151
- WARNING: The chosen output extension mp3 does not support video/cover art. It will be disabled.
152
- /tmp # ls
153
- 01. Goblin normalized.mp3
154
- 01. Goblin.mp3
141
+ ```bash
142
+ docker build -t ffmpeg-normalize .
155
143
  ```
156
144
 
157
- ## Usage
145
+ Then run the container with:
158
146
 
159
147
  ```bash
160
- ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
148
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize
161
149
  ```
162
150
 
163
- Example:
151
+ This will mount your current directory to the `/tmp` directory inside the container. Everything else works the same way as if you had installed the program locally. For example, to normalize a file:
164
152
 
165
153
  ```bash
166
- ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
154
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /tmp/yourfile.mp4 -o /tmp/yourfile-normalized.wav
167
155
  ```
168
156
 
169
- For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
157
+ You will then find the normalized file in your current directory.
170
158
 
171
- ## Description
159
+ ## High LeveL Introduction
172
160
 
173
161
  Please read this section for a high level introduction.
174
162
 
175
163
  **What does the program do?**
176
164
 
177
- The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume.
165
+ The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume according to the EBU R128 standard. This is done by analyzing the audio streams and applying a filter to bring them to a target level. Under the hood, the program uses ffmpeg's `loudnorm` filter to do this.
178
166
 
179
167
  **How do I specify the input?**
180
168
 
181
- Just give the program one or more input files as arguments. It works with most media files.
169
+ Just give the program one or more input files as arguments. It works with most media files, including video files.
182
170
 
183
171
  **How do I specify the output?**
184
172
 
185
- You can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
173
+ You don't have to specify an output file name (the default is `normalized/<input>.mkv`), but if you want to override it, you can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
186
174
 
187
175
  Example:
188
176
 
189
- ```
190
- ffmpeg-normalize 1.wav 2.wav -o 1n.wav 2n.wav
177
+ ```bash
178
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.wav 2-normalized.wav
191
179
  ```
192
180
 
193
- If you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`.
181
+ Note that if you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`. The reason for choosing the MKV container is that it can handle almost any codec combination.
194
182
 
195
- Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`.
183
+ Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`. However, you need to make sure that the container supports the codecs used for the output (see below).
196
184
 
197
185
  **What will get normalized?**
198
186
 
@@ -200,7 +188,7 @@ By default, all streams from the input file will be written to the output file.
200
188
 
201
189
  **How will the normalization be done?**
202
190
 
203
- The normalization will be performed with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
191
+ The normalization will be performed according to the EBU R128 algorithm with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
204
192
 
205
193
  **What codec is chosen?**
206
194
 
@@ -208,6 +196,22 @@ The default audio encoding method is uncompressed PCM (`pcm_s16le`) to avoid int
208
196
 
209
197
  Some containers (like MP4) also cannot handle PCM audio. If you want to use such containers and/or keep the file size down, use `-c:a` and specify an audio codec (e.g., `-c:a aac` for ffmpeg's built-in AAC encoder).
210
198
 
199
+ ## Basic Usage
200
+
201
+ Supply one or more input files, and optionally, output file names:
202
+
203
+ ```bash
204
+ ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
205
+ ```
206
+
207
+ Example:
208
+
209
+ ```bash
210
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
211
+ ```
212
+
213
+ For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
214
+
211
215
  ## Examples
212
216
 
213
217
  [Read the examples on the wiki.](https://github.com/slhck/ffmpeg-normalize/wiki/examples)
@@ -398,6 +402,32 @@ For more information see the [API documentation](https://htmlpreview.github.io/?
398
402
 
399
403
  ## FAQ
400
404
 
405
+ ### What options should I choose for the EBU R128 filter? What is linear and dynamic mode?
406
+
407
+ EBU R128 is a method for normalizing audio loudness across different tracks or programs. It works by analyzing the audio content and adjusting it to meet specific loudness targets. The main components are:
408
+
409
+ * Integrated Loudness (I): The overall loudness of the entire audio.
410
+ * Loudness Range (LRA): The variation in loudness over time.
411
+ * True Peak (TP): The maximum level of the audio signal.
412
+
413
+ The normalization process involves measuring these values (input) and then applying gain adjustments to meet target levels (output), typically -23 LUFS for integrated loudness. You can also specify a target loudness range (LRA) and true peak level (TP).
414
+
415
+ **Linear mode** applies a constant gain adjustment across the entire audio file. This is generally preferred because:
416
+
417
+ * It preserves the original dynamic range of the audio.
418
+ * It maintains the relative loudness between different parts of the audio.
419
+ * It avoids potential artifacts or pumping effects that can occur with dynamic processing.
420
+
421
+ **Dynamic mode**, on the other hand, can change the volume dynamically throughout the file. While this can achieve more consistent loudness, it may alter the original artistic intent and potentially introduce audible artifacts (possibly due to some bugs in the ffmpeg filter).
422
+
423
+ For most cases, linear mode is recommended. Dynamic mode should only be used when linear mode is not suitable or when a specific effect is desired. In some cases, `loudnorm` will still fall back to dynamic mode, and a warning will be printed to the console. Here's when this can happen:
424
+
425
+ * When the input loudness range (LRA) is larger than the target loudness range: If the input file has a loudness range that exceeds the specified loudness range target, the loudnorm filter will automatically switch to dynamic mode. This is because linear normalization alone cannot reduce the loudness range without dynamic processing (limiting). The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target.
426
+
427
+ * When the required gain adjustment to meet the integrated loudness target would result in the true peak exceeding the specified true peak limit. This is because linear processing alone cannot reduce peaks without affecting the entire signal. For example, if a file needs to be amplified by 6 dB to reach the target integrated loudness, but doing so would push the true peak above the specified limit, the filter might switch to dynamic mode to handle this situation. If your content allows for it, you can increase the true peak target to give more headroom for linear processing. If you're consistently running into true peak issues, you might also consider lowering your target integrated loudness level.
428
+
429
+ At this time, the `loudnorm` filter in ffmpeg does not provide a way to force linear mode when the input loudness range exceeds the target or when the true peak would be exceeded. The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target, but it will not force linear mode in all cases. We are working on a solution to handle this automatically!
430
+
401
431
  ### The program doesn't work because the "loudnorm" filter can't be found
402
432
 
403
433
  Make sure you run a recent ffmpeg version and that `loudnorm` is part of the output when you run `ffmpeg -filters`. Many distributions package outdated ffmpeg versions, or (even worse), Libav's `ffmpeg` disguising as a real `ffmpeg` from the FFmpeg project.
@@ -410,13 +440,15 @@ If you have to use an outdated ffmpeg version, you can only use `rms` or `peak`
410
440
 
411
441
  ### Should I use this to normalize my music collection?
412
442
 
443
+ Generally, no.
444
+
413
445
  When you run `ffmpeg-normalize` and re-encode files with MP3 or AAC, you will inevitably introduce [generation loss](https://en.wikipedia.org/wiki/Generation_loss). Therefore, I do not recommend running this on your precious music collection, unless you have a backup of the originals or accept potential quality reduction. If you just want to normalize the subjective volume of the files without changing the actual content, consider using [MP3Gain](http://mp3gain.sourceforge.net/) and [aacgain](http://aacgain.altosdesign.com/).
414
446
 
415
447
  ### Why are my output files MKV?
416
448
 
417
449
  I chose MKV as a default output container since it handles almost every possible combination of audio, video, and subtitle codecs. If you know which audio/video codec you want, and which container is supported, use the output options to specify the encoder and output file name manually.
418
450
 
419
- ### "Could not write header for output file" error
451
+ ### I get a "Could not write header for output file" error
420
452
 
421
453
  See the [next section](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error).
422
454
 
@@ -512,6 +544,7 @@ If you found this program useful and feel like giving back, feel free to send a
512
544
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sian1468"><img src="https://avatars.githubusercontent.com/u/58017832?v=4?s=100" width="100px;" alt="sian1468"/><br /><sub><b>sian1468</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=sian1468" title="Tests">⚠️</a></td>
513
545
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/psavva"><img src="https://avatars.githubusercontent.com/u/1454758?v=4?s=100" width="100px;" alt="Panayiotis Savva"/><br /><sub><b>Panayiotis Savva</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=psavva" title="Code">💻</a></td>
514
546
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/HighMans"><img src="https://avatars.githubusercontent.com/u/42877729?v=4?s=100" width="100px;" alt="HighMans"/><br /><sub><b>HighMans</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=HighMans" title="Code">💻</a></td>
547
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/kanjieater"><img src="https://avatars.githubusercontent.com/u/32607317?v=4?s=100" width="100px;" alt="kanjieater"/><br /><sub><b>kanjieater</b></sub></a><br /><a href="#ideas-kanjieater" title="Ideas, Planning, & Feedback">🤔</a></td>
515
548
  </tr>
516
549
  </tbody>
517
550
  <tfoot>
@@ -559,6 +592,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
559
592
  # Changelog
560
593
 
561
594
 
595
+ ## v1.28.3 (2024-08-16)
596
+
597
+ * Make colorama dependency windows-only.
598
+
599
+ * Update.
600
+
601
+ * Update badges.
602
+
603
+ * Docs: add @kanjieater as a contributor.
604
+
605
+
606
+ ## v1.28.2 (2024-06-22)
607
+
608
+ * Provide an entrypoint for the Docker image.
609
+
610
+ * Add docker push (#261)
611
+
612
+
562
613
  ## v1.28.1 (2024-05-15)
563
614
 
564
615
  * Fix assignment of audio statistics, fixes #257.
@@ -1,12 +1,12 @@
1
1
  # ffmpeg-normalize
2
2
 
3
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
4
- [![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
5
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
6
-
7
3
  [![PyPI version](https://img.shields.io/pypi/v/ffmpeg-normalize.svg)](https://pypi.org/project/ffmpeg-normalize)
4
+ ![Docker Image Version](https://img.shields.io/docker/v/slhck/ffmpeg-normalize?sort=semver&label=Docker%20image)
5
+ ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/slhck/ffmpeg-normalize/python-package.yml)
8
6
 
9
- [![Python package](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml)
7
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
8
+ [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-)
9
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
10
10
 
11
11
  A utility for batch-normalizing audio using ffmpeg.
12
12
 
@@ -28,9 +28,9 @@ Read on for more info.
28
28
  - [Requirements](#requirements)
29
29
  - [ffmpeg](#ffmpeg)
30
30
  - [Installation](#installation)
31
- - [Docker Build](#docker-build)
32
- - [Usage](#usage)
33
- - [Description](#description)
31
+ - [Usage with Docker](#usage-with-docker)
32
+ - [High LeveL Introduction](#high-level-introduction)
33
+ - [Basic Usage](#basic-usage)
34
34
  - [Examples](#examples)
35
35
  - [Detailed Options](#detailed-options)
36
36
  - [File Input/Output](#file-inputoutput)
@@ -43,10 +43,11 @@ Read on for more info.
43
43
  - [Environment Variables](#environment-variables)
44
44
  - [API](#api)
45
45
  - [FAQ](#faq)
46
+ - [What options should I choose for the EBU R128 filter? What is linear and dynamic mode?](#what-options-should-i-choose-for-the-ebu-r128-filter-what-is-linear-and-dynamic-mode)
46
47
  - [The program doesn't work because the "loudnorm" filter can't be found](#the-program-doesnt-work-because-the-loudnorm-filter-cant-be-found)
47
48
  - [Should I use this to normalize my music collection?](#should-i-use-this-to-normalize-my-music-collection)
48
49
  - [Why are my output files MKV?](#why-are-my-output-files-mkv)
49
- - ["Could not write header for output file" error](#could-not-write-header-for-output-file-error)
50
+ - [I get a "Could not write header for output file" error](#i-get-a-could-not-write-header-for-output-file-error)
50
51
  - [The conversion does not work and I get a cryptic ffmpeg error!](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error)
51
52
  - [What are the different normalization algorithms?](#what-are-the-different-normalization-algorithms)
52
53
  - [Couldn't I just run `loudnorm` with ffmpeg?](#couldnt-i-just-run-loudnorm-with-ffmpeg)
@@ -61,7 +62,7 @@ Read on for more info.
61
62
 
62
63
  ## Requirements
63
64
 
64
- You need Python 3.8 or higher.
65
+ You need Python 3.8 or higher, and ffmpeg.
65
66
 
66
67
  ### ffmpeg
67
68
 
@@ -100,74 +101,61 @@ pip3 install ffmpeg-normalize
100
101
 
101
102
  Or download this repository, then run `pip3 install .`.
102
103
 
103
- ## Docker Build
104
- Download this repository and run
104
+ To later upgrade to the latest version, run `pip3 install --upgrade ffmpeg-normalize`.
105
105
 
106
- ```
107
- docker build -t ffmpeg-normalize .
108
- ```
106
+ ## Usage with Docker
109
107
 
110
- Run using Windows Powershell or Linux:
111
- ```
112
- docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
113
- ```
114
- This will mount your current folder to the /tmp directory inside the container
108
+ You can use the pre-built image from Docker Hub:
115
109
 
116
- Note: The container will run in interactive mode.
110
+ ```bash
111
+ docker run -v "$(pwd):/tmp" -it slhck/ffmpeg-normalize
112
+ ```
117
113
 
118
- Example Usage:
114
+ Alternatively, download this repository and run
119
115
 
120
- ```
121
- PS C:\yonkers> docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
122
- / # cd /tmp
123
- /tmp # ls
124
- 01. Goblin.mp3
125
- /tmp # ffmpeg-normalize "01. Goblin.mp3" -f -c:a libmp3lame -b:a 320k --target-level -13 --output "01. Goblin normalized.mp3"
126
- WARNING: The chosen output extension mp3 does not support video/cover art. It will be disabled.
127
- /tmp # ls
128
- 01. Goblin normalized.mp3
129
- 01. Goblin.mp3
116
+ ```bash
117
+ docker build -t ffmpeg-normalize .
130
118
  ```
131
119
 
132
- ## Usage
120
+ Then run the container with:
133
121
 
134
122
  ```bash
135
- ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
123
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize
136
124
  ```
137
125
 
138
- Example:
126
+ This will mount your current directory to the `/tmp` directory inside the container. Everything else works the same way as if you had installed the program locally. For example, to normalize a file:
139
127
 
140
128
  ```bash
141
- ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
129
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /tmp/yourfile.mp4 -o /tmp/yourfile-normalized.wav
142
130
  ```
143
131
 
144
- For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
132
+ You will then find the normalized file in your current directory.
145
133
 
146
- ## Description
134
+ ## High LeveL Introduction
147
135
 
148
136
  Please read this section for a high level introduction.
149
137
 
150
138
  **What does the program do?**
151
139
 
152
- The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume.
140
+ The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume according to the EBU R128 standard. This is done by analyzing the audio streams and applying a filter to bring them to a target level. Under the hood, the program uses ffmpeg's `loudnorm` filter to do this.
153
141
 
154
142
  **How do I specify the input?**
155
143
 
156
- Just give the program one or more input files as arguments. It works with most media files.
144
+ Just give the program one or more input files as arguments. It works with most media files, including video files.
157
145
 
158
146
  **How do I specify the output?**
159
147
 
160
- You can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
148
+ You don't have to specify an output file name (the default is `normalized/<input>.mkv`), but if you want to override it, you can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
161
149
 
162
150
  Example:
163
151
 
164
- ```
165
- ffmpeg-normalize 1.wav 2.wav -o 1n.wav 2n.wav
152
+ ```bash
153
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.wav 2-normalized.wav
166
154
  ```
167
155
 
168
- If you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`.
156
+ Note that if you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`. The reason for choosing the MKV container is that it can handle almost any codec combination.
169
157
 
170
- Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`.
158
+ Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`. However, you need to make sure that the container supports the codecs used for the output (see below).
171
159
 
172
160
  **What will get normalized?**
173
161
 
@@ -175,7 +163,7 @@ By default, all streams from the input file will be written to the output file.
175
163
 
176
164
  **How will the normalization be done?**
177
165
 
178
- The normalization will be performed with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
166
+ The normalization will be performed according to the EBU R128 algorithm with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
179
167
 
180
168
  **What codec is chosen?**
181
169
 
@@ -183,6 +171,22 @@ The default audio encoding method is uncompressed PCM (`pcm_s16le`) to avoid int
183
171
 
184
172
  Some containers (like MP4) also cannot handle PCM audio. If you want to use such containers and/or keep the file size down, use `-c:a` and specify an audio codec (e.g., `-c:a aac` for ffmpeg's built-in AAC encoder).
185
173
 
174
+ ## Basic Usage
175
+
176
+ Supply one or more input files, and optionally, output file names:
177
+
178
+ ```bash
179
+ ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
180
+ ```
181
+
182
+ Example:
183
+
184
+ ```bash
185
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
186
+ ```
187
+
188
+ For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
189
+
186
190
  ## Examples
187
191
 
188
192
  [Read the examples on the wiki.](https://github.com/slhck/ffmpeg-normalize/wiki/examples)
@@ -373,6 +377,32 @@ For more information see the [API documentation](https://htmlpreview.github.io/?
373
377
 
374
378
  ## FAQ
375
379
 
380
+ ### What options should I choose for the EBU R128 filter? What is linear and dynamic mode?
381
+
382
+ EBU R128 is a method for normalizing audio loudness across different tracks or programs. It works by analyzing the audio content and adjusting it to meet specific loudness targets. The main components are:
383
+
384
+ * Integrated Loudness (I): The overall loudness of the entire audio.
385
+ * Loudness Range (LRA): The variation in loudness over time.
386
+ * True Peak (TP): The maximum level of the audio signal.
387
+
388
+ The normalization process involves measuring these values (input) and then applying gain adjustments to meet target levels (output), typically -23 LUFS for integrated loudness. You can also specify a target loudness range (LRA) and true peak level (TP).
389
+
390
+ **Linear mode** applies a constant gain adjustment across the entire audio file. This is generally preferred because:
391
+
392
+ * It preserves the original dynamic range of the audio.
393
+ * It maintains the relative loudness between different parts of the audio.
394
+ * It avoids potential artifacts or pumping effects that can occur with dynamic processing.
395
+
396
+ **Dynamic mode**, on the other hand, can change the volume dynamically throughout the file. While this can achieve more consistent loudness, it may alter the original artistic intent and potentially introduce audible artifacts (possibly due to some bugs in the ffmpeg filter).
397
+
398
+ For most cases, linear mode is recommended. Dynamic mode should only be used when linear mode is not suitable or when a specific effect is desired. In some cases, `loudnorm` will still fall back to dynamic mode, and a warning will be printed to the console. Here's when this can happen:
399
+
400
+ * When the input loudness range (LRA) is larger than the target loudness range: If the input file has a loudness range that exceeds the specified loudness range target, the loudnorm filter will automatically switch to dynamic mode. This is because linear normalization alone cannot reduce the loudness range without dynamic processing (limiting). The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target.
401
+
402
+ * When the required gain adjustment to meet the integrated loudness target would result in the true peak exceeding the specified true peak limit. This is because linear processing alone cannot reduce peaks without affecting the entire signal. For example, if a file needs to be amplified by 6 dB to reach the target integrated loudness, but doing so would push the true peak above the specified limit, the filter might switch to dynamic mode to handle this situation. If your content allows for it, you can increase the true peak target to give more headroom for linear processing. If you're consistently running into true peak issues, you might also consider lowering your target integrated loudness level.
403
+
404
+ At this time, the `loudnorm` filter in ffmpeg does not provide a way to force linear mode when the input loudness range exceeds the target or when the true peak would be exceeded. The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target, but it will not force linear mode in all cases. We are working on a solution to handle this automatically!
405
+
376
406
  ### The program doesn't work because the "loudnorm" filter can't be found
377
407
 
378
408
  Make sure you run a recent ffmpeg version and that `loudnorm` is part of the output when you run `ffmpeg -filters`. Many distributions package outdated ffmpeg versions, or (even worse), Libav's `ffmpeg` disguising as a real `ffmpeg` from the FFmpeg project.
@@ -385,13 +415,15 @@ If you have to use an outdated ffmpeg version, you can only use `rms` or `peak`
385
415
 
386
416
  ### Should I use this to normalize my music collection?
387
417
 
418
+ Generally, no.
419
+
388
420
  When you run `ffmpeg-normalize` and re-encode files with MP3 or AAC, you will inevitably introduce [generation loss](https://en.wikipedia.org/wiki/Generation_loss). Therefore, I do not recommend running this on your precious music collection, unless you have a backup of the originals or accept potential quality reduction. If you just want to normalize the subjective volume of the files without changing the actual content, consider using [MP3Gain](http://mp3gain.sourceforge.net/) and [aacgain](http://aacgain.altosdesign.com/).
389
421
 
390
422
  ### Why are my output files MKV?
391
423
 
392
424
  I chose MKV as a default output container since it handles almost every possible combination of audio, video, and subtitle codecs. If you know which audio/video codec you want, and which container is supported, use the output options to specify the encoder and output file name manually.
393
425
 
394
- ### "Could not write header for output file" error
426
+ ### I get a "Could not write header for output file" error
395
427
 
396
428
  See the [next section](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error).
397
429
 
@@ -487,6 +519,7 @@ If you found this program useful and feel like giving back, feel free to send a
487
519
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sian1468"><img src="https://avatars.githubusercontent.com/u/58017832?v=4?s=100" width="100px;" alt="sian1468"/><br /><sub><b>sian1468</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=sian1468" title="Tests">⚠️</a></td>
488
520
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/psavva"><img src="https://avatars.githubusercontent.com/u/1454758?v=4?s=100" width="100px;" alt="Panayiotis Savva"/><br /><sub><b>Panayiotis Savva</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=psavva" title="Code">💻</a></td>
489
521
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/HighMans"><img src="https://avatars.githubusercontent.com/u/42877729?v=4?s=100" width="100px;" alt="HighMans"/><br /><sub><b>HighMans</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=HighMans" title="Code">💻</a></td>
522
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/kanjieater"><img src="https://avatars.githubusercontent.com/u/32607317?v=4?s=100" width="100px;" alt="kanjieater"/><br /><sub><b>kanjieater</b></sub></a><br /><a href="#ideas-kanjieater" title="Ideas, Planning, & Feedback">🤔</a></td>
490
523
  </tr>
491
524
  </tbody>
492
525
  <tfoot>
@@ -0,0 +1 @@
1
+ __version__ = "1.28.3"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ffmpeg-normalize
3
- Version: 1.28.1
3
+ Version: 1.28.3
4
4
  Summary: Normalize audio via ffmpeg
5
5
  Home-page: https://github.com/slhck/ffmpeg-normalize
6
6
  Author: Werner Robitza
@@ -25,13 +25,13 @@ License-File: LICENSE
25
25
 
26
26
  # ffmpeg-normalize
27
27
 
28
- <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
29
- [![All Contributors](https://img.shields.io/badge/all_contributors-18-orange.svg?style=flat-square)](#contributors-)
30
- <!-- ALL-CONTRIBUTORS-BADGE:END -->
31
-
32
28
  [![PyPI version](https://img.shields.io/pypi/v/ffmpeg-normalize.svg)](https://pypi.org/project/ffmpeg-normalize)
29
+ ![Docker Image Version](https://img.shields.io/docker/v/slhck/ffmpeg-normalize?sort=semver&label=Docker%20image)
30
+ ![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/slhck/ffmpeg-normalize/python-package.yml)
33
31
 
34
- [![Python package](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml/badge.svg)](https://github.com/slhck/ffmpeg-normalize/actions/workflows/python-package.yml)
32
+ <!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
33
+ [![All Contributors](https://img.shields.io/badge/all_contributors-19-orange.svg?style=flat-square)](#contributors-)
34
+ <!-- ALL-CONTRIBUTORS-BADGE:END -->
35
35
 
36
36
  A utility for batch-normalizing audio using ffmpeg.
37
37
 
@@ -53,9 +53,9 @@ Read on for more info.
53
53
  - [Requirements](#requirements)
54
54
  - [ffmpeg](#ffmpeg)
55
55
  - [Installation](#installation)
56
- - [Docker Build](#docker-build)
57
- - [Usage](#usage)
58
- - [Description](#description)
56
+ - [Usage with Docker](#usage-with-docker)
57
+ - [High LeveL Introduction](#high-level-introduction)
58
+ - [Basic Usage](#basic-usage)
59
59
  - [Examples](#examples)
60
60
  - [Detailed Options](#detailed-options)
61
61
  - [File Input/Output](#file-inputoutput)
@@ -68,10 +68,11 @@ Read on for more info.
68
68
  - [Environment Variables](#environment-variables)
69
69
  - [API](#api)
70
70
  - [FAQ](#faq)
71
+ - [What options should I choose for the EBU R128 filter? What is linear and dynamic mode?](#what-options-should-i-choose-for-the-ebu-r128-filter-what-is-linear-and-dynamic-mode)
71
72
  - [The program doesn't work because the "loudnorm" filter can't be found](#the-program-doesnt-work-because-the-loudnorm-filter-cant-be-found)
72
73
  - [Should I use this to normalize my music collection?](#should-i-use-this-to-normalize-my-music-collection)
73
74
  - [Why are my output files MKV?](#why-are-my-output-files-mkv)
74
- - ["Could not write header for output file" error](#could-not-write-header-for-output-file-error)
75
+ - [I get a "Could not write header for output file" error](#i-get-a-could-not-write-header-for-output-file-error)
75
76
  - [The conversion does not work and I get a cryptic ffmpeg error!](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error)
76
77
  - [What are the different normalization algorithms?](#what-are-the-different-normalization-algorithms)
77
78
  - [Couldn't I just run `loudnorm` with ffmpeg?](#couldnt-i-just-run-loudnorm-with-ffmpeg)
@@ -86,7 +87,7 @@ Read on for more info.
86
87
 
87
88
  ## Requirements
88
89
 
89
- You need Python 3.8 or higher.
90
+ You need Python 3.8 or higher, and ffmpeg.
90
91
 
91
92
  ### ffmpeg
92
93
 
@@ -125,74 +126,61 @@ pip3 install ffmpeg-normalize
125
126
 
126
127
  Or download this repository, then run `pip3 install .`.
127
128
 
128
- ## Docker Build
129
- Download this repository and run
129
+ To later upgrade to the latest version, run `pip3 install --upgrade ffmpeg-normalize`.
130
130
 
131
- ```
132
- docker build -t ffmpeg-normalize .
133
- ```
131
+ ## Usage with Docker
134
132
 
135
- Run using Windows Powershell or Linux:
136
- ```
137
- docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
138
- ```
139
- This will mount your current folder to the /tmp directory inside the container
133
+ You can use the pre-built image from Docker Hub:
140
134
 
141
- Note: The container will run in interactive mode.
135
+ ```bash
136
+ docker run -v "$(pwd):/tmp" -it slhck/ffmpeg-normalize
137
+ ```
142
138
 
143
- Example Usage:
139
+ Alternatively, download this repository and run
144
140
 
145
- ```
146
- PS C:\yonkers> docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /bin/sh
147
- / # cd /tmp
148
- /tmp # ls
149
- 01. Goblin.mp3
150
- /tmp # ffmpeg-normalize "01. Goblin.mp3" -f -c:a libmp3lame -b:a 320k --target-level -13 --output "01. Goblin normalized.mp3"
151
- WARNING: The chosen output extension mp3 does not support video/cover art. It will be disabled.
152
- /tmp # ls
153
- 01. Goblin normalized.mp3
154
- 01. Goblin.mp3
141
+ ```bash
142
+ docker build -t ffmpeg-normalize .
155
143
  ```
156
144
 
157
- ## Usage
145
+ Then run the container with:
158
146
 
159
147
  ```bash
160
- ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
148
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize
161
149
  ```
162
150
 
163
- Example:
151
+ This will mount your current directory to the `/tmp` directory inside the container. Everything else works the same way as if you had installed the program locally. For example, to normalize a file:
164
152
 
165
153
  ```bash
166
- ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
154
+ docker run -v "$(pwd):/tmp" -it ffmpeg-normalize /tmp/yourfile.mp4 -o /tmp/yourfile-normalized.wav
167
155
  ```
168
156
 
169
- For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
157
+ You will then find the normalized file in your current directory.
170
158
 
171
- ## Description
159
+ ## High LeveL Introduction
172
160
 
173
161
  Please read this section for a high level introduction.
174
162
 
175
163
  **What does the program do?**
176
164
 
177
- The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume.
165
+ The program takes one or more input files and, by default, writes them to a folder called `normalized`, using an `.mkv` container. All audio streams will be normalized so that they have the same (perceived) volume according to the EBU R128 standard. This is done by analyzing the audio streams and applying a filter to bring them to a target level. Under the hood, the program uses ffmpeg's `loudnorm` filter to do this.
178
166
 
179
167
  **How do I specify the input?**
180
168
 
181
- Just give the program one or more input files as arguments. It works with most media files.
169
+ Just give the program one or more input files as arguments. It works with most media files, including video files.
182
170
 
183
171
  **How do I specify the output?**
184
172
 
185
- You can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
173
+ You don't have to specify an output file name (the default is `normalized/<input>.mkv`), but if you want to override it, you can specify one output file name for each input file with the `-o` option. In this case, the container format (e.g. `.wav`) will be inferred from the file name extension that you've given.
186
174
 
187
175
  Example:
188
176
 
189
- ```
190
- ffmpeg-normalize 1.wav 2.wav -o 1n.wav 2n.wav
177
+ ```bash
178
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.wav 2-normalized.wav
191
179
  ```
192
180
 
193
- If you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`.
181
+ Note that if you don't specify the output file name for an input file, the container format will be MKV, and the output will be written to `normalized/<input>.mkv`. The reason for choosing the MKV container is that it can handle almost any codec combination.
194
182
 
195
- Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`.
183
+ Using the `-ext` option, you can supply a different output extension common to all output files, e.g. `-ext m4a`. However, you need to make sure that the container supports the codecs used for the output (see below).
196
184
 
197
185
  **What will get normalized?**
198
186
 
@@ -200,7 +188,7 @@ By default, all streams from the input file will be written to the output file.
200
188
 
201
189
  **How will the normalization be done?**
202
190
 
203
- The normalization will be performed with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
191
+ The normalization will be performed according to the EBU R128 algorithm with the [`loudnorm` filter](https://ffmpeg.org/ffmpeg-filters.html#loudnorm) from FFmpeg, which was [originally written by Kyle Swanson](https://k.ylo.ph/2016/04/04/loudnorm.html). It will bring the audio to a specified target level. This ensures that multiple files normalized with this filter will have the same perceived loudness.
204
192
 
205
193
  **What codec is chosen?**
206
194
 
@@ -208,6 +196,22 @@ The default audio encoding method is uncompressed PCM (`pcm_s16le`) to avoid int
208
196
 
209
197
  Some containers (like MP4) also cannot handle PCM audio. If you want to use such containers and/or keep the file size down, use `-c:a` and specify an audio codec (e.g., `-c:a aac` for ffmpeg's built-in AAC encoder).
210
198
 
199
+ ## Basic Usage
200
+
201
+ Supply one or more input files, and optionally, output file names:
202
+
203
+ ```bash
204
+ ffmpeg-normalize input [input ...][-h][-o OUTPUT [OUTPUT ...]] [options]
205
+ ```
206
+
207
+ Example:
208
+
209
+ ```bash
210
+ ffmpeg-normalize 1.wav 2.wav -o 1-normalized.m4a 2-normalized.m4a -c:a aac -b:a 192k
211
+ ```
212
+
213
+ For more information on the options (`[options]`) available, run `ffmpeg-normalize -h`, or read on.
214
+
211
215
  ## Examples
212
216
 
213
217
  [Read the examples on the wiki.](https://github.com/slhck/ffmpeg-normalize/wiki/examples)
@@ -398,6 +402,32 @@ For more information see the [API documentation](https://htmlpreview.github.io/?
398
402
 
399
403
  ## FAQ
400
404
 
405
+ ### What options should I choose for the EBU R128 filter? What is linear and dynamic mode?
406
+
407
+ EBU R128 is a method for normalizing audio loudness across different tracks or programs. It works by analyzing the audio content and adjusting it to meet specific loudness targets. The main components are:
408
+
409
+ * Integrated Loudness (I): The overall loudness of the entire audio.
410
+ * Loudness Range (LRA): The variation in loudness over time.
411
+ * True Peak (TP): The maximum level of the audio signal.
412
+
413
+ The normalization process involves measuring these values (input) and then applying gain adjustments to meet target levels (output), typically -23 LUFS for integrated loudness. You can also specify a target loudness range (LRA) and true peak level (TP).
414
+
415
+ **Linear mode** applies a constant gain adjustment across the entire audio file. This is generally preferred because:
416
+
417
+ * It preserves the original dynamic range of the audio.
418
+ * It maintains the relative loudness between different parts of the audio.
419
+ * It avoids potential artifacts or pumping effects that can occur with dynamic processing.
420
+
421
+ **Dynamic mode**, on the other hand, can change the volume dynamically throughout the file. While this can achieve more consistent loudness, it may alter the original artistic intent and potentially introduce audible artifacts (possibly due to some bugs in the ffmpeg filter).
422
+
423
+ For most cases, linear mode is recommended. Dynamic mode should only be used when linear mode is not suitable or when a specific effect is desired. In some cases, `loudnorm` will still fall back to dynamic mode, and a warning will be printed to the console. Here's when this can happen:
424
+
425
+ * When the input loudness range (LRA) is larger than the target loudness range: If the input file has a loudness range that exceeds the specified loudness range target, the loudnorm filter will automatically switch to dynamic mode. This is because linear normalization alone cannot reduce the loudness range without dynamic processing (limiting). The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target.
426
+
427
+ * When the required gain adjustment to meet the integrated loudness target would result in the true peak exceeding the specified true peak limit. This is because linear processing alone cannot reduce peaks without affecting the entire signal. For example, if a file needs to be amplified by 6 dB to reach the target integrated loudness, but doing so would push the true peak above the specified limit, the filter might switch to dynamic mode to handle this situation. If your content allows for it, you can increase the true peak target to give more headroom for linear processing. If you're consistently running into true peak issues, you might also consider lowering your target integrated loudness level.
428
+
429
+ At this time, the `loudnorm` filter in ffmpeg does not provide a way to force linear mode when the input loudness range exceeds the target or when the true peak would be exceeded. The `--keep-loudness-range-target` option can be used to keep the input loudness range target above the specified target, but it will not force linear mode in all cases. We are working on a solution to handle this automatically!
430
+
401
431
  ### The program doesn't work because the "loudnorm" filter can't be found
402
432
 
403
433
  Make sure you run a recent ffmpeg version and that `loudnorm` is part of the output when you run `ffmpeg -filters`. Many distributions package outdated ffmpeg versions, or (even worse), Libav's `ffmpeg` disguising as a real `ffmpeg` from the FFmpeg project.
@@ -410,13 +440,15 @@ If you have to use an outdated ffmpeg version, you can only use `rms` or `peak`
410
440
 
411
441
  ### Should I use this to normalize my music collection?
412
442
 
443
+ Generally, no.
444
+
413
445
  When you run `ffmpeg-normalize` and re-encode files with MP3 or AAC, you will inevitably introduce [generation loss](https://en.wikipedia.org/wiki/Generation_loss). Therefore, I do not recommend running this on your precious music collection, unless you have a backup of the originals or accept potential quality reduction. If you just want to normalize the subjective volume of the files without changing the actual content, consider using [MP3Gain](http://mp3gain.sourceforge.net/) and [aacgain](http://aacgain.altosdesign.com/).
414
446
 
415
447
  ### Why are my output files MKV?
416
448
 
417
449
  I chose MKV as a default output container since it handles almost every possible combination of audio, video, and subtitle codecs. If you know which audio/video codec you want, and which container is supported, use the output options to specify the encoder and output file name manually.
418
450
 
419
- ### "Could not write header for output file" error
451
+ ### I get a "Could not write header for output file" error
420
452
 
421
453
  See the [next section](#the-conversion-does-not-work-and-i-get-a-cryptic-ffmpeg-error).
422
454
 
@@ -512,6 +544,7 @@ If you found this program useful and feel like giving back, feel free to send a
512
544
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/sian1468"><img src="https://avatars.githubusercontent.com/u/58017832?v=4?s=100" width="100px;" alt="sian1468"/><br /><sub><b>sian1468</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=sian1468" title="Tests">⚠️</a></td>
513
545
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/psavva"><img src="https://avatars.githubusercontent.com/u/1454758?v=4?s=100" width="100px;" alt="Panayiotis Savva"/><br /><sub><b>Panayiotis Savva</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=psavva" title="Code">💻</a></td>
514
546
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/HighMans"><img src="https://avatars.githubusercontent.com/u/42877729?v=4?s=100" width="100px;" alt="HighMans"/><br /><sub><b>HighMans</b></sub></a><br /><a href="https://github.com/slhck/ffmpeg-normalize/commits?author=HighMans" title="Code">💻</a></td>
547
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/kanjieater"><img src="https://avatars.githubusercontent.com/u/32607317?v=4?s=100" width="100px;" alt="kanjieater"/><br /><sub><b>kanjieater</b></sub></a><br /><a href="#ideas-kanjieater" title="Ideas, Planning, & Feedback">🤔</a></td>
515
548
  </tr>
516
549
  </tbody>
517
550
  <tfoot>
@@ -559,6 +592,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
559
592
  # Changelog
560
593
 
561
594
 
595
+ ## v1.28.3 (2024-08-16)
596
+
597
+ * Make colorama dependency windows-only.
598
+
599
+ * Update.
600
+
601
+ * Update badges.
602
+
603
+ * Docs: add @kanjieater as a contributor.
604
+
605
+
606
+ ## v1.28.2 (2024-06-22)
607
+
608
+ * Provide an entrypoint for the Docker image.
609
+
610
+ * Add docker push (#261)
611
+
612
+
562
613
  ## v1.28.1 (2024-05-15)
563
614
 
564
615
  * Fix assignment of audio statistics, fixes #257.
@@ -1,4 +1,6 @@
1
1
  tqdm
2
- colorama
3
2
  ffmpeg-progress-yield
4
3
  colorlog
4
+
5
+ [:platform_system == "Windows"]
6
+ colorama
@@ -34,7 +34,7 @@ setup(
34
34
  },
35
35
  install_requires=[
36
36
  "tqdm",
37
- "colorama",
37
+ "colorama;platform_system=='Windows'",
38
38
  "ffmpeg-progress-yield",
39
39
  "colorlog",
40
40
  ],
@@ -1 +0,0 @@
1
- __version__ = "1.28.1"