aboutsummaryrefslogtreecommitdiff
path: root/tools/make_faster_voices_json.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-23 23:48:25 -0400
committerhistoria <historiavg@proton.me>2026-08-23 23:48:25 -0400
commit5bfbdcb5765fd4eb57d13c67169bb3c2706ead75 (patch)
treea07a27976f56a449e8c33641161553aa0989f5c2 /tools/make_faster_voices_json.py
parent07f7b351f2956b6c92761877c9a4314bcede3b6e (diff)
downloadtts-audiobook-generator-5bfbdcb5765fd4eb57d13c67169bb3c2706ead75.tar.gz
feat: audiobook.py tui: convert, modify, or install backends
Diffstat (limited to 'tools/make_faster_voices_json.py')
-rwxr-xr-xtools/make_faster_voices_json.py121
1 files changed, 0 insertions, 121 deletions
diff --git a/tools/make_faster_voices_json.py b/tools/make_faster_voices_json.py
deleted file mode 100755
index 2e00f72..0000000
--- a/tools/make_faster_voices_json.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python3
-"""Generate a voices.json file for the faster-qwen3-tts server.
-
-Scans a directory for .wav files, transcribes each with a local Whisper
-backend (faster_whisper or whisper), and writes a voices.json
-
-Usage:
- python tools/make_faster_voices_json.py INPUT_DIR [--output PATH]
- [--language LANG]
- [--whisper-model NAME] [--force]
-
-The output can be passed to the faster server:
- python examples/openai_server.py --voices voices.json --port 8000
-"""
-
-import argparse
-import json
-import sys
-from pathlib import Path
-
-# Allow running from any working directory.
-sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
-
-from converter.tts import normalize_language, transcribe_reference_audio
-
-
-def find_wav_files(input_dir: Path) -> list:
- """Return the .wav files in INPUT_DIR, sorted alphabetically by name."""
- return sorted(
- (path for path in input_dir.iterdir()
- if path.is_file() and path.suffix.lower() == ".wav"),
- key=lambda path: path.name.lower(),
- )
-
-
-def prompt_overwrite(output_path: Path) -> bool:
- """Ask whether to overwrite an existing output file."""
- while True:
- try:
- answer = input(f"{output_path} already exists. Overwrite? (y/n): ").strip().lower()
- except EOFError:
- print("\n[WARNING] No interactive input available; keeping existing file")
- return False
- if answer in ("y", "yes"):
- return True
- if answer in ("n", "no"):
- return False
- print("Please answer 'y' or 'n'.")
-
-
-def build_voices(wav_files: list, language: str, whisper_model: str) -> dict:
- """Transcribe each wav file and build the voices mapping."""
- voices = {}
- for wav_file in wav_files:
- name = wav_file.stem
- print(f"[INFO] Transcribing {wav_file.name} (voice '{name}')...")
- text = transcribe_reference_audio(str(wav_file), model_name=whisper_model)
- if text:
- print(f"[OK] {name}: {text}")
- else:
- print(f"[WARNING] No transcript for '{name}'; the faster backend "
- "strongly recommends an accurate transcript — consider editing "
- "voices.json by hand before starting the server")
- voices[name] = {
- "ref_audio": str(wav_file.resolve()),
- "ref_text": text or "",
- "language": language,
- }
- return voices
-
-
-def main() -> int:
- parser = argparse.ArgumentParser(
- description="Generate a voices.json for the faster-qwen3-tts server "
- "from a directory of .wav reference files.")
- parser.add_argument("input_dir", type=Path,
- help="Directory containing .wav reference audio files")
- parser.add_argument("--output", type=Path, default=None,
- help="Output path for voices.json "
- "(default: INPUT_DIR/voices.json)")
- parser.add_argument("--language", type=str, default="English",
- help="Language for all voices, as passed to the TTS model "
- "(default: English; names and short codes accepted)")
- parser.add_argument("--whisper-model", type=str, default="base",
- help="Whisper model size for transcription "
- "(default: base)")
- parser.add_argument("--force", action="store_true",
- help="Overwrite the output file without prompting")
- args = parser.parse_args()
-
- try:
- language = normalize_language(args.language)
- except ValueError as exc:
- parser.error(str(exc))
-
- if not args.input_dir.is_dir():
- parser.error(f"Input directory not found: {args.input_dir}")
-
- wav_files = find_wav_files(args.input_dir)
- if not wav_files:
- parser.error(f"No .wav files found in {args.input_dir}")
-
- output_path = args.output if args.output is not None \
- else args.input_dir / "voices.json"
- if output_path.exists() and not args.force and not prompt_overwrite(output_path):
- print("[INFO] Aborted; existing voices.json kept")
- return 1
-
- voices = build_voices(wav_files, language, args.whisper_model)
-
- with output_path.open("w", encoding="utf-8") as handle:
- json.dump(voices, handle, indent=4, ensure_ascii=False)
- handle.write("\n")
-
- print(f"[OK] Wrote {output_path} with {len(voices)} voice(s): "
- f"{', '.join(voices)}")
- return 0
-
-
-if __name__ == "__main__":
- sys.exit(main())