RafaG commited on
Commit
dec6ec7
·
verified ·
1 Parent(s): 8abf4ab

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +363 -354
app.py CHANGED
@@ -1,355 +1,364 @@
1
- import subprocess
2
- import os
3
- import json
4
- import gradio as gr
5
- from pydub import AudioSegment
6
- from header import badges, description
7
- from pydub.silence import split_on_silence
8
- from get_voices import get_voices
9
- #from adjust import remove_silence, controlador_generate_audio, generate_audio
10
-
11
- # Load voices from JSON file
12
- def load_voices():
13
- with open('voices.json', 'r', encoding='utf-8') as f:
14
- return json.load(f)
15
-
16
- # Get formatted voice options for specific language
17
- def get_voice_options(language, voices_data):
18
- if language in voices_data:
19
- return [f"{voice['name']} | {voice['gender']}" for voice in voices_data[language]]
20
- return []
21
-
22
- # Extract voice name from formatted string
23
- def extract_voice_name(formatted_voice):
24
- return formatted_voice.split(" | ")[0]
25
-
26
- def update_voice_options(language):
27
- voices_data = load_voices()
28
- voice_options = get_voice_options(language, voices_data)
29
- # Retorna apenas a lista de opções e o primeiro valor
30
- if voice_options:
31
- return gr.Dropdown(choices=voice_options, value=voice_options[0])
32
- return gr.Dropdown(choices=[], value=None)
33
-
34
- def update_voices_and_refresh():
35
- # Execute get_voices to update the voices.json file
36
- get_voices()
37
- # Reload the voices data
38
- voices_data = load_voices()
39
- available_languages = list(voices_data.keys())
40
- # Get initial voices for the first language
41
- initial_voices = get_voice_options(available_languages[0], voices_data) if available_languages else []
42
-
43
- return (
44
- gr.Dropdown(choices=available_languages, value=available_languages[0] if available_languages else None),
45
- gr.Dropdown(choices=initial_voices, value=initial_voices[0] if initial_voices else None)
46
- )
47
-
48
- def remove_silence(input_file, output_file):
49
- audio = AudioSegment.from_wav(input_file)
50
-
51
- # Encontra os segmentos de áudio que não são silêncio
52
- segments = split_on_silence(audio, min_silence_len=500, silence_thresh=-40)
53
-
54
- # Concatena os segmentos de áudio não silenciosos
55
- non_silent_audio = AudioSegment.silent(duration=0)
56
- for segment in segments:
57
- non_silent_audio += segment
58
-
59
- # Salva o áudio sem as partes de silêncio
60
- non_silent_audio.export(output_file, format="wav")
61
-
62
- def controlador_generate_audio(audio_input, voice_model_input, speed_input, pitch_input, volume_input, checkbox_cortar_silencio):
63
- # Gerar áudio
64
- audio_file = generate_audio(audio_input, voice_model_input, speed_input, pitch_input, volume_input)
65
- if audio_file:
66
- print("Áudio gerado com sucesso:", audio_file)
67
- # Verificar se o checkbox de cortar silêncio está marcado
68
- if checkbox_cortar_silencio:
69
- print("Cortando silêncio...")
70
- # Remover silêncio do áudio
71
- remove_silence(audio_file, audio_file)
72
- print("Silêncio removido com sucesso!")
73
- else:
74
- print("Erro ao gerar áudio.")
75
- return audio_file # Retornar o caminho do arquivo de áudio
76
-
77
- def generate_audio(texto, modelo_de_voz, velocidade, tom, volume):
78
- # Extract actual voice name from formatted string if necessary
79
- actual_voice = extract_voice_name(modelo_de_voz)
80
-
81
- # Format parameters with proper signs
82
- if velocidade >= 0:
83
- rate_str = f"+{velocidade}%"
84
- else:
85
- rate_str = f"{velocidade}%"
86
-
87
- if tom >= 0:
88
- pitch_str = f"+{tom}Hz"
89
- else:
90
- pitch_str = f"{tom}Hz"
91
-
92
- if volume >= 0:
93
- volume_str = f"+{volume}%"
94
- else:
95
- volume_str = f"{volume}%"
96
-
97
- output_dir = "output"
98
- os.makedirs(output_dir, exist_ok=True)
99
- mp3_output_file = os.path.join(output_dir, "new_audio.mp3")
100
-
101
- cmd = [
102
- "edge-tts",
103
- "--rate=" + rate_str,
104
- "--pitch=" + pitch_str,
105
- "--volume=" + volume_str,
106
- "-v", actual_voice,
107
- "-t", texto,
108
- "--write-media", mp3_output_file
109
- ]
110
-
111
- print("Gerando áudio...")
112
- try:
113
- subprocess.run(cmd, check=True)
114
- except subprocess.CalledProcessError as e:
115
- print("Erro ao gerar áudio:", e)
116
- return None
117
-
118
- print("Áudio gerado com sucesso!")
119
- wav_output_file = os.path.join(output_dir, "new_audio.wav")
120
- audio = AudioSegment.from_mp3(mp3_output_file)
121
- audio.export(wav_output_file, format="wav")
122
- return wav_output_file
123
-
124
- def generate_audio_from_file(file_path, modelo_de_voz, velocidade, tom, volume):
125
- # Extrai o nome real da voz formatada, se necessário
126
- actual_voice = extract_voice_name(modelo_de_voz)
127
-
128
- # Formatação dos parâmetros com sinais adequados
129
- rate_str = f"+{velocidade}%" if velocidade >= 0 else f"{velocidade}%"
130
- pitch_str = f"+{tom}Hz" if tom >= 0 else f"{tom}Hz"
131
- volume_str = f"+{volume}%" if volume >= 0 else f"{volume}%"
132
-
133
- output_dir = "output"
134
- os.makedirs(output_dir, exist_ok=True)
135
- mp3_output_file = os.path.join(output_dir, "new_audio.mp3")
136
-
137
- # Usar -f FILE para passar o caminho do arquivo de texto
138
- cmd = [
139
- "edge-tts",
140
- "-f", file_path, # Certificar que o conteúdo do arquivo seja texto puro
141
- "--rate=" + rate_str,
142
- "--pitch=" + pitch_str,
143
- "--volume=" + volume_str,
144
- "-v", actual_voice,
145
- "--write-media", mp3_output_file
146
- ]
147
-
148
- print("Gerando áudio do arquivo...")
149
- try:
150
- subprocess.run(cmd, check=True)
151
- except subprocess.CalledProcessError as e:
152
- print("Erro ao gerar áudio:", e)
153
- return None
154
-
155
- print("Áudio gerado com sucesso!")
156
- wav_output_file = os.path.join(output_dir, "new_audio.wav")
157
- audio = AudioSegment.from_mp3(mp3_output_file)
158
- audio.export(wav_output_file, format="wav")
159
- return wav_output_file
160
-
161
- def controlador_generate_audio_from_file(file, voice_model_input, speed_input, pitch_input, volume_input, checkbox_cortar_silencio):
162
- if file is None:
163
- return None
164
-
165
- # Neste caso, o 'file' já é o caminho do arquivo, então não precisa reescrever
166
- temp_file_path = file # Caminho do arquivo que você recebe do Gradio
167
-
168
- # Gerar o áudio
169
- audio_file = generate_audio_from_file(temp_file_path, voice_model_input, speed_input, pitch_input, volume_input)
170
-
171
- if audio_file:
172
- print("Áudio gerado com sucesso:", audio_file)
173
- if checkbox_cortar_silencio:
174
- print("Cortando silêncio...")
175
- remove_silence(audio_file, audio_file)
176
- print("Silêncio removido com sucesso!")
177
- else:
178
- print("Erro ao gerar áudio.")
179
-
180
- return audio_file
181
-
182
- with gr.Blocks(theme=gr.themes.Default(primary_hue="green", secondary_hue="blue"), title="QuickTTS") as iface:
183
- gr.Markdown(badges)
184
- gr.Markdown(description)
185
-
186
- voices_data = load_voices()
187
- available_languages = list(voices_data.keys())
188
-
189
- with gr.Tabs():
190
- with gr.TabItem("Edge-TTS"):
191
- gr.Markdown("É ilimitado, podendo até mesmo colocar um livro inteiro, mas claro, tem a questão de tempo, quanto maior o texto, mais demorado é, dublagem por SRT talvez um dia eu bote.")
192
-
193
- with gr.Row():
194
- # Language selection dropdown
195
- language_input = gr.Dropdown(
196
- choices=available_languages,
197
- label="Idioma",
198
- value=available_languages[52] if available_languages else None
199
- )
200
-
201
- # Voice model dropdown (will be updated based on language selection)
202
- initial_voices = get_voice_options(available_languages[52], voices_data) if available_languages else []
203
- voice_model_input = gr.Dropdown(
204
- choices=initial_voices,
205
- label="Modelo de Voz",
206
- value=initial_voices[0] if initial_voices else None
207
- )
208
-
209
- # Connect language selection to voice model update
210
- language_input.change(
211
- fn=update_voice_options,
212
- inputs=[language_input],
213
- outputs=[voice_model_input]
214
- )
215
-
216
- audio_input = gr.Textbox(label="Texto", value='Texto de exemplo!', interactive=True)
217
-
218
- with gr.Row():
219
- with gr.Column():
220
- speed_input = gr.Slider(
221
- minimum=-200,
222
- maximum=200,
223
- label="Velocidade (%)",
224
- value=0,
225
- interactive=True
226
- )
227
- with gr.Column():
228
- pitch_input = gr.Slider(
229
- minimum=-100,
230
- maximum=100,
231
- label="Tom (Hz)",
232
- value=0,
233
- interactive=True
234
- )
235
- with gr.Column():
236
- volume_input = gr.Slider(
237
- minimum=-99,
238
- maximum=100,
239
- label="Volume (%)",
240
- value=0,
241
- interactive=True
242
- )
243
-
244
- checkbox_cortar_silencio = gr.Checkbox(label="Cortar Silencio", interactive=True)
245
- audio_output = gr.Audio(label="Resultado", type="filepath", interactive=False)
246
-
247
- with gr.Row():
248
- edgetts_button = gr.Button(value="Falar")
249
- edgetts_button.click(
250
- controlador_generate_audio,
251
- inputs=[
252
- audio_input,
253
- voice_model_input,
254
- speed_input,
255
- pitch_input, # New input
256
- volume_input, # New input
257
- checkbox_cortar_silencio
258
- ],
259
- outputs=[audio_output]
260
- )
261
-
262
- clear_button = gr.ClearButton(audio_input, value='Limpar')
263
-
264
- # Add update voices button at the top
265
- update_voices_btn = gr.Button(value="Atualizar Lista de Vozes")
266
- # Connect update voices button to refresh function
267
- update_voices_btn.click(
268
- fn=update_voices_and_refresh,
269
- inputs=[],
270
- outputs=[language_input, voice_model_input]
271
- )
272
- gr.Markdown("Agradecimentos a rany2 pelo Edge-TTS")
273
-
274
- with gr.TabItem("Lote (Arquivo txt)"):
275
- gr.Markdown("Carregar texto de um arquivo")
276
- # Language and voice selection (same as first tab)
277
- with gr.Row():
278
- language_input_file = gr.Dropdown(
279
- choices=available_languages,
280
- label="Idioma",
281
- value=available_languages[52] if available_languages else None
282
- )
283
-
284
- initial_voices = get_voice_options(available_languages[52], voices_data) if available_languages else []
285
- voice_model_input_file = gr.Dropdown(
286
- choices=initial_voices,
287
- label="Modelo de Voz",
288
- value=initial_voices[0] if initial_voices else None
289
- )
290
-
291
- language_input_file.change(
292
- fn=update_voice_options,
293
- inputs=[language_input_file],
294
- outputs=[voice_model_input_file]
295
- )
296
- gr.Markdown("O programa vai ler linha por linha e entregar em um único áudio")
297
- # File input
298
- file_input = gr.File(
299
- label="Arquivo de Texto",
300
- file_types=[".txt"],
301
- type="filepath"
302
- )
303
-
304
- with gr.Row():
305
- with gr.Column():
306
- speed_input_file = gr.Slider(
307
- minimum=-200,
308
- maximum=200,
309
- label="Velocidade (%)",
310
- value=0,
311
- interactive=True
312
- )
313
- with gr.Column():
314
- pitch_input_file = gr.Slider(
315
- minimum=-100,
316
- maximum=100,
317
- label="Tom (Hz)",
318
- value=0,
319
- interactive=True
320
- )
321
- with gr.Column():
322
- volume_input_file = gr.Slider(
323
- minimum=-99,
324
- maximum=100,
325
- label="Volume (%)",
326
- value=0,
327
- interactive=True
328
- )
329
-
330
- checkbox_cortar_silencio_file = gr.Checkbox(label="Cortar Silencio", interactive=True)
331
- audio_output_file = gr.Audio(label="Resultado", type="filepath", interactive=False)
332
- with gr.Row():
333
- edgetts_button_file = gr.Button(value="Falar")
334
- edgetts_button_file.click(
335
- controlador_generate_audio_from_file,
336
- inputs=[
337
- file_input,
338
- voice_model_input_file,
339
- speed_input_file,
340
- pitch_input_file,
341
- volume_input_file,
342
- checkbox_cortar_silencio_file
343
- ],
344
- outputs=[audio_output_file]
345
- )
346
-
347
- clear_button_file = gr.ClearButton(file_input, value='Limpar')
348
-
349
- gr.Markdown("Agradecimentos a rany2 pelo Edge-TTS")
350
-
351
- gr.Markdown("""
352
- Desenvolvido por Rafael Godoy <br>
353
- Apoie o projeto pelo https://nubank.com.br/pagar/1ls6a4/0QpSSbWBSq, qualquer valor é bem vindo.
354
- """)
 
 
 
 
 
 
 
 
 
