aboutsummaryrefslogtreecommitdiff
path: root/app/converter/audio.py
diff options
context:
space:
mode:
Diffstat (limited to 'app/converter/audio.py')
-rw-r--r--app/converter/audio.py13
1 files changed, 11 insertions, 2 deletions
diff --git a/app/converter/audio.py b/app/converter/audio.py
index 9df7aff..9536788 100644
--- a/app/converter/audio.py
+++ b/app/converter/audio.py
@@ -6,6 +6,7 @@ threads them through, so there is no module-global path to mutate.
"""
import logging
+import math
import re
import shutil
import subprocess
@@ -29,7 +30,12 @@ def atempo_filters(speed: float) -> str:
``atempo`` accepts 0.5..2.0 per filter; values outside that range are
handled by chaining multiple filters. Returns "" when ``speed`` is 1.0.
+ Non-finite values (``inf``, ``nan``) are rejected: they pass a bare
+ ``> 0`` check and would either loop forever (``inf / 2.0`` stays
+ ``inf``) or produce an invalid tempo expression.
"""
+ if not math.isfinite(speed):
+ raise ValueError(f"Speed must be a finite number, got {speed}")
if speed <= 0:
raise ValueError(f"Speed must be a positive number, got {speed}")
if abs(speed - 1.0) < SPEED_EPSILON:
@@ -252,7 +258,10 @@ def build_concat_command(concat_list: Path, output_path: Path, output_format: st
raise ValueError("speed_path is required when speed is not 1.0")
return [
"ffmpeg", "-y", *inputs, "-filter_complex",
- f"[0:a]split=2[base][spd];[spd]{filters}[spdout]",
+ # asplit (not split): split is a video filter and rejects
+ # audio streams, which would fail every speed-adjusted
+ # assembly after synthesis had already completed.
+ f"[0:a]asplit=2[base][spd];[spd]{filters}[spdout]",
"-map", "[base]", *encode, *tags, *cover_block, *container, str(output_path),
"-map", "[spdout]", *encode, *tags, *cover_block, *container, str(speed_path),
]
@@ -290,7 +299,7 @@ def build_m4b_chapters_command(concat_list: Path, metadata_file: Path, output_pa
if speed_path is not None:
return [
"ffmpeg", "-y", *inputs, "-filter_complex",
- f"[0:a]split=2[base][spd];[spd]{atempo_filters(speed)}[spdout]",
+ f"[0:a]asplit=2[base][spd];[spd]{atempo_filters(speed)}[spdout]",
"-map", "[base]", *cover_block, "-map_metadata", "1", "-map_chapters", "1",
*encode, *tags, *container, str(output_path),
"-map", "[spdout]", *cover_block, "-map_metadata", "2", "-map_chapters", "2",