ffmpeg-normalize 1.31.0__py2.py3-none-any.whl → 1.31.2__py2.py3-none-any.whl

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.
@@ -559,6 +559,7 @@ def main() -> None:
559
559
  extra_input_options=extra_input_options,
560
560
  extra_output_options=extra_output_options,
561
561
  output_format=cli_args.output_format,
562
+ extension=cli_args.extension,
562
563
  dry_run=cli_args.dry_run,
563
564
  progress=cli_args.progress,
564
565
  )
@@ -79,6 +79,7 @@ class FFmpegNormalize:
79
79
  extra_input_options (list, optional): Extra input options. Defaults to None.
80
80
  extra_output_options (list, optional): Extra output options. Defaults to None.
81
81
  output_format (str, optional): Output format. Defaults to None.
82
+ extension (str, optional): Output file extension to use for output files that were not explicitly specified. Defaults to "mkv".
82
83
  dry_run (bool, optional): Dry run. Defaults to False.
83
84
  debug (bool, optional): Debug. Defaults to False.
84
85
  progress (bool, optional): Progress. Defaults to False.
@@ -117,6 +118,7 @@ class FFmpegNormalize:
117
118
  extra_input_options: list[str] | None = None,
118
119
  extra_output_options: list[str] | None = None,
119
120
  output_format: str | None = None,
121
+ extension: str = "mkv",
120
122
  dry_run: bool = False,
121
123
  debug: bool = False,
122
124
  progress: bool = False,
@@ -197,6 +199,7 @@ class FFmpegNormalize:
197
199
  self.post_filter = post_filter
198
200
 
199
201
  self.output_format = output_format
202
+ self.extension = extension
200
203
  self.dry_run = dry_run
201
204
  self.debug = debug
202
205
  self.progress = progress
@@ -67,7 +67,12 @@ class MediaFile:
67
67
  self.skip = False
68
68
  self.input_file = input_file
69
69
  self.output_file = output_file
70
- self.output_ext = os.path.splitext(output_file)[1][1:]
70
+ current_ext = os.path.splitext(output_file)[1][1:]
71
+ # we need to check if it's empty, e.g. /dev/null or NUL
72
+ if current_ext == "" or self.output_file == NUL:
73
+ self.output_ext = self.ffmpeg_normalize.extension
74
+ else:
75
+ self.output_ext = current_ext
71
76
  self.streams: StreamDict = {"audio": {}, "video": {}, "subtitle": {}}
72
77
 
73
78
  self.parse_streams()
@@ -177,8 +182,7 @@ class MediaFile:
177
182
  and len(self.streams["audio"].values()) > 1
178
183
  ):
179
184
  _logger.warning(
180
- "Output file only supports one stream. "
181
- "Keeping only first audio stream."
185
+ "Output file only supports one stream. Keeping only first audio stream."
182
186
  )
183
187
  first_stream = list(self.streams["audio"].values())[0]
184
188
  self.streams["audio"] = {first_stream.stream_id: first_stream}
@@ -390,7 +394,12 @@ class MediaFile:
390
394
 
391
395
  # other audio options (if any)
392
396
  if self.ffmpeg_normalize.audio_bitrate:
393
- cmd.extend(["-b:a", str(self.ffmpeg_normalize.audio_bitrate)])
397
+ if self.ffmpeg_normalize.audio_codec == "libvorbis":
398
+ # libvorbis takes just a "-b" option, for some reason
399
+ # https://github.com/slhck/ffmpeg-normalize/issues/277
400
+ cmd.extend(["-b", str(self.ffmpeg_normalize.audio_bitrate)])
401
+ else:
402
+ cmd.extend(["-b:a", str(self.ffmpeg_normalize.audio_bitrate)])
394
403
  if self.ffmpeg_normalize.sample_rate:
395
404
  cmd.extend(["-ar", str(self.ffmpeg_normalize.sample_rate)])
396
405
  if self.ffmpeg_normalize.audio_channels:
@@ -420,13 +429,18 @@ class MediaFile:
420
429
  # if dry run, only show sample command
