ffmpeg-normalize 1.31.2__tar.gz → 1.31.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.
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/CHANGELOG.md +5 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/PKG-INFO +6 -1
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_cmd_utils.py +1 -3
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_media_file.py +6 -6
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_streams.py +15 -14
- ffmpeg_normalize-1.31.3/ffmpeg_normalize/_version.py +1 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/PKG-INFO +6 -1
- ffmpeg_normalize-1.31.2/ffmpeg_normalize/_version.py +0 -1
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/LICENSE +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/README.md +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/__init__.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/__main__.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_errors.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_ffmpeg_normalize.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/_logger.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize/py.typed +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/SOURCES.txt +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/dependency_links.txt +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/entry_points.txt +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/not-zip-safe +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/requires.txt +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/top_level.txt +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/setup.cfg +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/setup.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/test/out.mp4 +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/test/test.mp4 +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/test/test.py +0 -0
- {ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/test/test.wav +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ffmpeg_normalize
|
|
3
|
-
Version: 1.31.
|
|
3
|
+
Version: 1.31.3
|
|
4
4
|
Summary: Normalize audio via ffmpeg
|
|
5
5
|
Home-page: https://github.com/slhck/ffmpeg-normalize
|
|
6
6
|
Author: Werner Robitza
|
|
@@ -667,6 +667,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
667
667
|
# Changelog
|
|
668
668
|
|
|
669
669
|
|
|
670
|
+
## v1.31.3 (2025-04-14)
|
|
671
|
+
|
|
672
|
+
* Swap NUL to os.devnull.
|
|
673
|
+
|
|
674
|
+
|
|
670
675
|
## v1.31.2 (2025-03-19)
|
|
671
676
|
|
|
672
677
|
* Fix: special handling of /dev/null.
|
|
@@ -5,9 +5,8 @@ import os
|
|
|
5
5
|
import re
|
|
6
6
|
import shlex
|
|
7
7
|
import subprocess
|
|
8
|
-
from platform import system
|
|
9
8
|
from shutil import which
|
|
10
|
-
from typing import
|
|
9
|
+
from typing import Any, Iterator
|
|
11
10
|
|
|
12
11
|
from ffmpeg_progress_yield import FfmpegProgress
|
|
13
12
|
|
|
@@ -15,7 +14,6 @@ from ._errors import FFmpegNormalizeError
|
|
|
15
14
|
|
|
16
15
|
_logger = logging.getLogger(__name__)
|
|
17
16
|
|
|
18
|
-
NUL = "NUL" if system() in ("Windows", "cli") else "/dev/null"
|
|
19
17
|
DUR_REGEX = re.compile(
|
|
20
18
|
r"Duration: (?P<hour>\d{2}):(?P<min>\d{2}):(?P<sec>\d{2})\.(?P<ms>\d{2})"
|
|
21
19
|
)
|
|
@@ -10,7 +10,7 @@ from typing import TYPE_CHECKING, Iterable, Iterator, Literal, TypedDict
|
|
|
10
10
|
|
|
11
11
|
from tqdm import tqdm
|
|
12
12
|
|
|
13
|
-
from ._cmd_utils import DUR_REGEX,
|
|
13
|
+
from ._cmd_utils import DUR_REGEX, CommandRunner
|
|
14
14
|
from ._errors import FFmpegNormalizeError
|
|
15
15
|
from ._streams import (
|
|
16
16
|
AudioStream,
|
|
@@ -69,7 +69,7 @@ class MediaFile:
|
|
|
69
69
|
self.output_file = output_file
|
|
70
70
|
current_ext = os.path.splitext(output_file)[1][1:]
|
|
71
71
|
# we need to check if it's empty, e.g. /dev/null or NUL
|
|
72
|
-
if current_ext == "" or self.output_file ==
|
|
72
|
+
if current_ext == "" or self.output_file == os.devnull:
|
|
73
73
|
self.output_ext = self.ffmpeg_normalize.extension
|
|
74
74
|
else:
|
|
75
75
|
self.output_ext = current_ext
|
|
@@ -114,7 +114,7 @@ class MediaFile:
|
|
|
114
114
|
"0",
|
|
115
115
|
"-f",
|
|
116
116
|
"null",
|
|
117
|
-
|
|
117
|
+
os.devnull,
|
|
118
118
|
]
|
|
119
119
|
|
|
120
120
|
output = CommandRunner().run_command(cmd).get_output()
|
|
@@ -435,7 +435,7 @@ class MediaFile:
|
|
|
435
435
|
return
|
|
436
436
|
|
|
437
437
|
# special case: if output is a null device, write directly to it
|
|
438
|
-
if self.output_file ==
|
|
438
|
+
if self.output_file == os.devnull:
|
|
439
439
|
cmd.append(self.output_file)
|
|
440
440
|
else:
|
|
441
441
|
temp_dir = mkdtemp()
|
|
@@ -452,14 +452,14 @@ class MediaFile:
|
|
|
452
452
|
)
|
|
453
453
|
raise e
|
|
454
454
|
else:
|
|
455
|
-
if self.output_file !=
|
|
455
|
+
if self.output_file != os.devnull:
|
|
456
456
|
_logger.debug(
|
|
457
457
|
f"Moving temporary file from {temp_file} to {self.output_file}"
|
|
458
458
|
)
|
|
459
459
|
move(temp_file, self.output_file)
|
|
460
460
|
rmtree(temp_dir, ignore_errors=True)
|
|
461
461
|
except Exception as e:
|
|
462
|
-
if self.output_file !=
|
|
462
|
+
if self.output_file != os.devnull:
|
|
463
463
|
rmtree(temp_dir, ignore_errors=True)
|
|
464
464
|
raise e
|
|
465
465
|
|
|
@@ -4,9 +4,9 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import os
|
|
6
6
|
import re
|
|
7
|
-
from typing import TYPE_CHECKING, Iterator,
|
|
7
|
+
from typing import TYPE_CHECKING, Iterator, Literal, TypedDict, cast
|
|
8
8
|
|
|
9
|
-
from ._cmd_utils import
|
|
9
|
+
from ._cmd_utils import CommandRunner, dict_to_filter_opts
|
|
10
10
|
from ._errors import FFmpegNormalizeError
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
@@ -17,6 +17,7 @@ _logger = logging.getLogger(__name__)
|
|
|
17
17
|
|
|
18
18
|
_loudnorm_pattern = re.compile(r"\[Parsed_loudnorm_(\d+)")
|
|
19
19
|
|
|
20
|
+
|
|
20
21
|
class EbuLoudnessStatistics(TypedDict):
|
|
21
22
|
input_i: float
|
|
22
23
|
input_tp: float
|
|
@@ -239,7 +240,7 @@ class AudioStream(MediaStream):
|
|
|
239
240
|
"-sn",
|
|
240
241
|
"-f",
|
|
241
242
|
"null",
|
|
242
|
-
|
|
243
|
+
os.devnull,
|
|
243
244
|
]
|
|
244
245
|
|
|
245
246
|
cmd_runner = CommandRunner()
|
|
@@ -310,7 +311,7 @@ class AudioStream(MediaStream):
|
|
|
310
311
|
"-sn",
|
|
311
312
|
"-f",
|
|
312
313
|
"null",
|
|
313
|
-
|
|
314
|
+
os.devnull,
|
|
314
315
|
]
|
|
315
316
|
|
|
316
317
|
cmd_runner = CommandRunner()
|
|
@@ -322,11 +323,13 @@ class AudioStream(MediaStream):
|
|
|
322
323
|
)
|
|
323
324
|
|
|
324
325
|
# only one stream
|
|
325
|
-
self.loudness_statistics["ebu_pass1"] = next(
|
|
326
|
+
self.loudness_statistics["ebu_pass1"] = next(
|
|
327
|
+
iter(AudioStream.prune_and_parse_loudnorm_output(output).values())
|
|
328
|
+
)
|
|
326
329
|
|
|
327
330
|
@staticmethod
|
|
328
331
|
def prune_and_parse_loudnorm_output(
|
|
329
|
-
output: str
|
|
332
|
+
output: str,
|
|
330
333
|
) -> dict[int, EbuLoudnessStatistics]:
|
|
331
334
|
"""
|
|
332
335
|
Prune ffmpeg progress lines from output and parse the loudnorm filter output.
|
|
@@ -344,7 +347,7 @@ class AudioStream(MediaStream):
|
|
|
344
347
|
|
|
345
348
|
@staticmethod
|
|
346
349
|
def _parse_loudnorm_output(
|
|
347
|
-
output_lines: list[str]
|
|
350
|
+
output_lines: list[str],
|
|
348
351
|
) -> dict[int, EbuLoudnessStatistics]:
|
|
349
352
|
"""
|
|
350
353
|
Parse the output of a loudnorm filter to get the EBU loudness statistics.
|
|
@@ -403,7 +406,9 @@ class AudioStream(MediaStream):
|
|
|
403
406
|
# convert to floats
|
|
404
407
|
loudnorm_stats[key] = float(loudnorm_stats[key])
|
|
405
408
|
|
|
406
|
-
result[stream_index] = cast(
|
|
409
|
+
result[stream_index] = cast(
|
|
410
|
+
EbuLoudnessStatistics, loudnorm_stats
|
|
411
|
+
)
|
|
407
412
|
stream_index = -1
|
|
408
413
|
except Exception as e:
|
|
409
414
|
raise FFmpegNormalizeError(
|
|
@@ -504,15 +509,11 @@ class AudioStream(MediaStream):
|
|
|
504
509
|
"offset": self._constrain(
|
|
505
510
|
stats["target_offset"], -99, 99, name="target_offset"
|
|
506
511
|
),
|
|
507
|
-
"measured_i": self._constrain(
|
|
508
|
-
stats["input_i"], -99, 0, name="input_i"
|
|
509
|
-
),
|
|
512
|
+
"measured_i": self._constrain(stats["input_i"], -99, 0, name="input_i"),
|
|
510
513
|
"measured_lra": self._constrain(
|
|
511
514
|
stats["input_lra"], 0, 99, name="input_lra"
|
|
512
515
|
),
|
|
513
|
-
"measured_tp": self._constrain(
|
|
514
|
-
stats["input_tp"], -99, 99, name="input_tp"
|
|
515
|
-
),
|
|
516
|
+
"measured_tp": self._constrain(stats["input_tp"], -99, 99, name="input_tp"),
|
|
516
517
|
"measured_thresh": self._constrain(
|
|
517
518
|
stats["input_thresh"], -99, 0, name="input_thresh"
|
|
518
519
|
),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.31.3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ffmpeg-normalize
|
|
3
|
-
Version: 1.31.
|
|
3
|
+
Version: 1.31.3
|
|
4
4
|
Summary: Normalize audio via ffmpeg
|
|
5
5
|
Home-page: https://github.com/slhck/ffmpeg-normalize
|
|
6
6
|
Author: Werner Robitza
|
|
@@ -667,6 +667,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
667
667
|
# Changelog
|
|
668
668
|
|
|
669
669
|
|
|
670
|
+
## v1.31.3 (2025-04-14)
|
|
671
|
+
|
|
672
|
+
* Swap NUL to os.devnull.
|
|
673
|
+
|
|
674
|
+
|
|
670
675
|
## v1.31.2 (2025-03-19)
|
|
671
676
|
|
|
672
677
|
* Fix: special handling of /dev/null.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.31.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ffmpeg_normalize-1.31.2 → ffmpeg_normalize-1.31.3}/ffmpeg_normalize.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|