355
  iface.launch()
 
1
+ import subprocess
2
+ import os
3
+ import json
4
+ import gradio as gr
5
+ from pydub import AudioSegment
6
+ from header import badges, description
7
+ from pydub.silence import split_on_silence
8
+ from get_voices import get_voices
9
+ #from adjust import remove_silence, controlador_generate_audio, generate_audio
10
+
11
+ # Load voices from JSON file
12
+ def load_voices():
13
+ with open('voices.json', 'r', encoding='utf-8') as f:
14
+ return json.load(f)
15
+
16
+ # Get formatted voice options for specific language
17
+ def get_voice_options(language, voices_data):
18
+ if language in voices_data:
19
+ return [f"{voice['name']} | {voice['gender']}" for voice in voices_data[language]]
20
+ return []
21
+
22
+ # Extract voice name from formatted string
23
+ def extract_voice_name(formatted_voice):
24
+ return formatted_voice.split(" | ")[0]
25
+
26
+ def update_voice_options(language):
27
+ voices_data = load_voices()
28
+ voice_options = get_voice_options(language, voices_data)
29
+ # Retorna apenas a lista de opções e o primeiro valor
30
+ if voice_options:
31
+ return gr.Dropdown(choices=voice_options, value=voice_options[0])
32
+ return gr.Dropdown(choices=[], value=None)
33
+
34
+ def update_voices_and_refresh():
35
+ # Execute get_voices to update the voices.json file
36
+ get_voices()
37
+ # Reload the voices data
38
+ voices_data = load_voices()
39
+ available_languages = list(voices_data.keys())
40
+ # Get initial voices for the first language
41
+ initial_voices = get_voice_options(available_languages[0], voices_data) if available_languages else []
42
+
43
+ return (
44
+ gr.Dropdown(choices=available_languages, value=available_languages[0] if available_languages else None),
45
+ gr.Dropdown(choices=initial_voices, value=initial_voices[0] if initial_voices else None)
46
+ )
47
+
48
+ def remove_silence(input_file, output_file):
49
+ audio = AudioSegment.from_wav(input_file)
50
+
51
+ # Encontra os segmentos de áudio que não são silêncio
52
+ segments = split_on_silence(audio, min_silence_len=500, silence_thresh=-40)
53
+
54
+ # Concatena os segmentos de áudio não silenciosos
55
+ non_silent_audio = AudioSegment.silent(duration=0)
56
+ for segment in segments:
57
+ non_silent_audio += segment
58
+
59
+ # Salva o áudio sem as partes de silêncio
60
+ non_silent_audio.export(output_file, format="wav")
61
+
62
+ def controlador_generate_audio(audio_input, voice_model_input, speed_input, pitch_input, volume_input, checkbox_cortar_silencio):
63
+ # Gerar áudio
64
+ audio_file = generate_audio(audio_input, voice_model_input, speed_input, pitch_input, volume_input)
65
+ if audio_file:
66
+ print("Áudio gerado com sucesso:", audio_file)
67
+ # Verificar se o checkbox de cortar silêncio está marcado
68
+ if checkbox_cortar_silencio:
69
+ print("Cortando silêncio...")
70
+ # Remover silêncio do áudio
71
+ remove_silence(audio_file, audio_file)
72
+ print("Silêncio removido com sucesso!")
73
+ else:
74
+ print("Erro ao gerar áudio.")
75
+ return audio_file # Retornar o caminho do arquivo de áudio
76
+
77
+ def generate_audio(texto, modelo_de_voz, velocidade, tom, volume):
78
+ # Extract actual voice name from formatted string if necessary
79
+ actual_voice = extract_voice_name(modelo_de_voz)
80
+
81
+ # Format parameters with proper signs
82
+ if velocidade >= 0:
83
+ rate_str = f"+{velocidade}%"
84
+ else:
85
+ rate_str = f"{velocidade}%"
86
+
87
+ if tom >= 0:
88
+ pitch_str = f"+{tom}Hz"
89
+ else:
90
+ pitch_str = f"{tom}Hz"
91
+
92
+ if volume >= 0:
93
+ volume_str = f"+{volume}%"
94
+ else:
95
+ volume_str = f"{volume}%"
96
+
97
+ output_dir = "output"
98
+ os.makedirs(output_dir, exist_ok=True)
99
+ mp3_output_file = os.path.join(output_dir, "new_audio.mp3")
100
+
101
+ cmd = [
102
+ "edge-tts",
103
+ "--rate=" + rate_str,
104
+ "--pitch=" + pitch_str,
105
+ "--volume=" + volume_str,
106
+ "-v", actual_voice,
107
+ "-t", texto,
108
+ "--write-media", mp3_output_file
109
+ ]
110
+
111
+ print("Gerando áudio...")
112
+ try:
113
+ subprocess.run(cmd, check=True)
114
+ except subprocess.CalledProcessError as e:
115
+ print("Erro ao gerar áudio:", e)
116
+ return None
117
+
118
+ print("Áudio gerado com sucesso!")
119
+ wav_output_file = os.path.join(output_dir, "new_audio.wav")
120
+ audio = AudioSegment.from_mp3(mp3_output_file)
121
+ audio.export(wav_output_file, format="wav")
122
+ return wav_output_file
123
+
124
+ def generate_audio_from_file(file_path, modelo_de_voz, velocidade, tom, volume):
125
+ # Extrai o nome real da voz formatada, se necessário
126
+ actual_voice = extract_voice_name(modelo_de_voz)
127
+
128
+ # Formatação dos parâmetros com sinais adequados
129
+ rate_str = f"+{velocidade}%" if velocidade >= 0 else f"{velocidade}%"
130
+ pitch_str = f"+{tom}Hz" if tom >= 0 else f"{tom}Hz"
131
+ volume_str = f"+{volume}%" if volume >= 0 else f"{volume}%"
132
+
133
+ output_dir = "output"
134
+ os.makedirs(output_dir, exist_ok=True)
135
+ mp3_output_file = os.path.join(output_dir, "new_audio.mp3")
136
+
137
+ # Usar -f FILE para passar o caminho do arquivo de texto
138
+ cmd = [
139
+ "edge-tts",
140
+ "-f", file_path, # Certificar que o conteúdo do arquivo seja texto puro
141
+ "--rate=" + rate_str,
142
+ "--pitch=" + pitch_str,
143
+ "--volume=" + volume_str,
144
+ "-v", actual_voice,
145
+ "--write-media", mp3_output_file
146
+ ]
147
+
148
+ print("Gerando áudio do arquivo...")
149
+ try:
150
+ subprocess.run(cmd, check=True)
151
+ except subprocess.CalledProcessError as e:
152
+ print("Erro ao gerar áudio:", e)
153
+ return None
154
+
155
+ print("Áudio gerado com sucesso!")
156
+ wav_output_file = os.path.join(output_dir, "new_audio.wav")
157
+ audio = AudioSegment.from_mp3(mp3_output_file)
158
+ audio.export(wav_output_file, format="wav")
159
+ return wav_output_file
160
+
161
+ def controlador_generate_audio_from_file(file, voice_model_input, speed_input, pitch_input, volume_input, checkbox_cortar_silencio):
162
+ if file is None:
163
+ return None
164
+
165
+ # Neste caso, o 'file' já é o caminho do arquivo, então não precisa reescrever
166
+ temp_file_path = file # Caminho do arquivo que você recebe do Gradio
167
+
168
+ # Gerar o áudio
169
+ audio_file = generate_audio_from_file(temp_file_path, voice_model_input, speed_input, pitch_input, volume_input)
170
+
171
+ if audio_file:
172
+ print("Áudio gerado com sucesso:", audio_file)
173
+ if checkbox_cortar_silencio:
174
+ print("Cortando silêncio...")
175
+ remove_silence(audio_file, audio_file)
176
+ print("Silêncio removido com sucesso!")
177
+ else:
178
+ print("Erro ao gerar áudio.")
179
+
180
+ return audio_file
181
+
182
+ with gr.Blocks(theme=gr.themes.Default(primary_hue="green", secondary_hue="blue"), title="QuickTTS") as iface:
183
+ gr.Markdown(badges)
184
+ gr.Markdown(description)
185
+
186
+ voices_data = load_voices()
187
+ available_languages = list(voices_data.keys())
188
+
189
+ with gr.Tabs():
190
+ with gr.TabItem("Edge-TTS"):
191
+ gr.Markdown("É ilimitado, podendo até mesmo colocar um livro inteiro, mas claro, tem a questão de tempo, quanto maior o texto, mais demorado é, dublagem por SRT talvez um dia eu bote.")
192
+
193
+ with gr.Row():
194
+ # Language selection dropdown
195
+ language_input = gr.Dropdown(
196
+ choices=available_languages,
197
+ label="Idioma",
198
+ value=available_languages[52] if available_languages else None
199
+ )
200
+
201
+ # Voice model dropdown (will be updated based on language selection)
202
+ initial_voices = get_voice_options(available_languages[52], voices_data) if available_languages else []
203
+ voice_model_input = gr.Dropdown(
204
+ choices=initial_voices,
205
+ label="Modelo de Voz",
206
+ value=initial_voices[0] if initial_voices else None
207
+ )
208
+
209
+ # Connect language selection to voice model update
210
+ language_input.change(
211
+ fn=update_voice_options,
212
+ inputs=[language_input],
213
+ outputs=[voice_model_input]
214
+ )
215
+
216
+ audio_input = gr.Textbox(label="Texto", value='Texto de exemplo!', interactive=True)
217
+
218
+ with gr.Row():
219
+ with gr.Column():
220
+ speed_input = gr.Slider(
221
+ minimum=-200,
222
+ maximum=200,
223
+ label="Velocidade (%)",
224
+ value=0,
225
+ interactive=True
226
+ )
227
+ with gr.Column():
228
+ pitch_input = gr.Slider(
229
+ minimum=-100,
230
+ maximum=100,
231
+ label="Tom (Hz)",
232
+ value=0,
233
+ interactive=True
234
+ )
235
+ with gr.Column():
236
+ volume_input = gr.Slider(
237
+ minimum=-99,
238
+ maximum=100,
239
+ label="Volume (%)",
240
+ value=0,
241
+ interactive=True
242
+ )
243
+
244
+ checkbox_cortar_silencio = gr.Checkbox(label="Cortar Silencio", interactive=True)
245
+ audio_output = gr.Audio(
246
+ label="Resultado",
247
+ type="filepath",
248
+ interactive=False,
249
+ streaming=False,
250
+ format="mp3",
251
+ waveform_options={"show_controls": True},
252
+ autoplay=False,
253
+ show_download_button=True
254
+ )
255
+
256
+ with gr.Row():
257
+ edgetts_button = gr.Button(value="Falar")
258
+ edgetts_button.click(
259
+ controlador_generate_audio,
260
+ inputs=[
261
+ audio_input,
262
+ voice_model_input,
263
+ speed_input,
264
+ pitch_input, # New input
265
+ volume_input, # New input
266
+ checkbox_cortar_silencio
267
+ ],
268
+ outputs=[audio_output]
269
+ )
270
+
271
+ clear_button = gr.ClearButton(audio_input, value='Limpar')
272
+
273
+ # Add update voices button at the top
274
+ update_voices_btn = gr.Button(value="Atualizar Lista de Vozes")
275
+ # Connect update voices button to refresh function
276
+ update_voices_btn.click(
277
+ fn=update_voices_and_refresh,
278
+ inputs=[],
279
+ outputs=[language_input, voice_model_input]
280
+ )
281
+ gr.Markdown("Agradecimentos a rany2 pelo Edge-TTS")
282
+
283
+ with gr.TabItem("Lote (Arquivo txt)"):
284
+ gr.Markdown("Carregar texto de um arquivo")
285
+ # Language and voice selection (same as first tab)
286
+ with gr.Row():
287
+ language_input_file = gr.Dropdown(
288
+ choices=available_languages,
289
+ label="Idioma",
290
+ value=available_languages[52] if available_languages else None
291
+ )
292
+
293
+ initial_voices = get_voice_options(available_languages[52], voices_data) if available_languages else []
294
+ voice_model_input_file = gr.Dropdown(
295
+ choices=initial_voices,
296
+ label="Modelo de Voz",
297
+ value=initial_voices[0] if initial_voices else None
298
+ )
299
+
300
+ language_input_file.change(
301
+ fn=update_voice_options,
302
+ inputs=[language_input_file],
303
+ outputs=[voice_model_input_file]
304
+ )
305
+ gr.Markdown("O programa vai ler linha por linha e entregar em um único áudio")
306
+ # File input
307
+ file_input = gr.File(
308
+ label="Arquivo de Texto",
309
+ file_types=[".txt"],
310
+ type="filepath"
311
+ )
312
+
313
+ with gr.Row():
314
+ with gr.Column():
315
+ speed_input_file = gr.Slider(
316
+ minimum=-200,
317
+ maximum=200,
318
+ label="Velocidade (%)",
319
+ value=0,
320
+ interactive=True
321
+ )
322
+ with gr.Column():
323
+ pitch_input_file = gr.Slider(
324
+ minimum=-100,
325
+ maximum=100,
326
+ label="Tom (Hz)",
327
+ value=0,
328
+ interactive=True
329
+ )
330
+ with gr.Column():
331
+ volume_input_file = gr.Slider(
332
+ minimum=-99,
333
+ maximum=100,
334
+ label="Volume (%)",
335
+ value=0,
336
+ interactive=True
337
+ )
338
+
339
+ checkbox_cortar_silencio_file = gr.Checkbox(label="Cortar Silencio", interactive=True)
340
+ audio_output_file = gr.Audio(label="Resultado", type="filepath", interactive=False)
341
+ with gr.Row():
342
+ edgetts_button_file = gr.Button(value="Falar")
343
+ edgetts_button_file.click(
344
+ controlador_generate_audio_from_file,
345
+ inputs=[
346
+ file_input,
347
+ voice_model_input_file,
348
+ speed_input_file,
349
+ pitch_input_file,
350
+ volume_input_file,
351
+ checkbox_cortar_silencio_file
352
+ ],
353
+ outputs=[audio_output_file]
354
+ )
355
+
356
+ clear_button_file = gr.ClearButton(file_input, value='Limpar')
357
+
358
+ gr.Markdown("Agradecimentos a rany2 pelo Edge-TTS")
359
+
360
+ gr.Markdown("""
361
+ Desenvolvido por Rafael Godoy <br>
362
+ Apoie o projeto pelo https://nubank.com.br/pagar/1ls6a4/0QpSSbWBSq, qualquer valor é bem vindo.
363
+ """)
364
  iface.launch()