mirror of
https://github.com/denizsafak/abogen.git
synced 2026-07-18 13:40:27 +02:00
- Add get_default_voice() helper to tts_backend_registry - Replace all VOICES_INTERNAL imports in WebUI with get_metadata().voices - Replace all DEFAULT_SUPERTONIC_VOICES imports in conversion_runner with get_metadata().voices - Remove unused VOICES_INTERNAL import from voices.py Core modules (voice_profiles, voice_formulas, voice_cache) already used get_metadata(). This completes the WebUI migration.
141 lines
4.4 KiB
Python
141 lines
4.4 KiB
Python
from typing import Any, Dict, List, Optional
|
|
from flask import Blueprint, render_template, request, jsonify, abort, flash, redirect, url_for
|
|
from flask.typing import ResponseReturnValue
|
|
|
|
from abogen.webui.routes.utils.voice import (
|
|
template_options,
|
|
resolve_voice_setting,
|
|
resolve_voice_choice,
|
|
parse_voice_formula,
|
|
)
|
|
from abogen.webui.routes.utils.settings import load_settings, coerce_bool
|
|
from abogen.webui.routes.utils.preview import synthesize_preview
|
|
from abogen.speaker_configs import (
|
|
list_configs,
|
|
get_config,
|
|
load_configs,
|
|
save_configs,
|
|
delete_config,
|
|
)
|
|
|
|
|
|
voices_bp = Blueprint("voices", __name__)
|
|
|
|
@voices_bp.get("/")
|
|
def voice_profiles() -> ResponseReturnValue:
|
|
return render_template("voices.html", options=template_options())
|
|
|
|
@voices_bp.post("/test")
|
|
def test_voice() -> ResponseReturnValue:
|
|
text = (request.form.get("text") or "").strip()
|
|
voice = (request.form.get("voice") or "").strip()
|
|
speed = float(request.form.get("speed", 1.0))
|
|
|
|
# This seems to be the form-based preview
|
|
settings = load_settings()
|
|
use_gpu = coerce_bool(settings.get("use_gpu"), True)
|
|
|
|
try:
|
|
return synthesize_preview(
|
|
text=text,
|
|
voice_spec=voice,
|
|
language="a", # Default language
|
|
speed=speed,
|
|
use_gpu=use_gpu,
|
|
)
|
|
except Exception as e:
|
|
abort(400, str(e))
|
|
|
|
@voices_bp.get("/configs")
|
|
def speaker_configs() -> ResponseReturnValue:
|
|
return jsonify({"configs": list_configs()})
|
|
|
|
@voices_bp.post("/configs/save")
|
|
def save_speaker_config() -> ResponseReturnValue:
|
|
payload = request.get_json(force=True)
|
|
name = (payload.get("name") or "").strip()
|
|
config = payload.get("config")
|
|
|
|
if not name:
|
|
abort(400, "Config name is required")
|
|
if not config:
|
|
abort(400, "Config data is required")
|
|
|
|
configs = load_configs()
|
|
configs[name] = config
|
|
save_configs(configs)
|
|
return jsonify({"status": "saved", "configs": list_configs()})
|
|
|
|
@voices_bp.post("/configs/delete")
|
|
def delete_speaker_config() -> ResponseReturnValue:
|
|
payload = request.get_json(force=True)
|
|
name = (payload.get("name") or "").strip()
|
|
|
|
if not name:
|
|
abort(400, "Config name is required")
|
|
|
|
delete_config(name)
|
|
return jsonify({"status": "deleted", "configs": list_configs()})
|
|
|
|
@voices_bp.route("/presets", methods=["GET", "POST"])
|
|
def speaker_configs_page() -> ResponseReturnValue:
|
|
configs = load_configs()
|
|
editing_name = request.args.get("config")
|
|
message = None
|
|
error = None
|
|
|
|
if request.method == "POST":
|
|
try:
|
|
name = request.form.get("config_name", "").strip()
|
|
if not name:
|
|
raise ValueError("Preset name is required")
|
|
|
|
language = request.form.get("config_language", "en")
|
|
|
|
speakers = []
|
|
row_keys = request.form.getlist("speaker_rows")
|
|
for key in row_keys:
|
|
s_id = request.form.get(f"speaker-{key}-id", key)
|
|
label = request.form.get(f"speaker-{key}-label", "")
|
|
gender = request.form.get(f"speaker-{key}-gender", "unknown")
|
|
voice = request.form.get(f"speaker-{key}-voice", "")
|
|
|
|
if label:
|
|
speakers.append({
|
|
"id": s_id,
|
|
"label": label,
|
|
"gender": gender,
|
|
"voice": voice or None
|
|
})
|
|
|
|
config = {
|
|
"name": name,
|
|
"language": language,
|
|
"speakers": speakers,
|
|
"version": 1
|
|
}
|
|
|
|
configs[name] = config
|
|
save_configs(configs)
|
|
message = f"Preset '{name}' saved."
|
|
editing_name = name
|
|
except Exception as e:
|
|
error = str(e)
|
|
|
|
editing = configs.get(editing_name, {}) if editing_name else {}
|
|
|
|
return render_template(
|
|
"speakers.html",
|
|
options=template_options(),
|
|
configs=configs.values(),
|
|
editing_name=editing_name,
|
|
editing=editing,
|
|
message=message,
|
|
error=error
|
|
)
|
|
|
|
@voices_bp.post("/presets/<name>/delete")
|
|
def delete_speaker_config_named(name: str) -> ResponseReturnValue:
|
|
delete_config(name)
|
|
return redirect(url_for("voices.speaker_configs_page"))
|