aboutsummaryrefslogtreecommitdiff
path: root/converter/converter.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-18 01:56:25 -0400
committerhistoria <historiavg@proton.me>2026-08-18 01:56:25 -0400
commitd72d274bd9895bdf97d31d56690b7df07fa74ad4 (patch)
tree85b001881055fa1f7087de84a162a8a5a880484a /converter/converter.py
parent68ee76514a98169a5e7a075648b70ab40417fbdf (diff)
downloadtts-audiobook-generator-d72d274bd9895bdf97d31d56690b7df07fa74ad4.tar.gz
fix: timing/punctuation edge cases, process chunks as uncompressed wavs
Diffstat (limited to 'converter/converter.py')
-rw-r--r--converter/converter.py18
1 files changed, 13 insertions, 5 deletions
diff --git a/converter/converter.py b/converter/converter.py
index f63a412..0454892 100644
--- a/converter/converter.py
+++ b/converter/converter.py
@@ -130,12 +130,17 @@ class AudiobookConverter:
def _convert_m4b_with_chapters(self, sections, stem: str, start_time: float) -> bool:
"""Convert each chapter to audio, then assemble a single m4b with
- embedded chapter markers."""
+ embedded chapter markers.
+
+ Chapters are synthesized to lossless WAV scratch files (~170 MB per
+ hour of audio) so the final AAC pass is the only lossy encode.
+ """
chapter_files = []
titles = []
for index, section in enumerate(sections, 1):
- chapter_path = config.CHUNKS_FOLDER / f"chapter_{index:04d}.{self.output_format}"
- if not self._convert_text(section.text, chapter_path, start_time, speed=1.0):
+ chapter_path = config.CHUNKS_FOLDER / f"chapter_{index:04d}.wav"
+ if not self._convert_text(section.text, chapter_path, start_time,
+ speed=1.0, output_format="wav"):
logger.warning("Skipping chapter %d (%s) due to conversion failure",
index, section.title)
continue
@@ -150,10 +155,13 @@ class AudiobookConverter:
return audio.combine_chapters_to_m4b(chapter_files, titles, output_path, speed=self.speed)
def _convert_text(self, text: str, output_path: Path, start_time: float,
- speed: Optional[float] = None) -> bool:
+ speed: Optional[float] = None,
+ output_format: Optional[str] = None) -> bool:
"""Chunk, synthesize, and assemble ``text`` into ``output_path``."""
if speed is None:
speed = self.speed
+ if output_format is None:
+ output_format = self.output_format
try:
if not text.strip():
@@ -217,7 +225,7 @@ class AudiobookConverter:
# Combine chunks (only the successful ones)
success = audio.combine_chunks(total_chunks, output_path, results,
- speed=speed, output_format=self.output_format)
+ speed=speed, output_format=output_format)
if success:
duration = time.time() - start_time