File size: 2,183 Bytes
41ecf58 82aa895 41ecf58 82aa895 41ecf58 82aa895 41ecf58 82aa895 41ecf58 e44db73 82aa895 41ecf58 82aa895 41ecf58 82aa895 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 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") |