mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
Merge pull request #185 from denizsafak/refactor/use-backend-metadata-in-webui
refactor(webui): replace direct VOICES_INTERNAL/DEFAULT_SUPERTONIC_VOICES with get_metadata API
This commit is contained in:
@@ -79,6 +79,12 @@ def get_metadata(backend_id: str) -> TTSBackendMetadata:
|
||||
return _registry.get_metadata(backend_id)
|
||||
|
||||
|
||||
def get_default_voice(backend_id: str, fallback: str = "") -> str:
|
||||
"""Return the first voice of a backend, or *fallback* if none."""
|
||||
voices = get_metadata(backend_id).voices
|
||||
return voices[0] if voices else fallback
|
||||
|
||||
|
||||
def create_backend(backend_id: str, **kwargs: Any) -> TTSBackend:
|
||||
"""Create a TTS backend instance by provider id."""
|
||||
return _registry.create_backend(backend_id, **kwargs)
|
||||
|
||||
@@ -20,7 +20,7 @@ import numpy as np
|
||||
import soundfile as sf
|
||||
import static_ffmpeg
|
||||
|
||||
from abogen.constants import VOICES_INTERNAL
|
||||
from abogen.tts_backend_registry import get_metadata
|
||||
from abogen.epub3.exporter import build_epub3_package
|
||||
from abogen.kokoro_text_normalization import ApostropheConfig, normalize_for_pipeline, HAS_NUM2WORDS
|
||||
from abogen.normalization_settings import (
|
||||
@@ -47,7 +47,7 @@ from abogen.voice_formulas import extract_voice_ids, get_new_voice
|
||||
from abogen.voice_profiles import load_profiles, normalize_profile_entry
|
||||
from abogen.pronunciation_store import increment_usage
|
||||
from abogen.llm_client import LLMClientError
|
||||
from abogen.tts_backends.supertonic import DEFAULT_SUPERTONIC_VOICES
|
||||
|
||||
|
||||
from .service import Job, JobStatus
|
||||
|
||||
@@ -68,11 +68,11 @@ def _supertonic_voice_from_spec(spec: Any, fallback: str) -> str:
|
||||
raw = "M1"
|
||||
|
||||
upper = raw.upper()
|
||||
if upper in DEFAULT_SUPERTONIC_VOICES:
|
||||
if upper in get_metadata("supertonic").voices:
|
||||
return upper
|
||||
|
||||
fallback_upper = fallback_raw.upper() if fallback_raw else ""
|
||||
if fallback_upper in DEFAULT_SUPERTONIC_VOICES:
|
||||
if fallback_upper in get_metadata("supertonic").voices:
|
||||
return fallback_upper
|
||||
|
||||
return "M1"
|
||||
@@ -123,7 +123,7 @@ def _infer_provider_from_spec(value: Any, fallback: str = "kokoro") -> str:
|
||||
if not raw:
|
||||
return fallback
|
||||
upper = raw.upper()
|
||||
if upper in DEFAULT_SUPERTONIC_VOICES:
|
||||
if upper in get_metadata("supertonic").voices:
|
||||
return "supertonic"
|
||||
if "*" in raw or "+" in raw:
|
||||
return "kokoro"
|
||||
@@ -576,7 +576,7 @@ def _spec_to_voice_ids(spec: Any) -> Set[str]:
|
||||
return set(extract_voice_ids(text))
|
||||
except ValueError:
|
||||
return set()
|
||||
if text in VOICES_INTERNAL:
|
||||
if text in get_metadata("kokoro").voices:
|
||||
return {text}
|
||||
return set()
|
||||
|
||||
@@ -640,7 +640,7 @@ def _collect_required_voice_ids(job: Job) -> Set[str]:
|
||||
for key in ("resolved_voice", "voice_formula", "voice"):
|
||||
voices.update(_spec_to_voice_ids(payload.get(key)))
|
||||
|
||||
voices.update(VOICES_INTERNAL)
|
||||
voices.update(get_metadata("kokoro").voices)
|
||||
return voices
|
||||
|
||||
|
||||
@@ -1803,8 +1803,8 @@ def run_conversion_job(job: Job) -> None:
|
||||
fallback_key = next(iter(voice_cache.keys()), "")
|
||||
if fallback_key and fallback_key != "__custom_mix":
|
||||
intro_voice_spec = fallback_key.split(":", 1)[-1]
|
||||
if not intro_voice_spec and VOICES_INTERNAL:
|
||||
intro_voice_spec = VOICES_INTERNAL[0]
|
||||
if not intro_voice_spec:
|
||||
intro_voice_spec = get_default_voice("kokoro")
|
||||
|
||||
if intro_voice_spec:
|
||||
intro_provider, _, intro_voice_choice, intro_speed, intro_steps = resolve_voice_choice(
|
||||
@@ -2237,8 +2237,8 @@ def run_conversion_job(job: Job) -> None:
|
||||
if fallback_key and fallback_key != "__custom_mix":
|
||||
# `voice_cache` keys are internal and include provider prefixes.
|
||||
outro_voice_spec = fallback_key.split(":", 1)[-1]
|
||||
if not outro_voice_spec and VOICES_INTERNAL:
|
||||
outro_voice_spec = VOICES_INTERNAL[0]
|
||||
if not outro_voice_spec:
|
||||
outro_voice_spec = get_default_voice("kokoro")
|
||||
|
||||
if outro_text and outro_voice_spec:
|
||||
outro_start_time = current_time
|
||||
|
||||
@@ -32,7 +32,7 @@ from abogen.webui.routes.utils.common import split_profile_spec
|
||||
from abogen.utils import calculate_text_length
|
||||
from abogen.voice_profiles import serialize_profiles, normalize_profile_entry
|
||||
from abogen.chunking import ChunkLevel, build_chunks_for_chapters
|
||||
from abogen.constants import VOICES_INTERNAL
|
||||
from abogen.tts_backend_registry import get_default_voice
|
||||
from abogen.speaker_configs import get_config
|
||||
from abogen.kokoro_text_normalization import normalize_roman_numeral_titles
|
||||
from dataclasses import dataclass
|
||||
@@ -616,8 +616,8 @@ def apply_book_step_form(
|
||||
custom_formula = ""
|
||||
|
||||
base_voice_spec = resolved_default_voice or narrator_voice_raw
|
||||
if not base_voice_spec and VOICES_INTERNAL:
|
||||
base_voice_spec = VOICES_INTERNAL[0]
|
||||
if not base_voice_spec:
|
||||
base_voice_spec = get_default_voice("kokoro")
|
||||
|
||||
voice_choice, resolved_language, selected_profile = resolve_voice_choice(
|
||||
pending.language,
|
||||
@@ -796,8 +796,8 @@ def build_pending_job_from_extraction(
|
||||
profile_selection = inferred_profile
|
||||
|
||||
base_voice = base_voice_input or resolved_default_voice or str(default_voice_setting).strip()
|
||||
if not base_voice and VOICES_INTERNAL:
|
||||
base_voice = VOICES_INTERNAL[0]
|
||||
if not base_voice:
|
||||
base_voice = get_default_voice("kokoro")
|
||||
selected_speaker_config = (form.get("speaker_config") or "").strip()
|
||||
speaker_config_payload = get_config(selected_speaker_config) if selected_speaker_config else None
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ from abogen.constants import (
|
||||
LANGUAGE_DESCRIPTIONS,
|
||||
SUBTITLE_FORMATS,
|
||||
SUPPORTED_SOUND_FORMATS,
|
||||
VOICES_INTERNAL,
|
||||
)
|
||||
from abogen.tts_backend_registry import get_default_voice
|
||||
from abogen.normalization_settings import (
|
||||
DEFAULT_LLM_PROMPT,
|
||||
environment_llm_defaults,
|
||||
@@ -174,7 +174,7 @@ def settings_defaults() -> Dict[str, Any]:
|
||||
"subtitle_format": "srt",
|
||||
"save_mode": "default_output" if has_output_override() else "save_next_to_input",
|
||||
"default_speaker": "",
|
||||
"default_voice": VOICES_INTERNAL[0] if VOICES_INTERNAL else "",
|
||||
"default_voice": get_default_voice("kokoro"),
|
||||
"supertonic_total_steps": 5,
|
||||
"supertonic_speed": 1.0,
|
||||
"replace_single_newlines": False,
|
||||
|
||||
@@ -17,8 +17,8 @@ from abogen.constants import (
|
||||
SUPPORTED_SOUND_FORMATS,
|
||||
SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION,
|
||||
SAMPLE_VOICE_TEXTS,
|
||||
VOICES_INTERNAL,
|
||||
)
|
||||
from abogen.tts_backend_registry import get_metadata
|
||||
from abogen.speaker_configs import list_configs
|
||||
from abogen.tts_backend_registry import create_backend
|
||||
from abogen.webui.conversion_runner import _select_device, _to_float32, SAMPLE_RATE, SPLIT_PATTERN
|
||||
@@ -285,7 +285,7 @@ def filter_voice_catalog(
|
||||
def build_voice_catalog() -> List[Dict[str, str]]:
|
||||
catalog: List[Dict[str, str]] = []
|
||||
gender_map = {"f": "Female", "m": "Male"}
|
||||
for voice_id in VOICES_INTERNAL:
|
||||
for voice_id in get_metadata("kokoro").voices:
|
||||
prefix, _, rest = voice_id.partition("_")
|
||||
language_code = prefix[0] if prefix else "a"
|
||||
gender_code = prefix[1] if len(prefix) > 1 else ""
|
||||
@@ -590,7 +590,7 @@ def template_options() -> Dict[str, Any]:
|
||||
voice_catalog = build_voice_catalog()
|
||||
return {
|
||||
"languages": LANGUAGE_DESCRIPTIONS,
|
||||
"voices": VOICES_INTERNAL,
|
||||
"voices": get_metadata("kokoro").voices,
|
||||
"subtitle_formats": SUBTITLE_FORMATS,
|
||||
"supported_langs_for_subs": SUPPORTED_LANGUAGES_FOR_SUBTITLE_GENERATION,
|
||||
"output_formats": SUPPORTED_SOUND_FORMATS,
|
||||
|
||||
@@ -17,7 +17,7 @@ from abogen.speaker_configs import (
|
||||
save_configs,
|
||||
delete_config,
|
||||
)
|
||||
from abogen.constants import VOICES_INTERNAL
|
||||
|
||||
|
||||
voices_bp = Blueprint("voices", __name__)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user