from fastapi import FastAPI, Response from pydantic import BaseModel from kokoro import KPipeline import soundfile as sf import numpy as np import io app = FastAPI() # Initialisation du pipeline STRICTEMENT en français (lang_code 'f') # Cela force toutes les voix (même anglaises) à lire avec les règles du français pipeline = KPipeline(lang_code='f') class TTSRequest(BaseModel): input: str voice: str = "ff_siwis" # Voix 100% française par défaut speed: float = 1.0 @app.get("/") def home(): return { "status": "En ligne", "astuce": "Utilisez le format 'voix1+voix2' pour fusionner des voix avec un accent !" } @app.post("/v1/audio/speech") def generate_audio(request: TTSRequest): # 1. GESTION DE LA FUSION DE VOIX (Voice Blending) if "+" in request.voice: # Si l'utilisateur demande "ff_siwis+am_michael" voice_names = request.voice.split("+") tensors = [] for name in voice_names: try: # On télécharge/charge le profil de la voix t = pipeline.load_voice(name.strip()) tensors.append(t) except Exception as e: print(f"Erreur avec la voix {name}: {e}") # On calcule la moyenne mathématique des voix pour créer une voix hybride if tensors: voice_param = sum(tensors) / len(tensors) else: voice_param = "ff_siwis" else: # Voix simple classique voice_param = request.voice # 2. GÉNÉRATION DE L'AUDIO generator = pipeline(request.input, voice=voice_param, speed=request.speed) # 3. ASSEMBLAGE (Pratique pour les textes longs) audio_chunks = [] for _, _, audio in generator: audio_chunks.append(audio) if not audio_chunks: return Response(status_code=500, content="Erreur lors de la génération") # On colle tous les morceaux ensemble final_audio = np.concatenate(audio_chunks) # 4. EXPORTATION EN WAV out = io.BytesIO() sf.write(out, final_audio, 24000, format='wav') return Response(content=out.getvalue(), media_type="audio/wav")