| | from fastapi import FastAPI, Response, HTTPException |
| | from fastapi.middleware.cors import CORSMiddleware |
| | from melo.api import TTS |
| | import os |
| |
|
| | app = FastAPI() |
| |
|
| | app.add_middleware( |
| | CORSMiddleware, |
| | allow_origins=["*"], |
| | allow_methods=["*"], |
| | allow_headers=["*"], |
| | ) |
| |
|
| | |
| | models = {} |
| | device = 'cpu' |
| |
|
| | print("⏳ Initialisation de MeloTTS...") |
| |
|
| | try: |
| | |
| | print(" - Chargement FR...") |
| | models['FR'] = TTS(language='FR', device=device) |
| | |
| | print(" - Chargement EN...") |
| | models['EN'] = TTS(language='EN', device=device) |
| | |
| | print("✅ MeloTTS Prêt (FR + EN) !") |
| | except Exception as e: |
| | print(f"❌ Erreur au chargement : {e}") |
| |
|
| | @app.post("/tts") |
| | async def generate_speech(data: dict): |
| | text = data.get("text", "") |
| | lang = data.get("lang", "FR").upper() |
| | speed = data.get("speed", 1.0) |
| |
|
| | if not text: |
| | raise HTTPException(status_code=400, detail="Texte vide") |
| |
|
| | |
| | if lang not in models: |
| | try: |
| | print(f"⏳ Chargement dynamique de {lang}...") |
| | models[lang] = TTS(language=lang, device=device) |
| | except Exception as e: |
| | raise HTTPException(status_code=400, detail=f"Langue {lang} non supportée: {e}") |
| |
|
| | model = models[lang] |
| | speaker_ids = model.hps.data.spk2id |
| | |
| | |
| | |
| | |
| | |
| | try: |
| | spk_id = None |
| | |
| | if lang == 'EN': |
| | |
| | |
| | spk_id = speaker_ids['EN-US'] |
| | elif lang == 'FR': |
| | |
| | spk_id = speaker_ids['FR'] |
| | elif lang == 'ES': |
| | |
| | spk_id = speaker_ids['ES'] |
| | elif lang == 'ZH': |
| | spk_id = speaker_ids['ZH'] |
| | elif lang == 'JP': |
| | spk_id = speaker_ids['JP'] |
| | elif lang == 'KR': |
| | spk_id = speaker_ids['KR'] |
| | else: |
| | |
| | |
| | spk_id = speaker_ids[lang] |
| | |
| | except Exception as e: |
| | |
| | print(f"⚠️ Erreur Speaker ID: {e}") |
| | |
| | try: |
| | spk_id = getattr(speaker_ids, lang) |
| | except: |
| | return Response(content=f"Erreur: Impossible de trouver la voix pour {lang}", status_code=500) |
| |
|
| | output_path = f"/tmp/output_{os.getpid()}.wav" |
| |
|
| | try: |
| | |
| | model.tts_to_file(text, spk_id, output_path, speed=speed) |
| | |
| | with open(output_path, "rb") as f: |
| | audio_data = f.read() |
| | |
| | return Response(content=audio_data, media_type="audio/wav") |
| |
|
| | except Exception as e: |
| | print(f"❌ Erreur génération : {e}") |
| | return Response(content=str(e), status_code=500) |
| |
|
| | @app.get("/") |
| | def home(): |
| | return {"status": "MeloTTS Ready", "loaded": list(models.keys())} |