Spaces:
Sleeping
Sleeping
Upload 2 files
Browse files- edgeTTS.py +34 -10
- tiktokTTS.py +43 -24
edgeTTS.py
CHANGED
|
@@ -90,28 +90,52 @@ def controlador_generate_audio_from_file(file, voice_model_input, speed, pitch,
|
|
| 90 |
|
| 91 |
# --- Lógica de Processamento de SRT (Usa Edge-TTS) ---
|
| 92 |
async def process_srt_file(srt_file_path, voice, output_dir_str, pitch, volume, srt_temp_deleta, progress=None):
|
| 93 |
-
from edge_tts import Communicate as EdgeTTS
|
|
|
|
|
|
|
| 94 |
subs = pysrt.open(srt_file_path)
|
| 95 |
output_dir = Path(output_dir_str)
|
| 96 |
output_dir.mkdir(parents=True, exist_ok=True)
|
| 97 |
|
| 98 |
-
total_indices = len(subs)
|
| 99 |
pitch_str = f"+{pitch}Hz" if pitch >= 0 else f"{pitch}Hz"
|
| 100 |
volume_str = f"+{volume}%" if volume >= 0 else f"{volume}%"
|
|
|
|
| 101 |
|
| 102 |
-
with tqdm(total=
|
| 103 |
for sub in subs:
|
| 104 |
-
temp_file = output_dir / f"{sub.index:02d}_temp.mp3"
|
| 105 |
output_file = output_dir / f"{sub.index:02d}.mp3"
|
|
|
|
| 106 |
target_duration_ms = timetoms(sub.end) - timetoms(sub.start)
|
| 107 |
-
|
|
|
|
| 108 |
if not output_file.exists() or output_file.stat().st_size == 0:
|
| 109 |
-
|
| 110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
|
|
|
|
|
|
|
|
|
| 115 |
pbar.update(1)
|
| 116 |
|
| 117 |
final_audio = await merge_audio_files(output_dir, srt_file_path)
|
|
|
|
| 90 |
|
| 91 |
# --- Lógica de Processamento de SRT (Usa Edge-TTS) ---
|
| 92 |
async def process_srt_file(srt_file_path, voice, output_dir_str, pitch, volume, srt_temp_deleta, progress=None):
|
| 93 |
+
from edge_tts import Communicate as EdgeTTS
|
| 94 |
+
from pydub import AudioSegment # Adicionado para gerar silêncio
|
| 95 |
+
|
| 96 |
subs = pysrt.open(srt_file_path)
|
| 97 |
output_dir = Path(output_dir_str)
|
| 98 |
output_dir.mkdir(parents=True, exist_ok=True)
|
| 99 |
|
|
|
|
| 100 |
pitch_str = f"+{pitch}Hz" if pitch >= 0 else f"{pitch}Hz"
|
| 101 |
volume_str = f"+{volume}%" if volume >= 0 else f"{volume}%"
|
| 102 |
+
max_retries = 3 # Número de tentativas para cada legenda
|
| 103 |
|
| 104 |
+
with tqdm(total=len(subs), desc="Gerando e ajustando áudios com EdgeTTS", unit="segmento") as pbar:
|
| 105 |
for sub in subs:
|
|
|
|
| 106 |
output_file = output_dir / f"{sub.index:02d}.mp3"
|
| 107 |
+
temp_file = output_dir / f"{sub.index:02d}_temp.mp3"
|
| 108 |
target_duration_ms = timetoms(sub.end) - timetoms(sub.start)
|
| 109 |
+
|
| 110 |
+
# Só processa se o arquivo final não existir
|
| 111 |
if not output_file.exists() or output_file.stat().st_size == 0:
|
| 112 |
+
success = False
|
| 113 |
+
# Loop de retentativa
|
| 114 |
+
for attempt in range(max_retries):
|
| 115 |
+
try:
|
| 116 |
+
tts_edge = EdgeTTS(text=sub.text, voice=voice, pitch=pitch_str, volume=volume_str)
|
| 117 |
+
await tts_edge.save(str(temp_file))
|
| 118 |
+
|
| 119 |
+
# Verifica se o arquivo foi realmente criado e não está vazio
|
| 120 |
+
if temp_file.exists() and temp_file.stat().st_size > 0:
|
| 121 |
+
await adjust_audio_speed(str(temp_file), str(output_file), target_duration_ms)
|
| 122 |
+
os.remove(temp_file)
|
| 123 |
+
success = True
|
| 124 |
+
break # Sai do loop de retentativa se tiver sucesso
|
| 125 |
+
else:
|
| 126 |
+
print(f"Aviso: Tentativa {attempt + 1} para o índice {sub.index} falhou (arquivo não criado). Retentando...")
|
| 127 |
+
|
| 128 |
+
except Exception as e:
|
| 129 |
+
print(f"Aviso: Tentativa {attempt + 1} para o índice {sub.index} falhou com erro: {e}. Retentando...")
|
| 130 |
+
|
| 131 |
+
await asyncio.sleep(1) # Espera 1 segundo antes da próxima tentativa
|
| 132 |
|
| 133 |
+
# Se todas as tentativas falharem, gera silêncio
|
| 134 |
+
if not success:
|
| 135 |
+
print(f"ERRO: Todas as {max_retries} tentativas falharam para o índice {sub.index}. Gerando silêncio.")
|
| 136 |
+
silent_segment = AudioSegment.silent(duration=target_duration_ms)
|
| 137 |
+
silent_segment.export(str(output_file), format="mp3")
|
| 138 |
+
|
| 139 |
pbar.update(1)
|
| 140 |
|
| 141 |
final_audio = await merge_audio_files(output_dir, srt_file_path)
|
tiktokTTS.py
CHANGED
|
@@ -73,32 +73,51 @@ def get_tiktok_voice_options(language):
|
|
| 73 |
return TIKTOK_VOICES_CATEGORIZED.get(language, [])
|
| 74 |
|
| 75 |
# --- Função Controladora de Texto/Arquivo ---
|
| 76 |
-
def
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
print("Áudio TikTok gerado com sucesso!")
|
| 90 |
-
if cut_silence:
|
| 91 |
-
print("Removendo silêncio do áudio TikTok..."); remove_silence(output_file, output_file); print("Silêncio removido.")
|
| 92 |
-
return output_file
|
| 93 |
|
| 94 |
-
|
| 95 |
-
print(f"!!! TIKTOK TTS NETWORK ERROR DETECTED: {e}")
|
| 96 |
-
raise gr.Error(TIKTOK_CONNECTION_ERROR_MSG)
|
| 97 |
-
except KeyError:
|
| 98 |
-
raise gr.Error(f"A voz '{voice_str}' não foi encontrada.")
|
| 99 |
-
except Exception as e:
|
| 100 |
-
print(f"!!! TIKTOK TTS UNEXPECTED ERROR: {type(e).__name__} - {e}")
|
| 101 |
-
raise gr.Error(f"Ocorreu um erro inesperado no TikTok TTS, se tiver usando GRADIO, mude pra Google Colab: {e}")
|
| 102 |
|
| 103 |
# --- NOVA LÓGICA DE PROCESSAMENTO DE SRT PARA TIKTOK ---
|
| 104 |
|
|
|
|
| 73 |
return TIKTOK_VOICES_CATEGORIZED.get(language, [])
|
| 74 |
|
| 75 |
# --- Função Controladora de Texto/Arquivo ---
|
| 76 |
+
async def process_srt_file_tiktok(srt_file_path, voice_str, output_dir_str, srt_temp_deleta, progress=None):
|
| 77 |
+
subs = pysrt.open(srt_file_path)
|
| 78 |
+
output_dir = Path(output_dir_str)
|
| 79 |
+
output_dir.mkdir(parents=True, exist_ok=True)
|
| 80 |
+
max_retries = 3 # Número de tentativas para cada legenda
|
| 81 |
+
|
| 82 |
+
with tqdm(total=len(subs), desc="Gerando e ajustando áudios com TikTok", unit="segmento") as pbar:
|
| 83 |
+
for sub in subs:
|
| 84 |
+
output_file = output_dir / f"{sub.index:02d}.mp3"
|
| 85 |
+
temp_file = output_dir / f"{sub.index:02d}_temp.mp3"
|
| 86 |
+
target_duration_ms = timetoms(sub.end) - timetoms(sub.start)
|
| 87 |
+
|
| 88 |
+
if not output_file.exists() or output_file.stat().st_size == 0:
|
| 89 |
+
success = False
|
| 90 |
+
for attempt in range(max_retries):
|
| 91 |
+
try:
|
| 92 |
+
await asyncio.to_thread(tts, sub.text, Voice[voice_str], str(temp_file))
|
| 93 |
+
|
| 94 |
+
if temp_file.exists() and temp_file.stat().st_size > 0:
|
| 95 |
+
await adjust_audio_speed(str(temp_file), str(output_file), target_duration_ms)
|
| 96 |
+
os.remove(temp_file)
|
| 97 |
+
success = True
|
| 98 |
+
break
|
| 99 |
+
else:
|
| 100 |
+
print(f"Aviso: Tentativa {attempt + 1} para o índice {sub.index} (TikTok) falhou. Retentando...")
|
| 101 |
+
|
| 102 |
+
except Exception as e:
|
| 103 |
+
print(f"Aviso: Tentativa {attempt + 1} para o índice {sub.index} (TikTok) falhou com erro: {e}. Retentando...")
|
| 104 |
+
|
| 105 |
+
await asyncio.sleep(1)
|
| 106 |
+
|
| 107 |
+
if not success:
|
| 108 |
+
print(f"ERRO: Todas as {max_retries} tentativas (TikTok) falharam para o índice {sub.index}. Gerando silêncio.")
|
| 109 |
+
silent_segment = AudioSegment.silent(duration=target_duration_ms)
|
| 110 |
+
silent_segment.export(str(output_file), format="mp3")
|
| 111 |
+
|
| 112 |
+
pbar.update(1)
|
| 113 |
+
|
| 114 |
+
final_audio = await merge_audio_files(output_dir, srt_file_path)
|
| 115 |
|
| 116 |
+
if srt_temp_deleta:
|
| 117 |
+
shutil.rmtree(output_dir, ignore_errors=True)
|
| 118 |
+
print(f"Pasta temporária {output_dir} apagada.")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
|
| 120 |
+
return final_audio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
# --- NOVA LÓGICA DE PROCESSAMENTO DE SRT PARA TIKTOK ---
|
| 123 |
|