Randriamiandry commited on
Commit
f7be0cf
·
1 Parent(s): ec13a3e

fix error

Browse files
Files changed (1) hide show
  1. app.py +23 -34
app.py CHANGED
@@ -12,38 +12,32 @@ import time
12
  print("🚀 Démarrage API Kokoro-82M (ONNX rapide)")
13
 
14
  # -------------------------------------------------------------
15
- # Import correct (classe Kokoro)
16
  # -------------------------------------------------------------
17
- try:
18
- from kokoro_onnx import Kokoro
19
- tts = Kokoro()
20
- print("✅ Kokoro chargé (classe Kokoro)")
21
- except ImportError:
22
- try:
23
- from kokoro_onnx import TTS
24
- tts = TTS()
25
- print("✅ Kokoro chargé (classe TTS)")
26
- except ImportError as e:
27
- raise ImportError("Impossible d'importer kokoro_onnx. Installez 'kokoro-onnx'") from e
28
 
29
- # Dictionnaire pour les voix clonées (certaines versions supportent)
 
 
 
30
  cloned_voices = {}
31
 
32
  # -------------------------------------------------------------
33
  # Application FastAPI
34
  # -------------------------------------------------------------
35
- app = FastAPI(title="Kokoro TTS API", version="2.1")
36
 
37
  # Servir l'interface HTML (optionnel)
38
  app.mount("/static", StaticFiles(directory="static"), name="static")
39
 
40
  @app.get("/")
41
  async def root():
42
- voices_list = list(tts.voices.keys()) if hasattr(tts, 'voices') else []
43
  return {
44
  "status": "ok",
45
  "model": "Kokoro-82M (ONNX)",
46
- "available_voices": voices_list,
47
  "endpoints": ["/tts", "/clone-voice", "/voices"]
48
  }
49
 
@@ -64,26 +58,20 @@ async def generate_speech(request: TTSRequest):
64
  if not text:
65
  raise HTTPException(400, "Texte vide")
66
 
67
- # Choix de la voix (clonée ou intégrée)
68
  voice = request.voice
69
  if voice in cloned_voices:
70
- voice = cloned_voices[voice]
71
 
72
  try:
73
- # Appel selon la signature de kokoro-onnx
74
- if hasattr(tts, 'tts'):
75
- audio, sample_rate = tts.tts(
76
- text=text, voice=voice,
77
- speed=request.speed, lang=request.lang
78
- )
79
- else:
80
- # Fallback : instance callable
81
- audio, sample_rate = tts(
82
- text=text, voice=voice,
83
- speed=request.speed, lang=request.lang
84
- )
85
-
86
- # Écrire le fichier WAV en mémoire
87
  buffer = io.BytesIO()
88
  sf.write(buffer, audio, sample_rate, format='WAV')
89
  buffer.seek(0)
@@ -105,11 +93,11 @@ async def clone_voice(audio_file: UploadFile = File(...), voice_name: str = Form
105
  tmp_path = tmp.name
106
 
107
  try:
108
- # Certaines versions de kokoro-onnx supportent clone_voice
109
  if hasattr(tts, 'clone_voice'):
110
  cloned_voice = tts.clone_voice(tmp_path)
111
  else:
112
- # Fallback : on stocke simplement le chemin (peut ne pas fonctionner)
113
  cloned_voice = tmp_path
114
  cloned_voices[voice_name] = cloned_voice
115
  return {"message": f"Voix '{voice_name}' clonée", "voice_name": voice_name, "total": len(cloned_voices)}
@@ -121,6 +109,7 @@ async def clone_voice(audio_file: UploadFile = File(...), voice_name: str = Form
121
 
122
  @app.get("/voices")
123
  async def list_voices():
 
124
  builtin = list(tts.voices.keys()) if hasattr(tts, 'voices') else []
125
  return {"builtin": builtin, "cloned": list(cloned_voices.keys())}
126
 
 
12
  print("🚀 Démarrage API Kokoro-82M (ONNX rapide)")
13
 
14
  # -------------------------------------------------------------
15
+ # Chargement du modèle via from_pretrained (recommandé)
16
  # -------------------------------------------------------------
17
+ from kokoro_onnx import Kokoro
18
+
19
+ # Modèle par défaut (sera téléchargé automatiquement depuis HF)
20
+ MODEL_NAME = "onnx-community/Kokoro-82M-v1.0-ONNX"
 
 
 
 
 
 
 
21
 
22
+ tts = Kokoro.from_pretrained(MODEL_NAME, device="cpu")
23
+ print("✅ Modèle Kokoro chargé avec succès")
24
+
25
+ # Dictionnaire pour les voix clonées (si supporté)
26
  cloned_voices = {}
27
 
28
  # -------------------------------------------------------------
29
  # Application FastAPI
30
  # -------------------------------------------------------------
31
+ app = FastAPI(title="Kokoro TTS API", version="2.2")
32
 
33
  # Servir l'interface HTML (optionnel)
34
  app.mount("/static", StaticFiles(directory="static"), name="static")
35
 
36
  @app.get("/")
37
  async def root():
 
38
  return {
39
  "status": "ok",
40
  "model": "Kokoro-82M (ONNX)",
 
41
  "endpoints": ["/tts", "/clone-voice", "/voices"]
42
  }
43
 
 
58
  if not text:
59
  raise HTTPException(400, "Texte vide")
60
 
61
+ # Choix de la voix : clonée ou intégrée
62
  voice = request.voice
63
  if voice in cloned_voices:
64
+ voice = cloned_voices[voice] # peut être un chemin ou un identifiant
65
 
66
  try:
67
+ # Génération audio
68
+ audio, sample_rate = tts.tts(
69
+ text=text,
70
+ voice=voice,
71
+ speed=request.speed,
72
+ lang=request.lang
73
+ )
74
+ # Sauvegarde en mémoire
 
 
 
 
 
 
75
  buffer = io.BytesIO()
76
  sf.write(buffer, audio, sample_rate, format='WAV')
77
  buffer.seek(0)
 
93
  tmp_path = tmp.name
94
 
95
  try:
96
+ # Certaines versions supportent clone_voice
97
  if hasattr(tts, 'clone_voice'):
98
  cloned_voice = tts.clone_voice(tmp_path)
99
  else:
100
+ # Fallback : on stocke le chemin (fonctionne si l'API l'accepte)
101
  cloned_voice = tmp_path
102
  cloned_voices[voice_name] = cloned_voice
103
  return {"message": f"Voix '{voice_name}' clonée", "voice_name": voice_name, "total": len(cloned_voices)}
 
109
 
110
  @app.get("/voices")
111
  async def list_voices():
112
+ # Les voix intégrées sont dans tts.voices (si dispo)
113
  builtin = list(tts.voices.keys()) if hasattr(tts, 'voices') else []
114
  return {"builtin": builtin, "cloned": list(cloned_voices.keys())}
115