60 lines
1.4 KiB
Python
60 lines
1.4 KiB
Python
from pathlib import Path
|
|
from threading import Lock
|
|
|
|
from fastapi import FastAPI
|
|
from pydantic import BaseModel, Field
|
|
|
|
app = FastAPI(title="Emotion Museum TTS")
|
|
|
|
_model = None
|
|
_speaker_ids = None
|
|
_model_lock = Lock()
|
|
|
|
|
|
class SynthesizeRequest(BaseModel):
|
|
text: str = Field(min_length=1, max_length=5000)
|
|
voice: str = "default_zh_female"
|
|
outputPath: str
|
|
|
|
|
|
def get_model():
|
|
global _model, _speaker_ids
|
|
with _model_lock:
|
|
if _model is None:
|
|
from melo.api import TTS
|
|
|
|
_model = TTS(language="ZH", device="cpu")
|
|
_speaker_ids = _model.hps.data.spk2id
|
|
return _model, _speaker_ids
|
|
|
|
|
|
@app.get("/health")
|
|
def health():
|
|
return {"status": "ok"}
|
|
|
|
|
|
@app.post("/synthesize")
|
|
def synthesize(request: SynthesizeRequest):
|
|
output = Path(request.outputPath)
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
try:
|
|
model, speaker_ids = get_model()
|
|
speaker_id = speaker_ids.get("ZH")
|
|
model.tts_to_file(request.text, speaker_id, str(output), speed=1.0)
|
|
except Exception as exc:
|
|
return {
|
|
"success": False,
|
|
"audioPath": None,
|
|
"durationMs": None,
|
|
"engine": "melotts",
|
|
"errorMessage": str(exc),
|
|
}
|
|
|
|
return {
|
|
"success": True,
|
|
"audioPath": str(output),
|
|
"durationMs": None,
|
|
"engine": "melotts",
|
|
}
|