RXTIME commited on
Commit
42d7d7d
·
verified ·
1 Parent(s): 9796a25

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +120 -84
app.py CHANGED
@@ -1,104 +1,140 @@
1
- from transformers import pipeline, MarianMTModel, MarianTokenizer, SpeechT5Processor, SpeechT5ForTextToSpeech, SpeechT5HifiGan
 
2
  import torch
 
 
 
 
 
 
3
  import ffmpeg
4
- import os
5
- from pydub import AudioSegment
6
 
7
- # 1. Reconhecimento de Fala com Whisper (Inglês)
8
- def transcribe_audio(audio_path):
9
- print("Transcrevendo áudio...")
10
- # Carregar o modelo Whisper para inglês
11
- asr = pipeline("automatic-speech-recognition", model="openai/whisper-large-v2")
12
-
13
- # Processar o áudio
14
- result = asr(audio_path, chunk_length_s=30)
15
- text = result['text']
16
- print(f"Texto transcrito: {text}")
17
- return text
18
 
 
 
 
19
 
20
- # 2. Tradução Automática com MarianMT (Inglês → Português)
21
- def translate_text(text):
22
- print("Traduzindo texto para o português...")
23
- # Carregar o modelo MarianMT para inglês → português
24
- model_name = "Helsinki-NLP/opus-mt-en-pt"
25
- tokenizer = MarianTokenizer.from_pretrained(model_name)
26
- model = MarianMTModel.from_pretrained(model_name)
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- # Tokenizar e traduzir
29
- inputs = tokenizer(text, return_tensors="pt")
30
- translated_ids = model.generate(**inputs)
31
- translated_text = tokenizer.decode(translated_ids[0], skip_special_tokens=True)
32
- print(f"Texto traduzido: {translated_text}")
33
- return translated_text
34
-
35
-
36
- # 3. Síntese de Voz com VITS/FastSpeech (Português)
37
- def synthesize_speech(text, output_path="output_speech.wav"):
38
- print("Sintetizando voz em português...")
39
- # Carregar o processador e o modelo VITS
40
- processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
41
- model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
42
- vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
43
 
44
- # Obter embeddings de voz (opcional: usar embeddings pré-carregados)
45
- speaker_embeddings = torch.randn((1, 512)) # Gerar embeddings aleatórios
46
 
47
- # Processar o texto
48
- inputs = processor(text=text, return_tensors="pt")
49
- speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)
 
 
 
 
 
 
 
 
 
50
 
51
- # Salvar o áudio gerado
52
- speech_np = speech.numpy()
53
- AudioSegment(speech_np.tobytes(), frame_rate=16000, sample_width=2, channels=1).export(output_path, format="wav")
54
- print(f"Áudio sintetizado salvo em: {output_path}")
55
- return output_path
56
 
 
 
 
 
 
 
 
 
 
57
 
58
- # 4. Substituição de Áudio no Vídeo com FFmpeg
59
- def replace_audio_in_video(input_video, new_audio, output_video):
60
- print("Substituindo áudio no vídeo...")
61
  try:
62
- # Usar FFmpeg para substituir o áudio
 
 
 
 
 
63
  (
64
  ffmpeg
65
- .input(input_video)
66
- .output(new_audio, output_video, map_video=0, map_audio=1)
 
67
  .run(overwrite_output=True)
68
  )
69
- print(f"Vídeo com áudio substituído salvo em: {output_video}")
70
- except Exception as e:
71
- print(f"Erro ao substituir áudio: {e}")
72
 
 
 
 
73
 
74
- # Função Principal
75
- def main():
76
- # Caminhos dos arquivos
77
- input_video_path = "input_video.mp4" # Substitua pelo caminho do seu vídeo
78
- temp_audio_path = "temp_audio.wav"
79
- output_video_path = "output_video.mp4"
80
-
81
- # Passo 1: Extrair áudio do vídeo
82
- print("Extraindo áudio do vídeo...")
83
- (
84
- ffmpeg
85
- .input(input_video_path)
86
- .output(temp_audio_path)
87
- .run(overwrite_output=True)
88
- )
89
-
90
- # Passo 2: Transcrever o áudio
91
- transcribed_text = transcribe_audio(temp_audio_path)
92
-
93
- # Passo 3: Traduzir o texto para português
94
- translated_text = translate_text(transcribed_text)
95
-
96
- # Passo 4: Sintetizar a voz traduzida
97
- synthesized_audio_path = synthesize_speech(translated_text, output_path="synthesized_audio.wav")
98
-
99
- # Passo 5: Substituir o áudio no vídeo
100
- replace_audio_in_video(input_video_path, synthesized_audio_path, output_video_path)
 
 
 
 
 
 
 
 
101
 
102
  if __name__ == "__main__":
103
- main()
104
-
 
1
+ import gradio as gr
2
+ import os
3
  import torch
4
+ import torchaudio
5
+ from transformers import (
6
+ WhisperProcessor, WhisperForConditionalGeneration,
7
+ MarianMTModel, MarianTokenizer,
8
+ SpeechT5Processor, SpeechT5ForTextToSpeech
9
+ )
10
  import ffmpeg
11
+ import soundfile as sf
12
+ import numpy as np
13
 
14
+ # Configurações
15
+ UPLOAD_FOLDER = "uploads"
16
+ OUTPUT_FOLDER = "outputs"
17
+ os.makedirs(UPLOAD_FOLDER, exist_ok=True)
18
+ os.makedirs(OUTPUT_FOLDER, exist_ok=True)
 
 
 
 
 
 
19
 
20
+ # Configurar dispositivo (GPU se disponível)
21
+ device = "cuda" if torch.cuda.is_available() else "cpu"
22
+ torch.backends.cudnn.benchmark = True # Acelera GPU NVIDIA
23
 
