ffmpeg-normalize 1.37.7__tar.gz → 1.37.8__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 (17) hide show
  1. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/PKG-INFO +3 -4
  2. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/README.md +1 -1
  3. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/pyproject.toml +3 -4
  4. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_media_file.py +8 -0
  5. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_streams.py +27 -0
  6. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/LICENSE.md +0 -0
  7. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/__init__.py +0 -0
  8. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/__main__.py +0 -0
  9. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_cmd_utils.py +0 -0
  10. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_errors.py +0 -0
  11. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_ffmpeg_normalize.py +0 -0
  12. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_logger.py +0 -0
  13. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/_presets.py +0 -0
  14. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/data/presets/music.json +0 -0
  15. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/data/presets/podcast.json +0 -0
  16. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/data/presets/streaming-video.json +0 -0
  17. {ffmpeg_normalize-1.37.7 → ffmpeg_normalize-1.37.8}/src/ffmpeg_normalize/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ffmpeg-normalize
3
- Version: 1.37.7
3
+ Version: 1.37.8
4
4
  Summary: Normalize audio via ffmpeg
5
5
  Keywords: ffmpeg,normalize,audio
6
6
  Author: Werner Robitza
@@ -14,7 +14,6 @@ Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
14
14
  Classifier: Topic :: Multimedia :: Sound/Audio :: Conversion
15
15
  Classifier: Natural Language :: English
16
16
  Classifier: Programming Language :: Python :: 3
17
- Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
@@ -25,7 +24,7 @@ Requires-Dist: colorama>=0.4.6 ; sys_platform == 'win32'
25
24
  Requires-Dist: ffmpeg-progress-yield>=1.0.1
26
25
  Requires-Dist: colorlog==6.7.0
27
26
  Requires-Dist: mutagen>=1.47.0
28
- Requires-Python: >=3.9
27
+ Requires-Python: >=3.10
29
28
  Project-URL: Homepage, https://github.com/slhck/ffmpeg-normalize
30
29
  Project-URL: Repository, https://github.com/slhck/ffmpeg-normalize
31
30
  Description-Content-Type: text/markdown
@@ -58,7 +57,7 @@ This program normalizes media files to a certain loudness level using the EBU R1
58
57
 
59
58
  ## 🚀 Quick Start
60
59
 
