init
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
from typing import Optional
|
||||
|
||||
import numpy as np
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TTSService:
|
||||
def __init__(self) -> None:
|
||||
self._pipeline = None
|
||||
self._ready = False
|
||||
self._attempted = False
|
||||
self._init_error: Optional[str] = None
|
||||
|
||||
def _ensure_loaded(self) -> None:
|
||||
if self._ready or self._attempted:
|
||||
return
|
||||
self._attempted = True
|
||||
try:
|
||||
import kokoro
|
||||
|
||||
self._pipeline = kokoro.KPipeline(lang_code="z")
|
||||
self._ready = True
|
||||
except Exception as exc: # pragma: no cover
|
||||
self._init_error = str(exc)
|
||||
logger.warning("TTS fallback mode: %s", exc)
|
||||
|
||||
async def synthesize(self, text: str) -> tuple[np.ndarray, int]:
|
||||
self._ensure_loaded()
|
||||
if self._ready and self._pipeline is not None:
|
||||
chunks = []
|
||||
for _, _, audio in self._pipeline(text, voice="zf_xiaoxiao"):
|
||||
chunks.append(audio)
|
||||
if chunks:
|
||||
return np.concatenate(chunks), 24000
|
||||
|
||||
# 0.5s silence fallback for flow verification
|
||||
return np.zeros(12000, dtype=np.float32), 24000
|
||||
|
||||
@property
|
||||
def health(self) -> dict:
|
||||
return {"ready": self._ready, "attempted": self._attempted, "error": self._init_error}
|
||||
Reference in New Issue
Block a user