Spaces:
Runtime error
Runtime error
Upload 2 files
Browse files- app.py +81 -0
- requeriments.txt +8 -0
app.py
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import zipfile
|
| 3 |
+
from tqdm import tqdm
|
| 4 |
+
from faster_whisper import WhisperModel
|
| 5 |
+
from datetime import timedelta
|
| 6 |
+
import srt
|
| 7 |
+
from transformers import pipeline
|
| 8 |
+
import torch
|
| 9 |
+
import gradio as gr
|
| 10 |
+
|
| 11 |
+
OUTPUT_DIR = "outputs"
|
| 12 |
+
LEGENDAS_DIR = os.path.join(OUTPUT_DIR, "legendas")
|
| 13 |
+
os.makedirs(LEGENDAS_DIR, exist_ok=True)
|
| 14 |
+
|
| 15 |
+
IDIOMAS = {
|
| 16 |
+
"Alemão": "de", "Cebuano": "ceb", "Chinês": "zh", "Coreano": "ko",
|
| 17 |
+
"Espanhol": "es", "Francês": "fr", "Inglês": "en", "Italiano": "it",
|
| 18 |
+
"Japonês": "ja", "Português": "pt", "Russo": "ru", "Tagalog": "tl"
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
print("Carregando modelos de IA...")
|
| 22 |
+
try:
|
| 23 |
+
MODELO_WHISPER = "medium"
|
| 24 |
+
device = "cpu"
|
| 25 |
+
compute_type = "int8"
|
| 26 |
+
model_whisper = WhisperModel(MODELO_WHISPER, device=device, compute_type=compute_type)
|
| 27 |
+
model_translator = pipeline("translation", model="facebook/m2m100_418M")
|
| 28 |
+
print("Modelos carregados com sucesso!")
|
| 29 |
+
except Exception as e:
|
| 30 |
+
print(f"Erro ao carregar os modelos: {e}")
|
| 31 |
+
model_whisper = None
|
| 32 |
+
model_translator = None
|
| 33 |
+
|
| 34 |
+
def gerar_legenda_interface(arquivos_path, idioma_origem, idioma_destino, progresso=gr.Progress(track_tqdm=True)):
|
| 35 |
+
if not arquivos_path: raise gr.Error("Por favor, envie pelo menos um arquivo.")
|
| 36 |
+
if not idioma_origem or not idioma_destino: raise gr.Error("Por favor, selecione os idiomas.")
|
| 37 |
+
|
| 38 |
+
lang_origem_code = IDIOMAS[idioma_origem]
|
| 39 |
+
lang_destino_code = IDIOMAS[idioma_destino]
|
| 40 |
+
|
| 41 |
+
if os.path.exists(LEGENDAS_DIR):
|
| 42 |
+
for f in os.listdir(LEGENDAS_DIR): os.remove(os.path.join(LEGENDAS_DIR, f))
|
| 43 |
+
|
| 44 |
+
for caminho_video in tqdm(arquivos_path, desc="Processando arquivos"):
|
| 45 |
+
nome_base = os.path.splitext(os.path.basename(caminho_video))[0]
|
| 46 |
+
segmentos, _ = model_whisper.transcribe(caminho_video, language=lang_origem_code, beam_size=5, log_progress=False)
|
| 47 |
+
|
| 48 |
+
segmentos_lista = list(segmentos)
|
| 49 |
+
textos_originais = [seg.text.strip() for seg in segmentos_lista]
|
| 50 |
+
|
| 51 |
+
if lang_origem_code != lang_destino_code:
|
| 52 |
+
textos_finais = model_translator(textos_originais, src_lang=lang_origem_code, tgt_lang=lang_destino_code)
|
| 53 |
+
textos_finais = [t['translation_text'] for t in textos_finais]
|
| 54 |
+
else: textos_finais = textos_originais
|
| 55 |
+
|
| 56 |
+
legendas = []
|
| 57 |
+
for i, seg in enumerate(segmentos_lista):
|
| 58 |
+
legendas.append(srt.Subtitle(index=i+1, start=timedelta(seconds=seg.start), end=timedelta(seconds=seg.end), content=textos_finais[i]))
|
| 59 |
+
|
| 60 |
+
nome_srt = f"{nome_base}_{lang_destino_code}.srt"
|
| 61 |
+
caminho_srt = os.path.join(LEGENDAS_DIR, nome_srt)
|
| 62 |
+
with open(caminho_srt, "w", encoding="utf-8") as f: f.write(srt.compose(legendas))
|
| 63 |
+
|
| 64 |
+
zip_path = os.path.join(OUTPUT_DIR, "legendas_geradas.zip")
|
| 65 |
+
with zipfile.ZipFile(zip_path, 'w') as zipf:
|
| 66 |
+
for file in os.listdir(LEGENDAS_DIR): zipf.write(os.path.join(LEGENDAS_DIR, file), arcname=file)
|
| 67 |
+
return zip_path
|
| 68 |
+
|
| 69 |
+
with gr.Blocks(theme=gr.themes.Default(), title="Gerador de Legendas") as interface:
|
| 70 |
+
gr.Markdown("# 🎬 Gerador Automático de Legendas e Traduções")
|
| 71 |
+
with gr.Row():
|
| 72 |
+
with gr.Column(scale=1):
|
| 73 |
+
input_arquivos = gr.File(label="1. Envie seus arquivos de vídeo ou áudio", file_count="multiple", type="filepath")
|
| 74 |
+
input_idioma_origem = gr.Dropdown(choices=sorted(list(IDIOMAS.keys())), label="2. Idioma original do áudio", value="Inglês")
|
| 75 |
+
input_idioma_destino = gr.Dropdown(choices=sorted(list(IDIOMAS.keys())), label="3. Idioma desejado para a legenda", value="Português")
|
| 76 |
+
botao_gerar = gr.Button("✨ Gerar Legendas!", variant="primary")
|
| 77 |
+
with gr.Column(scale=1):
|
| 78 |
+
output_legenda = gr.File(label="Resultado para Download (Arquivo .ZIP)", interactive=False)
|
| 79 |
+
botao_gerar.click(fn=gerar_legenda_interface, inputs=[input_arquivos, input_idioma_origem, input_idioma_destino], outputs=[output_legenda])
|
| 80 |
+
|
| 81 |
+
interface.launch()
|
requeriments.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
ctranslate2
|
| 3 |
+
faster-whisper
|
| 4 |
+
torch
|
| 5 |
+
transformers
|
| 6 |
+
sentencepiece
|
| 7 |
+
srt
|
| 8 |
+
tqdm
|