feat: add real-time TTS endpoint POST /api/tts

This commit is contained in:
TTS Service
2026-03-27 13:48:16 +08:00
parent a3f5f5d243
commit 6c5caa308d

View File

@@ -219,6 +219,71 @@ async def get_chapter_audio(book_id: str, chapter_id: str):
return FileResponse(chapter.audio_file, media_type="audio/mpeg", filename=f"{chapter_id}.mp3") return FileResponse(chapter.audio_file, media_type="audio/mpeg", filename=f"{chapter_id}.mp3")
# ── 实时 TTS 接口(兼容百度/阿里云风格)──────────────────────────────────
from fastapi.responses import Response
@app.post("/api/tts")
async def realtime_tts(request: Request):
"""
实时 TTS 生成接口
请求体 (JSON):
- text: 要合成的文本(必填)
- style: 风格(可选,如"开心""东北话"
- speed: 语速调整可选暂未使用MiMo 通过 style 控制语速)
返回: MP3 音频二进制流 (audio/mpeg)
"""
data = await request.json()
text = data.get("text", "").strip()
style = data.get("style", "").strip()
if not text:
return Response(
content=json.dumps({"status": 40000001, "message": "text 不能为空"}, ensure_ascii=False),
media_type="application/json",
status_code=400,
)
try:
# MiMo TTS 生成 WAV
wav_bytes = await call_mimo_tts(text, style)
# WAV → MP3内存中完成
tmp_dir = Path(config.AUDIO_DIR) / "_tmp"
tmp_dir.mkdir(parents=True, exist_ok=True)
tmp_id = uuid.uuid4().hex
wav_path = str(tmp_dir / f"{tmp_id}.wav")
mp3_path = str(tmp_dir / f"{tmp_id}.mp3")
with open(wav_path, "wb") as f:
f.write(wav_bytes)
loop = asyncio.get_event_loop()
await loop.run_in_executor(None, wav_to_mp3, wav_path, mp3_path)
with open(mp3_path, "rb") as f:
mp3_bytes = f.read()
# 清理临时文件
os.remove(wav_path)
os.remove(mp3_path)
return Response(content=mp3_bytes, media_type="audio/mpeg")
except HTTPException:
return Response(
content=json.dumps({"status": 50000001, "message": "TTS 生成失败"}, ensure_ascii=False),
media_type="application/json",
status_code=502,
)
except Exception as e:
return Response(
content=json.dumps({"status": 50000002, "message": str(e)[:300]}, ensure_ascii=False),
media_type="application/json",
status_code=500,
)
# ── 管理 API ────────────────────────────────────────────────────────────── # ── 管理 API ──────────────────────────────────────────────────────────────
# --- Books --- # --- Books ---