421
430
  if self.ffmpeg_normalize.dry_run:
422
431
  cmd.append(self.output_file)
432
+ _logger.warning("Dry run used, not actually running second-pass command")
423
433
  CommandRunner(dry=True).run_command(cmd)
424
434
  yield 100
425
435
  return
426
436
 
427
- temp_dir = mkdtemp()
428
- temp_file = os.path.join(temp_dir, f"out.{self.output_ext}")
429
- cmd.append(temp_file)
437
+ # special case: if output is a null device, write directly to it
438
+ if self.output_file == NUL:
439
+ cmd.append(self.output_file)
440
+ else:
441
+ temp_dir = mkdtemp()
442
+ temp_file = os.path.join(temp_dir, f"out.{self.output_ext}")
443
+ cmd.append(temp_file)
430
444
 
431
445
  cmd_runner = CommandRunner()
432
446
  try:
@@ -438,13 +452,15 @@ class MediaFile:
438
452
  )
439
453
  raise e
440
454
  else:
441
- _logger.debug(
442
- f"Moving temporary file from {temp_file} to {self.output_file}"
443
- )
444
- move(temp_file, self.output_file)
445
- rmtree(temp_dir, ignore_errors=True)
455
+ if self.output_file != NUL:
456
+ _logger.debug(
457
+ f"Moving temporary file from {temp_file} to {self.output_file}"
458
+ )
459
+ move(temp_file, self.output_file)
460
+ rmtree(temp_dir, ignore_errors=True)
446
461
  except Exception as e:
447
- rmtree(temp_dir, ignore_errors=True)
462
+ if self.output_file != NUL:
463
+ rmtree(temp_dir, ignore_errors=True)
448
464
  raise e
449
465
 
450
466
  output = cmd_runner.get_output()
@@ -1 +1 @@
1
- __version__ = "1.31.0"
1
+ __version__ = "1.31.2"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ffmpeg-normalize
3
- Version: 1.31.0
3
+ Version: 1.31.2
4
4
  Summary: Normalize audio via ffmpeg
5
5
  Home-page: https://github.com/slhck/ffmpeg-normalize
6
6
  Author: Werner Robitza
@@ -671,6 +671,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
671
671
  # Changelog
672
672
 
673
673
 
674
+ ## v1.31.2 (2025-03-19)
675
+
676
+ * Fix: special handling of /dev/null.
677
+
678
+
679
+ ## v1.31.1 (2025-02-19)
680
+
681
+ * Fix bitrate setting for libvorbis, fixes #277.
682
+
683
+ * Update issue templates.
684
+
685
+ * Prevent blank issues.
686
+
687
+
674
688
  ## v1.31.0 (2024-12-15)
675
689
 
676
690
  * Update docs and completions.
