aboutsummaryrefslogtreecommitdiff
path: root/backends/faster.py
diff options
context:
space:
mode:
authorhistoria <historiavg@proton.me>2026-08-24 01:57:13 -0400
committerhistoria <historiavg@proton.me>2026-08-24 01:58:17 -0400
commitc02d66b2d3221c0c5f5e8f2cb2ae218f1e325a0a (patch)
treee9ec4f35c18102d4624d3cd59358d192be7bbfcb /backends/faster.py
parent194c63e4d11e6de9792a736a7b99788f1db78741 (diff)
downloadtts-audiobook-generator-c02d66b2d3221c0c5f5e8f2cb2ae218f1e325a0a.tar.gz
feat: manage venv for all backends
Diffstat (limited to 'backends/faster.py')
-rwxr-xr-xbackends/faster.py63
1 files changed, 40 insertions, 23 deletions
diff --git a/backends/faster.py b/backends/faster.py
index 71be050..50c6102 100755
--- a/backends/faster.py
+++ b/backends/faster.py
@@ -17,7 +17,6 @@ Usage:
"""
import argparse
-import importlib.util
import json
import sys
from pathlib import Path
@@ -25,13 +24,27 @@ from typing import List, Optional
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
-from ui import tui
-from backends import BackendStatus, ConfigureAction
-from backends import common
-from backends.common import TTS_ROOT, find_wav_files, normalize_dir_arg
+from backends import (
+ BackendStatus,
+ ConfigureAction,
+ ServerSpec,
+ common,
+ envs,
+ format_launch_hint,
+)
+from backends.common import (
+ TTS_ROOT,
+ VOICES_DIR,
+ find_wav_files,
+ normalize_dir_arg,
+)
from converter import config
-from converter.tts import normalize_language, transcribe_reference_audio, \
- whisper_backend_available
+from converter.tts import (
+ normalize_language,
+ transcribe_reference_audio,
+ whisper_backend_available,
+)
+from ui import tui
FASTER_DIR_NAME = "faster-qwen3-tts"
FASTER_GIT_URL = "https://github.com/andimarafioti/faster-qwen3-tts"
@@ -44,7 +57,7 @@ def _checkout() -> Path:
def _is_installed() -> bool:
- return importlib.util.find_spec("faster_qwen3_tts") is not None
+ return envs.module_available("faster_qwen3_tts")
def _is_cloned() -> bool:
@@ -133,7 +146,7 @@ def _wizard(stdscr, args: argparse.Namespace) -> Optional[dict]:
wav_dir = tui.browse_directory(
stdscr, "Select the directory with your .wav voices",
info=common.wav_dir_info, preview=common.wav_dir_preview,
- start=Path.cwd())
+ start=VOICES_DIR)
language = args.language
if language is None:
lang_text = tui.line_edit(
@@ -239,8 +252,9 @@ def _execute(settings: dict) -> int:
def _print_launch_hint(voices_path: Path, port: int) -> None:
print()
if _is_cloned():
- print("Start the server with:")
- print(f" python {_checkout()}/examples/openai_server.py "
+ py = envs.env_python()
+ print("Start the server with (or use the hub's 'Server' menu):")
+ print(f" {py} {_checkout()}/examples/openai_server.py "
f"--voices {voices_path} --port {port}")
else:
print("[INFO] Clone faster-qwen3-tts to get examples/openai_server.py,")
@@ -270,25 +284,23 @@ def run_tui(args: Optional[argparse.Namespace] = None) -> int:
def _collect_from_flags(args: argparse.Namespace,
parser: argparse.ArgumentParser) -> Optional[dict]:
"""Build the settings dict from flags for a non-interactive run."""
- if args.input_dir is None:
- parser.error("--wavs is required in a non-interactive run (or run "
- "without flags for the TUI wizard)")
- if not args.input_dir.is_dir():
- parser.error(f"WAV directory not found: {args.input_dir}")
+ wav_dir = args.input_dir if args.input_dir is not None else VOICES_DIR
+ if not wav_dir.is_dir():
+ parser.error(f"WAV directory not found: {wav_dir}")
try:
language = normalize_language(args.language or config.LANGUAGE)
except ValueError as exc:
parser.error(str(exc))
output_path = args.output if args.output is not None \
else ((_checkout() / "voices.json") if _is_cloned()
- else (args.input_dir / "voices.json"))
+ else (wav_dir / "voices.json"))
if output_path.exists() and not args.force:
print("[INFO] Aborted; existing voices.json kept")
return None
return {
"do_install": (not _is_installed()) and not args.skip_install,
"do_clone": (not _is_cloned()) and not args.skip_clone,
- "wav_dir": args.input_dir,
+ "wav_dir": wav_dir,
"language": language,
"whisper_model": args.whisper_model or "base",
"output_path": output_path,
@@ -303,8 +315,8 @@ def build_parser() -> argparse.ArgumentParser:
"build voices.json, and sync converter/config.py.")
parser.add_argument("input_dir", type=normalize_dir_arg, nargs="?",
default=None, metavar="WAV_DIR",
- help="Directory with .wav reference files (required in "
- "a non-interactive run; browsed for in the TUI)")
+ help="Directory with .wav reference files "
+ f"(default: {VOICES_DIR}; browsed for in the TUI)")
parser.add_argument("--output", type=Path, default=None,
help="Output path for voices.json (default: "
"./faster-qwen3-tts/voices.json, or "
@@ -344,13 +356,18 @@ def detect() -> BackendStatus:
details.append(f"voices: {voices_json}" if voices_json.exists() else
"no voices.json — run setup to create one")
launch = ""
+ servers: List[ServerSpec] = []
if cloned and voices_json.exists():
- launch = (f"python {_checkout()}/examples/openai_server.py "
- f"--voices {voices_json} --port {_config_port()}")
+ argv = [str(envs.env_python()),
+ str(_checkout() / "examples" / "openai_server.py"),
+ "--voices", str(voices_json), "--port", str(_config_port())]
+ servers = [ServerSpec("faster", config.FASTER_API_URL, argv)]
+ launch = format_launch_hint(servers)
return BackendStatus("faster", "faster-qwen3-tts",
installed=installed and cloned,
configured=configured, running=running,
- details=details, launch_hint=launch)
+ details=details, launch_hint=launch,
+ servers=servers)
def _run_voices_only_tui() -> int: