| from fastapi import APIRouter, HTTPException |
| from fastapi.responses import FileResponse |
| from models.tts import TTSRequest |
| from services.tts_service import text_to_speech, text_to_speech_base64 |
| from pathlib import Path |
|
|
| router = APIRouter(prefix="/tts", tags=["Text To Speech"]) |
|
|
| @router.post("/") |
| async def generate_tts(request: TTSRequest): |
| """ |
| Convert text to speech using the free gTTS backend (MP3 only). |
| Can return either Base64 or file based on return_base64 parameter. |
| """ |
| try: |
| |
| if getattr(request, "return_base64", False): |
| result = text_to_speech_base64( |
| text=request.text, |
| voice=request.voice, |
| fmt=request.format, |
| ) |
|
|
| return { |
| "success": True, |
| "audio_base64": result["audio_base64"], |
| "mime_type": result["mime_type"], |
| "format": result["format"], |
| "filename": result["filename"], |
| "size_bytes": result["size_bytes"], |
| "size_base64": result["size_base64"] |
| } |
|
|
| |
| else: |
| audio_path = text_to_speech( |
| text=request.text, |
| voice=request.voice, |
| fmt=request.format, |
| ) |
|
|
| if not Path(audio_path).exists(): |
| raise HTTPException(status_code=500, detail="Audio file generation failed") |
|
|
| media_type = "audio/mpeg" |
|
|
| return FileResponse( |
| path=audio_path, |
| filename=f"speech.{request.format}", |
| media_type=media_type, |
| headers={ |
| "Content-Disposition": f"attachment; filename=speech.{request.format}" |
| }, |
| ) |
|
|
| except ValueError as e: |
| raise HTTPException(status_code=400, detail=str(e)) |
| except Exception as e: |
| raise HTTPException(status_code=500, detail=str(e)) |
| except Exception as e: |
| raise HTTPException(status_code=500, detail=str(e)) |