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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -117
app.py CHANGED
@@ -1,138 +1,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
- # Etapa 1: Extrair áudio
86
- progress(0.1, "Extraindo áudio...")
87
- audio_path = os.path.join(UPLOAD_FOLDER, "audio.wav")
88
  (
89
  ffmpeg
90
- .input(video)
91
- .output(audio_path, ac=1, ar=16000)
92
- .global_args('-loglevel', 'error')
93
  .run(overwrite_output=True)
94
  )
95
-
96
- # Etapa 2: Transcrição paralela
97
- progress(0.3, "Transcrevendo...")
98
- transcription = transcribe_audio(audio_path)
99
-
100
- # Etapa 3: Tradução em lote
101
- progress(0.5, "Traduzindo...")
102
- translated_text = translate_text(transcription)
103
-
104
- # Etapa 4: Síntese de voz acelerada
105
- progress(0.7, "Sintetizando voz...")
106
- synthesized_audio = os.path.join(UPLOAD_FOLDER, "synthesized_audio.wav")
107
- synthesize_speech(translated_text, synthesized_audio)
108
-
109
- # Etapa 5: Processamento final do vídeo
110
- progress(0.9, "Montando vídeo...")
111
- output_path = os.path.join(OUTPUT_FOLDER, "video_traduzido.mp4")
112
- (
113
- ffmpeg
114
- .input(video)
115
- .output(output_path, vcodec='copy', acodec='copy', map='0:v:0')
116
- .input(synthesized_audio)
117
- .global_args('-loglevel', 'error')
118
- .run(overwrite_output=True)
119
- )
120
-
121
- return output_path
122
-
123
  except Exception as e:
124
- return f"Erro: {str(e)}"
 
125
 
126
- # Interface otimizada
127
- iface = gr.Interface(
128
- fn=translate_video,
129
- inputs=gr.Video(label="Vídeo de Entrada"),
130
- outputs=gr.Video(label="Vídeo Traduzido"),
131
- title="🚀 Tradutor de Vídeo Ultra-Rápido",
132
- description="Carregue um vídeo e receba a versão em português com áudio traduzido!",
133
- allow_flagging="never"
134
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
 
136
  if __name__ == "__main__":
137
- iface.launch(server_port=7860, show_error=True)
138
 
 
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