Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI | |
| from fastapi.responses import FileResponse, JSONResponse | |
| from pydantic import BaseModel | |
| import asyncio | |
| import tempfile | |
| import subprocess | |
| import os | |
| import gc | |
| import torch | |
| app = FastAPI() | |
| # Chỉ cho chạy 1 request mỗi lần | |
| lock = asyncio.Semaphore(1) | |
| # ========================= | |
| # Request model | |
| # ========================= | |
| class TTSRequest(BaseModel): | |
| text: str | |
| # ========================= | |
| # Root | |
| # ========================= | |
| async def root(): | |
| return {"status": "running"} | |
| # ========================= | |
| # TTS Endpoint | |
| # ========================= | |
| async def tts(req: TTSRequest): | |
| async with lock: | |
| # Kiểm tra text | |
| if not req.text.strip(): | |
| return JSONResponse( | |
| status_code=400, | |
| content={ | |
| "success": False, | |
| "error": "Text is empty" | |
| } | |
| ) | |
| # Tạo file wav tạm | |
| temp_wav = tempfile.NamedTemporaryFile( | |
| suffix=".wav", | |
| delete=False | |
| ) | |
| output_path = temp_wav.name | |
| temp_wav.close() | |
| try: | |
| # Command OmniVoice | |
| cmd = [ | |
| "omnivoice-infer", | |
| "--text", req.text, | |
| "--output", output_path, | |
| ] | |
| print("Running command:") | |
| print(" ".join(cmd)) | |
| # Chạy subprocess | |
| result = subprocess.run( | |
| cmd, | |
| capture_output=True, | |
| text=True | |
| ) | |
| # Logs debug | |
| print("STDOUT:") | |
| print(result.stdout) | |
| print("STDERR:") | |
| print(result.stderr) | |
| # Nếu command lỗi | |
| if result.returncode != 0: | |
| return JSONResponse( | |
| status_code=500, | |
| content={ | |
| "success": False, | |
| "error": result.stderr | |
| } | |
| ) | |
| # Không tạo file | |
| if not os.path.exists(output_path): | |
| return JSONResponse( | |
| status_code=500, | |
| content={ | |
| "success": False, | |
| "error": "Audio file not created" | |
| } | |
| ) | |
| # File rỗng | |
| if os.path.getsize(output_path) == 0: | |
| return JSONResponse( | |
| status_code=500, | |
| content={ | |
| "success": False, | |
| "error": "Audio file empty" | |
| } | |
| ) | |
| # Trả audio | |
| return FileResponse( | |
| path=output_path, | |
| media_type="audio/wav", | |
| filename="tts.wav" | |
| ) | |
| except Exception as e: | |
| print("EXCEPTION:") | |
| print(str(e)) | |
| return JSONResponse( | |
| status_code=500, | |
| content={ | |
| "success": False, | |
| "error": str(e) | |
| } | |
| ) | |
| finally: | |
| # Cleanup RAM | |
| gc.collect() | |
| if torch.cuda.is_available(): | |
| torch.cuda.empty_cache() |