61
- 1. Install a recent version of [ffmpeg](https://ffmpeg.org/download.html)
60
+ 1. Install a recent version of [ffmpeg](https://ffmpeg.org/download.html) and Python 3.10 or higher
62
61
  2. Run `pip3 install ffmpeg-normalize` and `ffmpeg-normalize /path/to/your/file.mp4`, alternatively install [`uv`](https://docs.astral.sh/uv/getting-started/installation/) and run `uvx ffmpeg-normalize /path/to/your/file.mp4`
63
62
  3. Done! 🎧 (the normalized file will be called `normalized/file.mkv`)
64
63
 
@@ -26,7 +26,7 @@ This program normalizes media files to a certain loudness level using the EBU R1
26
26
 
27
27
  ## 🚀 Quick Start
28
28
 
29
- 1. Install a recent version of [ffmpeg](https://ffmpeg.org/download.html)
29
+ 1. Install a recent version of [ffmpeg](https://ffmpeg.org/download.html) and Python 3.10 or higher
30
30
  2. Run `pip3 install ffmpeg-normalize` and `ffmpeg-normalize /path/to/your/file.mp4`, alternatively install [`uv`](https://docs.astral.sh/uv/getting-started/installation/) and run `uvx ffmpeg-normalize /path/to/your/file.mp4`
31
31
  3. Done! 🎧 (the normalized file will be called `normalized/file.mkv`)
32
32
 
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "ffmpeg-normalize"
7
- version = "1.37.7"
7
+ version = "1.37.8"
8
8
  description = "Normalize audio via ffmpeg"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -21,14 +21,13 @@ classifiers = [
21
21
  "Topic :: Multimedia :: Sound/Audio :: Conversion",
22
22
  "Natural Language :: English",
23
23
  "Programming Language :: Python :: 3",
24
- "Programming Language :: Python :: 3.9",
25
24
  "Programming Language :: Python :: 3.10",
26
25
  "Programming Language :: Python :: 3.11",
27
26
  "Programming Language :: Python :: 3.12",
28
27
  "Programming Language :: Python :: 3.13",
29
28
  "Programming Language :: Python :: 3.14",
30
29
  ]
31
- requires-python = ">=3.9"
30
+ requires-python = ">=3.10"
32
31
  dependencies = [
33
32
  "tqdm>=4.64.1",
34
33
  "colorama>=0.4.6; platform_system=='Windows'",
@@ -50,7 +49,7 @@ package-data = {"ffmpeg_normalize" = ["data/**/*.json"]}
50
49
 
51
50
  [dependency-groups]
52
51
  dev = [
53
- "pytest>=8.1.1,<9",
52
+ "pytest>=9.0.3",
54
53
  "ruff>=0.12.11",
55
54
  "types-tqdm",
56
55
  "shtab>=1.7.0",
@@ -660,6 +660,14 @@ class MediaFile:
660
660
  if self.ffmpeg_normalize.pre_filter:
661
661
  filter_chain.append(self.ffmpeg_normalize.pre_filter)
662
662
 
663
+ # Apply channel conversion before normalization so that the
664
+ # normalization filter operates on the same channel layout that
665
+ # was measured in the first pass. See issue #316.
666
+ if self.ffmpeg_normalize.audio_channels:
667
+ filter_chain.append(
668
+ f"aformat=sample_fmts=fltp:channel_layouts={self.ffmpeg_normalize.audio_channels}c"
669
+ )
670
+
663
671
  filter_chain.append(normalization_filter)
664
672
 
665
673
  if self.ffmpeg_normalize.post_filter:
@@ -210,6 +210,10 @@ class AudioStream(MediaStream):
210
210
  Get a filter string for current_filter, with the pre-filter
211
211
  added before. Applies the input label before.
212
212
 
213
+ If a target channel count is set via ``audio_channels``, a channel
214
+ layout conversion is inserted before the analysis/normalization
215
+ filter so that measurements reflect the downmixed signal.
216
+
213
217
  Args:
214
218
  current_filter (str): The current filter.
215
219
 
@@ -220,10 +224,33 @@ class AudioStream(MediaStream):
220
224
  filter_chain = []
221
225
  if self.media_file.ffmpeg_normalize.pre_filter:
222
226
  filter_chain.append(self.media_file.ffmpeg_normalize.pre_filter)
227
+ channel_conversion = self._get_channel_conversion_filter()
228
+ if channel_conversion:
229
+ filter_chain.append(channel_conversion)
223
230
  filter_chain.append(current_filter)
224
231
  filter_str = input_label + ",".join(filter_chain)
225
232
  return filter_str
226
233
 
234
+ def _get_channel_conversion_filter(self) -> str | None:
235
+ """
236
+ Return an ``aformat`` filter string that downmixes/upmixes to the
237
+ requested channel count, or None if no conversion is configured.
238
+
239
+ The ``Nc`` channel-layout notation matches ffmpeg's default layout
240
+ selection for ``-ac N``, so the analysis pass measures the same
241
+ signal that the output will contain.
242
+
243
+ A float planar sample format is requested so the downmix is not
244
+ attenuated to fit an integer range. This is what the analysis
245
+ measurement should reflect, since the volume gain is applied in
246
+ the filter graph (where samples are also float) before being
247
+ written to the output codec.
248
+ """
249
+ audio_channels = self.media_file.ffmpeg_normalize.audio_channels
250
+ if not audio_channels:
251
+ return None
252
+ return f"aformat=sample_fmts=fltp:channel_layouts={audio_channels}c"
253
+
227
254
  def parse_astats(self) -> Iterator[float]:
228
255
  """
229
256
  Use ffmpeg with astats filter to get the mean (RMS) and max (peak) volume of the input file.