@@ -0,0 +1,16 @@
1
+ ffmpeg_normalize/__init__.py,sha256=aAhlk93ZE6SQcWUDzZQcw9vJh0bJcKEUNFGhVc5ZIto,453
2
+ ffmpeg_normalize/__main__.py,sha256=qOiycud87-wBceNLujaPZgWCTwJr7kaJM-IBvz4D7f4,19431
3
+ ffmpeg_normalize/_cmd_utils.py,sha256=S7PLXQAZHmJ30RM9K6b--vXuxMf-cQHtaFOPtILxz-4,5360
4
+ ffmpeg_normalize/_errors.py,sha256=brTQ4osJ4fTA8wnyMPVVYfGwJ0wqeShRFydTEwi_VEY,48
5
+ ffmpeg_normalize/_ffmpeg_normalize.py,sha256=JIVE03ZJi-jOvnc7OuftQEqloQwwyO7ZD3PIMFmIvbo,11283
6
+ ffmpeg_normalize/_logger.py,sha256=3Ap4Fxg7xGrzz7h4IGuNEf0KKstx0Rq_eLbHPrHzcrI,1841
7
+ ffmpeg_normalize/_media_file.py,sha256=ko5Jn0OxaDsIHbsm-CKWu96chf-8CA5aVUcxGUrPTEU,18863
8
+ ffmpeg_normalize/_streams.py,sha256=LIllXl4SKLxlyPVjD3ieHqc_byF2eUTjnK-clh2g_CY,20211
9
+ ffmpeg_normalize/_version.py,sha256=6MP_NMOhYOl3gX-No5ZuL2yHjzinJzxgtxqL3H5MNuc,23
10
+ ffmpeg_normalize/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ ffmpeg_normalize-1.31.2.dist-info/LICENSE,sha256=zeqAHGWrSIwdPHsZMZv1_N0gGFO1xxjcZEz9CplR4EM,1086
12
+ ffmpeg_normalize-1.31.2.dist-info/METADATA,sha256=CJJ8-L3WwkbJgfY_MBewdmtjGJmsMRcHRt62pXKj9DU,60274
13
+ ffmpeg_normalize-1.31.2.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
14
+ ffmpeg_normalize-1.31.2.dist-info/entry_points.txt,sha256=X0EC5ptb0iGOxrk3Aa65dVQtvUixngLd_2-iAtSixdc,68
15
+ ffmpeg_normalize-1.31.2.dist-info/top_level.txt,sha256=wnUkr17ckPrrU1JsxZQiXbEBUnHKsC64yck-MemEBuI,17
16
+ ffmpeg_normalize-1.31.2.dist-info/RECORD,,
@@ -1,16 +0,0 @@
1
- ffmpeg_normalize/__init__.py,sha256=aAhlk93ZE6SQcWUDzZQcw9vJh0bJcKEUNFGhVc5ZIto,453
2
- ffmpeg_normalize/__main__.py,sha256=AuyIcMU1WxGamczZtZyISfgMsEIt3Y1kSJ87dCoH9J4,19393
3
- ffmpeg_normalize/_cmd_utils.py,sha256=S7PLXQAZHmJ30RM9K6b--vXuxMf-cQHtaFOPtILxz-4,5360
4
- ffmpeg_normalize/_errors.py,sha256=brTQ4osJ4fTA8wnyMPVVYfGwJ0wqeShRFydTEwi_VEY,48
5
- ffmpeg_normalize/_ffmpeg_normalize.py,sha256=VoxhER57Ew0RKC_WcGpoCmyKKoqsHYuqNFMm7z4BPM4,11080
6
- ffmpeg_normalize/_logger.py,sha256=3Ap4Fxg7xGrzz7h4IGuNEf0KKstx0Rq_eLbHPrHzcrI,1841
7
- ffmpeg_normalize/_media_file.py,sha256=KUAjyI5hAGv5M-Y7NurrS8nmH0gelgIfw9CbLYWOWf8,17972
8
- ffmpeg_normalize/_streams.py,sha256=LIllXl4SKLxlyPVjD3ieHqc_byF2eUTjnK-clh2g_CY,20211
9
- ffmpeg_normalize/_version.py,sha256=jYtGJTa-bBcDTtE3IrYQBdcmjbk5Cfx7X6sxv2dEPwg,23
10
- ffmpeg_normalize/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
- ffmpeg_normalize-1.31.0.dist-info/LICENSE,sha256=zeqAHGWrSIwdPHsZMZv1_N0gGFO1xxjcZEz9CplR4EM,1086
12
- ffmpeg_normalize-1.31.0.dist-info/METADATA,sha256=TaXepF_i6VrztwLBsg8SEik_g3TOss4RQSTuX0RuUqI,60081
13
- ffmpeg_normalize-1.31.0.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
14
- ffmpeg_normalize-1.31.0.dist-info/entry_points.txt,sha256=X0EC5ptb0iGOxrk3Aa65dVQtvUixngLd_2-iAtSixdc,68
15
- ffmpeg_normalize-1.31.0.dist-info/top_level.txt,sha256=wnUkr17ckPrrU1JsxZQiXbEBUnHKsC64yck-MemEBuI,17
16
- ffmpeg_normalize-1.31.0.dist-info/RECORD,,