AthanasiusRG commited on
Commit
f4f68ae
ยท
verified ยท
1 Parent(s): 811537a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -77
app.py CHANGED
@@ -6,7 +6,7 @@ from fastapi import FastAPI, UploadFile, File, Form, HTTPException
6
  from fastapi.responses import FileResponse
7
  from core.cloner import KokoClone
8
 
9
- # โ”€โ”€ Chargement des modรจles (une seule fois au dรฉmarrage) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
10
  print("Loading KokoClone models...")
11
  cloner = KokoClone()
12
 
@@ -14,10 +14,9 @@ cloner = KokoClone()
14
  # โ”€โ”€ Handlers Gradio โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
15
 
16
  def gradio_speak(text, lang, speed):
17
- """TTS simple sans clone."""
18
  if not text or not text.strip():
19
  raise gr.Error("Veuillez entrer du texte.")
20
- output_file = "gradio_speak_output.wav"
21
  try:
22
  cloner.speak(text=text, lang=lang, output_path=output_file, speed=float(speed))
23
  return output_file
@@ -26,12 +25,11 @@ def gradio_speak(text, lang, speed):
26
 
27
 
28
  def gradio_clone(text, lang, ref_audio_path):
29
- """TTS + voice cloning."""
30
  if not text or not text.strip():
31
  raise gr.Error("Please enter some text.")
32
  if not ref_audio_path:
33
  raise gr.Error("Please upload or record a reference audio file.")
34
- output_file = "gradio_clone_output.wav"
35
  try:
36
  cloner.generate(text=text, lang=lang, reference_audio=ref_audio_path, output_path=output_file)
37
  return output_file
@@ -40,12 +38,11 @@ def gradio_clone(text, lang, ref_audio_path):
40
 
41
 
42
  def gradio_convert(source_audio_path, ref_audio_path):
43
- """Re-voicing audio source."""
44
  if not source_audio_path:
45
  raise gr.Error("Please upload a source audio file.")
46
  if not ref_audio_path:
47
  raise gr.Error("Please upload a reference audio file.")
48
- output_file = "gradio_convert_output.wav"
49
  try:
50
  cloner.convert(source_audio=source_audio_path, reference_audio=ref_audio_path, output_path=output_file)
51
  return output_file
@@ -53,9 +50,9 @@ def gradio_convert(source_audio_path, ref_audio_path):
53
  raise gr.Error(f"An error occurred: {str(e)}")
54
 
55
 
56
- # โ”€โ”€ Interface Gradio โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
57
 
