Update app.py
Browse files
app.py
CHANGED
@@ -2,33 +2,37 @@ import gradio as gr
|
|
2 |
import os
|
3 |
import subprocess
|
4 |
import ssl
|
5 |
-
|
|
|
6 |
from transformers import pipeline
|
7 |
-
import torchaudio
|
8 |
-
import librosa
|
9 |
-
import numpy as np
|
10 |
import ffmpeg
|
11 |
|
12 |
# Configuração para evitar erro de SSL
|
13 |
ssl._create_default_https_context = ssl._create_unverified_context
|
14 |
|
|
|
|
|
|
|
|
|
15 |
# Função para extrair áudio do vídeo
|
16 |
-
def extract_audio(video_path):
|
17 |
video = VideoFileClip(video_path)
|
18 |
-
if video.audio is None:
|
19 |
-
raise ValueError("O vídeo não contém áudio.")
|
20 |
audio_path = "temp_audio.wav"
|
|
|
21 |
video.audio.write_audiofile(audio_path, codec='pcm_s16le')
|
|
|
22 |
return audio_path
|
23 |
|
24 |
# Função para transcrever o áudio e gerar legendas
|
25 |
-
def transcribe_audio(audio_path, language):
|
26 |
transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-large-v2")
|
|
|
27 |
result = transcriber(audio_path, return_timestamps=True)
|
|
|
28 |
return result['text'], result['chunks']
|
29 |
|
30 |
-
# Função para clonar a voz e gerar dublagem
|
31 |
-
def clone_voice_and_generate_dub(text, language, audio_path):
|
32 |
cloned_voice_path = "dub_audio.wav"
|
33 |
command = [
|
34 |
"python", "vits_inference.py",
|
@@ -37,33 +41,43 @@ def clone_voice_and_generate_dub(text, language, audio_path):
|
|
37 |
"--output_audio", cloned_voice_path,
|
38 |
"--language", language
|
39 |
]
|
40 |
-
|
|
|
|
|
41 |
return cloned_voice_path
|
42 |
|
43 |
# Função para adicionar legendas ao vídeo
|
44 |
-
def add_subtitles(video_clip, subtitles, primary_lang, secondary_lang
|
45 |
subtitle_clips = []
|
46 |
for chunk in subtitles:
|
47 |
start, end, text = chunk['timestamp'][0], chunk['timestamp'][1], chunk['text']
|
48 |
-
subtitle = TextClip(text, fontsize=30, color='white', bg_color='black', size=(video_clip.w, 50))
|
49 |
-
subtitle = subtitle.set_start(start).set_duration(end - start).set_position(('center', 'bottom'))
|
50 |
subtitle_clips.append(subtitle)
|
|
|
51 |
return CompositeVideoClip([video_clip] + subtitle_clips)
|
52 |
|
53 |
-
# Função para processar o vídeo
|
54 |
-
def process_video(video_path, format_choice, add_subtitles_option, dual_subtitles, primary_lang, secondary_lang, dub_language):
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
58 |
|
59 |
video = VideoFileClip(video_path).set_audio(AudioFileClip(dub_audio_path))
|
60 |
|
61 |
if add_subtitles_option:
|
62 |
-
video = add_subtitles(video, subtitles, primary_lang, secondary_lang if dual_subtitles else None)
|
63 |
|
64 |
final_video_path = "final_video.mp4"
|
|
|
65 |
video.write_videofile(final_video_path, codec='libx264', fps=30)
|
66 |
-
|
|
|
|
|
|
|
|
|
|
|
67 |
|
68 |
# Interface Gradio
|
69 |
iface = gr.Interface(
|
@@ -73,11 +87,11 @@ iface = gr.Interface(
|
|
73 |
gr.Radio(["TikTok/Kwai (9:16)", "YouTube (16:9)"], label="Formato de Saída"),
|
74 |
gr.Checkbox(label="Adicionar Legendas?"),
|
75 |
gr.Checkbox(label="Usar Legenda Dupla?"),
|
76 |
-
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma Principal das Legendas"),
|
77 |
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma Secundário da Legenda", value=None),
|
78 |
-
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma da Dublagem")
|
79 |
],
|
80 |
-
outputs=gr.Video(label="Vídeo Final"),
|
81 |
title="Ferramenta de Dublagem e Legendas Automáticas",
|
82 |
description="Carregue um vídeo, escolha as opções desejadas e receba o vídeo dublado com legendas automáticas!"
|
83 |
)
|
|
|
2 |
import os
|
3 |
import subprocess
|
4 |
import ssl
|
5 |
+
import time
|
6 |
+
from moviepy.editor import VideoFileClip, AudioFileClip, TextClip, CompositeVideoClip
|
7 |
from transformers import pipeline
|
|
|
|
|
|
|
8 |
import ffmpeg
|
9 |
|
10 |
# Configuração para evitar erro de SSL
|
11 |
ssl._create_default_https_context = ssl._create_unverified_context
|
12 |
|
13 |
+
# Função para atualizar a barra de progresso
|
14 |
+
def update_progress(current, total, progress=gr.Progress()):
|
15 |
+
progress(current / total)
|
16 |
+
|
17 |
# Função para extrair áudio do vídeo
|
18 |
+
def extract_audio(video_path, progress):
|
19 |
video = VideoFileClip(video_path)
|
|
|
|
|
20 |
audio_path = "temp_audio.wav"
|
21 |
+
update_progress(10, 100, progress)
|
22 |
video.audio.write_audiofile(audio_path, codec='pcm_s16le')
|
23 |
+
update_progress(20, 100, progress)
|
24 |
return audio_path
|
25 |
|
26 |
# Função para transcrever o áudio e gerar legendas
|
27 |
+
def transcribe_audio(audio_path, language, progress):
|
28 |
transcriber = pipeline("automatic-speech-recognition", model="openai/whisper-large-v2")
|
29 |
+
update_progress(30, 100, progress)
|
30 |
result = transcriber(audio_path, return_timestamps=True)
|
31 |
+
update_progress(40, 100, progress)
|
32 |
return result['text'], result['chunks']
|
33 |
|
34 |
+
# Função para clonar a voz e gerar dublagem
|
35 |
+
def clone_voice_and_generate_dub(text, language, audio_path, progress):
|
36 |
cloned_voice_path = "dub_audio.wav"
|
37 |
command = [
|
38 |
"python", "vits_inference.py",
|
|
|
41 |
"--output_audio", cloned_voice_path,
|
42 |
"--language", language
|
43 |
]
|
44 |
+
update_progress(50, 100, progress)
|
45 |
+
subprocess.run(command)
|
46 |
+
update_progress(70, 100, progress)
|
47 |
return cloned_voice_path
|
48 |
|
49 |
# Função para adicionar legendas ao vídeo
|
50 |
+
def add_subtitles(video_clip, subtitles, primary_lang, secondary_lang, progress):
|
51 |
subtitle_clips = []
|
52 |
for chunk in subtitles:
|
53 |
start, end, text = chunk['timestamp'][0], chunk['timestamp'][1], chunk['text']
|
54 |
+
subtitle = TextClip(text, fontsize=30, color='white', bg_color='black', size=(video_clip.w, 50)).set_start(start).set_duration(end - start).set_position(('center', 'bottom'))
|
|
|
55 |
subtitle_clips.append(subtitle)
|
56 |
+
update_progress(80, 100, progress)
|
57 |
return CompositeVideoClip([video_clip] + subtitle_clips)
|
58 |
|
59 |
+
# Função para processar o vídeo
|
60 |
+
def process_video(video_path, format_choice, add_subtitles_option, dual_subtitles, primary_lang, secondary_lang, dub_language, progress=gr.Progress()):
|
61 |
+
start_time = time.time()
|
62 |
+
|
63 |
+
audio_path = extract_audio(video_path, progress)
|
64 |
+
text, subtitles = transcribe_audio(audio_path, primary_lang, progress)
|
65 |
+
dub_audio_path = clone_voice_and_generate_dub(text, dub_language, audio_path, progress)
|
66 |
|
67 |
video = VideoFileClip(video_path).set_audio(AudioFileClip(dub_audio_path))
|
68 |
|
69 |
if add_subtitles_option:
|
70 |
+
video = add_subtitles(video, subtitles, primary_lang, secondary_lang if dual_subtitles else None, progress)
|
71 |
|
72 |
final_video_path = "final_video.mp4"
|
73 |
+
update_progress(90, 100, progress)
|
74 |
video.write_videofile(final_video_path, codec='libx264', fps=30)
|
75 |
+
update_progress(100, 100, progress)
|
76 |
+
|
77 |
+
end_time = time.time()
|
78 |
+
estimated_time = round(end_time - start_time, 2)
|
79 |
+
|
80 |
+
return final_video_path, f"✅ Processamento concluído! Tempo estimado: {estimated_time} segundos."
|
81 |
|
82 |
# Interface Gradio
|
83 |
iface = gr.Interface(
|
|
|
87 |
gr.Radio(["TikTok/Kwai (9:16)", "YouTube (16:9)"], label="Formato de Saída"),
|
88 |
gr.Checkbox(label="Adicionar Legendas?"),
|
89 |
gr.Checkbox(label="Usar Legenda Dupla?"),
|
90 |
+
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma Principal das Legendas e Dublagem"),
|
91 |
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma Secundário da Legenda", value=None),
|
92 |
+
gr.Dropdown(["en", "es", "fr", "de", "pt"], label="Idioma da Dublagem"),
|
93 |
],
|
94 |
+
outputs=[gr.Video(label="Vídeo Final"), gr.Textbox(label="Status do Processamento")],
|
95 |
title="Ferramenta de Dublagem e Legendas Automáticas",
|
96 |
description="Carregue um vídeo, escolha as opções desejadas e receba o vídeo dublado com legendas automáticas!"
|
97 |
)
|