24
+ # Carregar modelos uma única vez (cache)
25
+ WHISPER_MODEL = "openai/whisper-tiny" # Modelo mais rápido
26
+ TRANSLATION_MODEL = "Helsinki-NLP/opus-mt-tc-big-en-pt" # Modelo alternativo
27
+ TTS_MODEL = "microsoft/speecht5_tts"
28
+
29
+ # Inicialização rápida dos modelos
30
+ print("Carregando modelos...")
31
+ whisper_processor = WhisperProcessor.from_pretrained(WHISPER_MODEL)
32
+ whisper_model = WhisperForConditionalGeneration.from_pretrained(WHISPER_MODEL).to(device)
33
+
34
+ translation_tokenizer = MarianTokenizer.from_pretrained(TRANSLATION_MODEL)
35
+ translation_model = MarianMTModel.from_pretrained(TRANSLATION_MODEL).to(device)
36
+
37
+ tts_processor = SpeechT5Processor.from_pretrained(TTS_MODEL)
38
+ tts_model = SpeechT5ForTextToSpeech.from_pretrained(TTS_MODEL).to(device)
39
+
40
+ # Funções otimizadas
41
+ def transcribe_audio(audio_path):
42
+ waveform, sample_rate = torchaudio.load(audio_path)
43
+ waveform = waveform.to(device)
44
 
45
+ # Processamento em chunks para áudios longos
46
+ inputs = whisper_processor(
47
+ waveform.squeeze().cpu().numpy(),
48
+ sampling_rate=sample_rate,
49
+ return_tensors="pt",
50
+ chunk_length_s=30 # Processar em chunks de 30 segundos
51
+ ).to(device)
 
 
 
 
 
 
 
 
52
 
53
+ with torch.inference_mode():
54
+ predicted_ids = whisper_model.generate(**inputs)
55
 
56
+ return whisper_processor.batch_decode(predicted_ids, skip_special_tokens=True)[0]
57
+
58
+ def translate_text(text):
59
+ inputs = translation_tokenizer(text, return_tensors="pt", truncation=True).to(device)
60
+ with torch.inference_mode():
61
+ translated_ids = translation_model.generate(**inputs)
62
+ return translation_tokenizer.decode(translated_ids[0], skip_special_tokens=True)
63
+
64
+ def synthesize_speech(text, output_path):
65
+ inputs = tts_processor(text, return_tensors="pt").to(device)
66
+ with torch.inference_mode():
67
+ speech = tts_model.generate_speech(inputs["input_ids"], tts_model.speaker_embeddings)
68
 
69
+ # Converter para formato compatível com vídeo (44100 Hz, stereo)
70
+ sf.write(output_path, np.tile(speech.cpu().numpy(), (2, 1)).T, 44100, subtype='PCM_16')
 
 
 
71
 
72
+ def process_video(video_path, output_path):
73
+ # Processamento paralelizado com FFmpeg
74
+ (
75
+ ffmpeg
76
+ .input(video_path)
77
+ .output(output_path, vcodec='copy', acodec='aac', strict='experimental')
78
+ .global_args('-loglevel', 'error') # Reduzir logs
79
+ .run(overwrite_output=True, cmd='ffmpeg')
80
+ )
81
 
82
+ # Fluxo principal otimizado
83
+ def translate_video(video, progress=gr.Progress()):
 
84
  try:
85
+ # O Gradio passa o caminho do arquivo como uma string
86
+ video_path = video
87
+
88
+ # Etapa 1: Extrair áudio
89
+ progress(0.1, "Extraindo áudio...")
90
+ audio_path = os.path.join(UPLOAD_FOLDER, "audio.wav")
91
  (
92
  ffmpeg
93
+ .input(video_path)
94
+ .output(audio_path, ac=1, ar=16000)
95
+ .global_args('-loglevel', 'error')
96
  .run(overwrite_output=True)
97
  )
 
 
 
98
 
99
+ # Etapa 2: Transcrição paralela
100
+ progress(0.3, "Transcrevendo...")
101
+ transcription = transcribe_audio(audio_path)
102
 
103
+ # Etapa 3: Tradução em lote
104
+ progress(0.5, "Traduzindo...")
105
+ translated_text = translate_text(transcription)
106
+
107
+ # Etapa 4: Síntese de voz acelerada
108
+ progress(0.7, "Sintetizando voz...")
109
+ synthesized_audio = os.path.join(UPLOAD_FOLDER, "synthesized_audio.wav")
110
+ synthesize_speech(translated_text, synthesized_audio)
111
+
112
+ # Etapa 5: Processamento final do vídeo
113
+ progress(0.9, "Montando vídeo...")
114
+ output_path = os.path.join(OUTPUT_FOLDER, "video_traduzido.mp4")
115
+ (
116
+ ffmpeg
117
+ .input(video_path)
118
+ .output(output_path, vcodec='copy', acodec='copy', map='0:v:0')
119
+ .input(synthesized_audio)
120
+ .global_args('-loglevel', 'error')
121
+ .run(overwrite_output=True)
122
+ )
123
+
124
+ return output_path
125
+
126
+ except Exception as e:
127
+ return f"Erro: {str(e)}"
128
+
129
+ # Interface otimizada
130
+ iface = gr.Interface(
131
+ fn=translate_video,
132
+ inputs=gr.Video(label="Vídeo de Entrada"),
133
+ outputs=gr.Video(label="Vídeo Traduzido"),
134
+ title="🚀 Tradutor de Vídeo Ultra-Rápido",
135
+ description="Carregue um vídeo e receba a versão em português com áudio traduzido!",
136
+ allow_flagging="never"
137
+ )
138
 
139
  if __name__ == "__main__":
140
+ iface.launch(server_port=7860, show_error=True)