58
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
59
  gr.Markdown(
60
  """
61
  <div style="text-align: center;">
@@ -70,10 +67,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
70
  # โ”€โ”€ Onglet 1 : TTS Simple โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
71
  with gr.Tab("๐Ÿ—ฃ๏ธ Simple TTS"):
72
  gr.Markdown(
73
- """
74
- Gรฉnรจre la parole directement avec une voix Kokoro โ€” **aucun audio de rรฉfรฉrence requis**.
75
- Idรฉal pour l'anglais et le franรงais dans MikoHelper.
76
- """
77
  )
78
  with gr.Row():
79
  with gr.Column(scale=1):
@@ -85,8 +79,8 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
85
  speak_lang = gr.Dropdown(
86
  label="Langue / Voix",
87
  choices=[
88
- ("๐Ÿ‡ฌ๐Ÿ‡ง English โ€” af_bella (femme amรฉricaine)", "en"),
89
- ("๐Ÿ‡ซ๐Ÿ‡ท Franรงais โ€” ff_siwis (femme franรงaise)", "fr"),
90
  ("๐Ÿ‡ฎ๐Ÿ‡ณ Hindi โ€” hf_alpha", "hi"),
91
  ("๐Ÿ‡ช๐Ÿ‡ธ Espaรฑol โ€” im_nicola", "es"),
92
  ("๐Ÿ‡ฎ๐Ÿ‡น Italiano โ€” im_nicola", "it"),
@@ -101,7 +95,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
101
  value=1.0,
102
  step=0.1
103
  )
104
- speak_btn = gr.Button("๐Ÿ—ฃ๏ธ Gรฉnรฉrer l'audio", variant="primary", size="lg")
105
 
106
  with gr.Column(scale=1):
107
  speak_out = gr.Audio(
@@ -111,27 +105,21 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
111
  )
112
  gr.Markdown(
113
  """
114
- ### ๐Ÿ’ก Voix disponibles
115
- - **EN** `af_bella` โ€” femme, accent amรฉricain, claire et naturelle
116
- - **FR** `ff_siwis` โ€” femme, accent franรงais, fluide
117
- - **HI** `hf_alpha` โ€” Hindi
118
- - **ES/IT** `im_nicola` โ€” voix masculine
119
- - **PT** `pf_dora` โ€” Portugais brรฉsilien
120
-
121
- > Ajustez la **vitesse** pour les apprenants dรฉbutants (0.7โ€“0.8 recommandรฉ).
122
  """
123
  )
124
 
125
  speak_btn.click(
126
- fn=lambda: gr.update(value="โŒ› Gรฉnรฉration en cours...", interactive=False),
127
- outputs=speak_btn
128
- ).then(
129
  fn=gradio_speak,
130
  inputs=[speak_text, speak_lang, speak_speed],
131
  outputs=speak_out
132
- ).then(
133
- fn=lambda: gr.update(value="๐Ÿ—ฃ๏ธ Gรฉnรฉrer l'audio", interactive=True),
134
- outputs=speak_btn
135
  )
136
 
137
  # โ”€โ”€ Onglet 2 : Text โ†’ Clone โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@@ -159,10 +147,10 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
159
  value="en"
160
  )
161
  clone_ref = gr.Audio(
162
- label="3. Audio de rรฉfรฉrence (upload ou enregistrement)",
163
  type="filepath"
164
  )
165
- clone_btn = gr.Button("๐Ÿš€ Gรฉnรฉrer avec clonage", variant="primary", size="lg")
166
 
167
  with gr.Column(scale=1):
168
  clone_out = gr.Audio(
@@ -172,23 +160,17 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
172
  )
173
  gr.Markdown(
174
  """
175
- ### ๐Ÿ’ก Conseils
176
- - Audio de rรฉfรฉrence propre, sans bruit de fond
177
- - 3 ร  10 secondes = rรฉsultat optimal
178
- - La langue sรฉlectionnรฉe doit correspondre au texte
179
  """
180
  )
181
 
182
  clone_btn.click(
183
- fn=lambda: gr.update(value="โŒ› Gรฉnรฉration...", interactive=False),
184
- outputs=clone_btn
185
- ).then(
186
  fn=gradio_clone,
187
  inputs=[clone_text, clone_lang, clone_ref],
188
  outputs=clone_out
189
- ).then(
190
- fn=lambda: gr.update(value="๐Ÿš€ Gรฉnรฉrer avec clonage", interactive=True),
191
- outputs=clone_btn
192
  )
193
 
194
  # โ”€โ”€ Onglet 3 : Audio โ†’ Clone โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
@@ -197,14 +179,14 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
197
  with gr.Row():
198
  with gr.Column(scale=1):
199
  convert_src = gr.Audio(
200
- label="1. Audio source (parole ร  re-voicer)",
201
  type="filepath"
202
  )
203
  convert_ref = gr.Audio(
204
- label="2. Voix de rรฉfรฉrence (locuteur cible)",
205
  type="filepath"
206
  )
207
- convert_btn = gr.Button("๐Ÿ” Convertir la voix", variant="primary", size="lg")
208
 
209
  with gr.Column(scale=1):
210
  convert_out = gr.Audio(
@@ -214,24 +196,18 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
214
  )
215
  gr.Markdown(
216
  """
217
- ### ๐Ÿ’ก Comment รงa marche
218
- - Uploadez n'importe quel enregistrement vocal comme **source**
219
- - Uploadez un court clip du **locuteur cible** comme rรฉfรฉrence
220
- - KokoClone re-voice la source pour sonner comme la rรฉfรฉrence
221
- - Aucune transcription nรฉcessaire !
222
  """
223
  )
224
 
225
  convert_btn.click(
226
- fn=lambda: gr.update(value="โŒ› Conversion...", interactive=False),
227
- outputs=convert_btn
228
- ).then(
229
  fn=gradio_convert,
230
  inputs=[convert_src, convert_ref],
231
  outputs=convert_out
232
- ).then(
233
- fn=lambda: gr.update(value="๐Ÿ” Convertir la voix", interactive=True),
234
- outputs=convert_btn
235
  )
236
 
237
 
@@ -242,7 +218,6 @@ app = gr.mount_gradio_app(FastAPI(), demo, path="/")
242
 
243
  @app.get("/api/voices")
244
  def list_voices():
245
- """Liste toutes les voix disponibles."""
246
  return {
247
  "voices": [
248
  {"lang": "en", "voice": "af_bella", "description": "English - American Female"},
@@ -261,13 +236,6 @@ async def api_speak(
261
  lang: str = Form(default="en"),
262
  speed: float = Form(default=1.0),
263
  ):
264
- """
265
- TTS simple sans clone.
266
- - text : texte ร  synthรฉtiser
267
- - lang : 'en', 'fr', 'hi', 'es', 'it', 'pt'
268
- - speed : vitesse (0.5 โ€“ 1.5), dรฉfaut 1.0
269
- Retourne un fichier WAV.
270
- """
271
  out_path = tempfile.mktemp(suffix=".wav")
272
  try:
273
  cloner.speak(text=text, lang=lang, output_path=out_path, speed=speed)
@@ -284,13 +252,6 @@ async def api_clone(
284
  lang: str = Form(default="en"),
285
  reference_audio: UploadFile = File(...),
286
  ):
287
- """
288
- TTS + voice cloning.
289
- - text : texte ร  synthรฉtiser
290
- - lang : langue
291
- - reference_audio : fichier audio WAV de rรฉfรฉrence
292
- Retourne un fichier WAV clonรฉ.
293
- """
294
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as ref_tmp:
295
  shutil.copyfileobj(reference_audio.file, ref_tmp)
296
  ref_path = ref_tmp.name
@@ -310,12 +271,6 @@ async def api_convert(
310
  source_audio: UploadFile = File(...),
311
  reference_audio: UploadFile = File(...),
312
  ):
313
- """
314
- Re-voicing audio source โ†’ voix de rรฉfรฉrence.
315
- - source_audio : parole ร  re-voicer
316
- - reference_audio : locuteur cible
317
- Retourne un fichier WAV converti.
318
- """
319
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as src_tmp:
320
  shutil.copyfileobj(source_audio.file, src_tmp)
321
  src_path = src_tmp.name
 
6
  from fastapi.responses import FileResponse
7
  from core.cloner import KokoClone
8
 
9
+ # โ”€โ”€ Chargement unique des modรจles โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
10
  print("Loading KokoClone models...")
11
  cloner = KokoClone()
12
 
 
14
  # โ”€โ”€ Handlers Gradio โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
15
 
16
  def gradio_speak(text, lang, speed):
 
17
  if not text or not text.strip():
18
  raise gr.Error("Veuillez entrer du texte.")
19
+ output_file = "/tmp/gradio_speak_output.wav"
20
  try:
21
  cloner.speak(text=text, lang=lang, output_path=output_file, speed=float(speed))
22
  return output_file
 
25
 
26
 
27
  def gradio_clone(text, lang, ref_audio_path):
 
28
  if not text or not text.strip():
29
  raise gr.Error("Please enter some text.")
30
  if not ref_audio_path:
31
  raise gr.Error("Please upload or record a reference audio file.")
32
+ output_file = "/tmp/gradio_clone_output.wav"
33
  try:
34
  cloner.generate(text=text, lang=lang, reference_audio=ref_audio_path, output_path=output_file)
35
  return output_file
 
38
 
39
 
40
  def gradio_convert(source_audio_path, ref_audio_path):
 
41
  if not source_audio_path:
42
  raise gr.Error("Please upload a source audio file.")
43
  if not ref_audio_path:
44
  raise gr.Error("Please upload a reference audio file.")
45
+ output_file = "/tmp/gradio_convert_output.wav"
46
  try:
47
  cloner.convert(source_audio=source_audio_path, reference_audio=ref_audio_path, output_path=output_file)
48
  return output_file
 
50
  raise gr.Error(f"An error occurred: {str(e)}")
51
 
52
 
53
+ # โ”€โ”€ Interface Gradio (Gradio 6 compatible) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
54
 
55
+ with gr.Blocks() as demo: # theme retirรฉ ici โ†’ va dans launch()
56
  gr.Markdown(
57
  """
58
  <div style="text-align: center;">
 
67
  # โ”€โ”€ Onglet 1 : TTS Simple โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
68
  with gr.Tab("๐Ÿ—ฃ๏ธ Simple TTS"):
69
  gr.Markdown(
70
+ "Gรฉnรจre la parole avec une voix Kokoro โ€” **aucun audio de rรฉfรฉrence requis**."
 
 
 
71
  )
72
  with gr.Row():
73
  with gr.Column(scale=1):
 
79
  speak_lang = gr.Dropdown(
80
  label="Langue / Voix",
81
  choices=[
82
+ ("๐Ÿ‡ฌ๐Ÿ‡ง English โ€” af_bella", "en"),
83
+ ("๐Ÿ‡ซ๐Ÿ‡ท Franรงais โ€” ff_siwis", "fr"),
84
  ("๐Ÿ‡ฎ๐Ÿ‡ณ Hindi โ€” hf_alpha", "hi"),
85
  ("๐Ÿ‡ช๐Ÿ‡ธ Espaรฑol โ€” im_nicola", "es"),
86
  ("๐Ÿ‡ฎ๐Ÿ‡น Italiano โ€” im_nicola", "it"),
 
95
  value=1.0,
96
  step=0.1
97
  )
98
+ speak_btn = gr.Button("๐Ÿ—ฃ๏ธ Gรฉnรฉrer l'audio", variant="primary")
99
 
100
  with gr.Column(scale=1):
101
  speak_out = gr.Audio(
 
105
  )
106
  gr.Markdown(
107
  """
108
+ **Voix disponibles**
109
+ - ๐Ÿ‡ฌ๐Ÿ‡ง `af_bella` โ€” femme amรฉricaine, claire
110
+ - ๐Ÿ‡ซ๐Ÿ‡ท `ff_siwis` โ€” femme franรงaise, fluide
111
+ - ๐Ÿ‡ฎ๐Ÿ‡ณ `hf_alpha` โ€” Hindi
112
+ - ๐Ÿ‡ช๐Ÿ‡ธ๐Ÿ‡ฎ๐Ÿ‡น `im_nicola` โ€” voix masculine
113
+ - ๐Ÿ‡ง๐Ÿ‡ท `pf_dora` โ€” Portugais brรฉsilien
114
+
115
+ > Vitesse **0.7โ€“0.8** recommandรฉe pour les apprenants dรฉbutants.
116
  """
117
  )
118
 
119
  speak_btn.click(
 
 
 
120
  fn=gradio_speak,
121
  inputs=[speak_text, speak_lang, speak_speed],
122
  outputs=speak_out
 
 
 
123
  )
124
 
125
  # โ”€โ”€ Onglet 2 : Text โ†’ Clone โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 
147
  value="en"
148
  )
149
  clone_ref = gr.Audio(
150
+ label="3. Audio de rรฉfรฉrence",
151
  type="filepath"
152
  )
153
+ clone_btn = gr.Button("๐Ÿš€ Gรฉnรฉrer avec clonage", variant="primary")
154
 
155
  with gr.Column(scale=1):
156
  clone_out = gr.Audio(
 
160
  )
161
  gr.Markdown(
162
  """
163
+ **Conseils**
164
+ - Audio de rรฉfรฉrence propre, sans bruit de fond
165
+ - 3 ร  10 secondes = rรฉsultat optimal
166
+ - La langue doit correspondre au texte
167
  """
168
  )
169
 
170
  clone_btn.click(
 
 
 
171
  fn=gradio_clone,
172
  inputs=[clone_text, clone_lang, clone_ref],
173
  outputs=clone_out
 
 
 
174
  )
175
 
176
  # โ”€โ”€ Onglet 3 : Audio โ†’ Clone โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
 
179
  with gr.Row():
180
  with gr.Column(scale=1):
181
  convert_src = gr.Audio(
182
+ label="1. Audio source",
183
  type="filepath"
184
  )
185
  convert_ref = gr.Audio(
186
+ label="2. Voix de rรฉfรฉrence",
187
  type="filepath"
188
  )
189
+ convert_btn = gr.Button("๐Ÿ” Convertir la voix", variant="primary")
190
 
191
  with gr.Column(scale=1):
192
  convert_out = gr.Audio(
 
196
  )
197
  gr.Markdown(
198
  """
199
+ **Comment รงa marche**
200
+ - **Source** : n'importe quel enregistrement vocal
201
+ - **Rรฉfรฉrence** : court clip du locuteur cible
202
+ - KokoClone re-voice la source vers la rรฉfรฉrence
203
+ - Aucune transcription nรฉcessaire
204
  """
205
  )
206
 
207
  convert_btn.click(
 
 
 
208
  fn=gradio_convert,
209
  inputs=[convert_src, convert_ref],
210
  outputs=convert_out
 
 
 
211
  )
212
 
213
 
 
218
 
219
  @app.get("/api/voices")
220
  def list_voices():
 
221
  return {
222
  "voices": [
223
  {"lang": "en", "voice": "af_bella", "description": "English - American Female"},
 
236
  lang: str = Form(default="en"),
237
  speed: float = Form(default=1.0),
238
  ):
 
 
 
 
 
 
 
239
  out_path = tempfile.mktemp(suffix=".wav")
240
  try:
241
  cloner.speak(text=text, lang=lang, output_path=out_path, speed=speed)
 
252
  lang: str = Form(default="en"),
253
  reference_audio: UploadFile = File(...),
254
  ):
 
 
 
 
 
 
 
255
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as ref_tmp:
256
  shutil.copyfileobj(reference_audio.file, ref_tmp)
257
  ref_path = ref_tmp.name
 
271
  source_audio: UploadFile = File(...),
272
  reference_audio: UploadFile = File(...),
273
  ):
 
 
 
 
 
 
274
  with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as src_tmp:
275
  shutil.copyfileobj(source_audio.file, src_tmp)
276
  src_path = src_tmp.name