File size: 4,888 Bytes
11296df
 
 
 
 
 
 
 
0689d10
11296df
 
 
 
 
 
 
 
 
 
 
 
df07d48
 
 
 
 
11296df
 
 
df07d48
 
 
 
 
 
11296df
 
 
df07d48
 
 
 
11296df
df07d48
 
 
 
 
 
 
 
 
11296df
 
 
df07d48
 
 
 
 
 
 
11296df
df07d48
 
 
11296df
0689d10
 
 
 
 
 
 
 
 
11296df
 
df07d48
9142bd9
 
 
 
 
df07d48
9142bd9
df07d48
 
9142bd9
df07d48
 
 
 
9142bd9
df07d48
 
 
 
9142bd9
df07d48
 
 
11296df
9142bd9
df07d48
 
 
11296df
0689d10
 
 
 
 
 
 
df07d48
 
11296df
 
 
 
 
0689d10
11296df
 
 
 
0689d10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import gradio as gr
import whisper
import torch
from transformers import MarianMTModel, MarianTokenizer
import ffmpeg
import requests
import os
import tempfile
import shutil

# Configuração do Hugging Face e ElevenLabs
HF_MODEL = "Helsinki-NLP/opus-mt-mul-en"
ELEVENLABS_API_KEY = os.getenv("ELEVENLABS_API_KEY")  # Defina essa variável no Hugging Face Spaces

# Carregar modelos
whisper_model = whisper.load_model("small")
translator = MarianMTModel.from_pretrained(HF_MODEL)
tokenizer = MarianTokenizer.from_pretrained(HF_MODEL)

# Função para transcrever áudio
def transcribe_audio(video_path: str) -> str:
    try:
        result = whisper_model.transcribe(video_path)
        return result["text"]
    except Exception as e:
        return f"Erro na transcrição: {str(e)}"

# Função para traduzir texto
def translate_text(text: str, target_lang="pt") -> str:
    try:
        inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
        translated_tokens = translator.generate(**inputs)
        return tokenizer.decode(translated_tokens[0], skip_special_tokens=True)
    except Exception as e:
        return f"Erro na tradução: {str(e)}"

# Função para gerar áudio em português (usando ElevenLabs)
def synthesize_speech(text: str, voice="Antônio") -> str:
    try:
        url = "https://api.elevenlabs.io/v1/text-to-speech"
        headers = {"Authorization": f"Bearer {ELEVENLABS_API_KEY}"}
        response = requests.post(url, json={"text": text, "voice": voice}, headers=headers)

        if response.status_code != 200:
            return f"Erro na geração de voz: {response.text}"

        temp_audio = tempfile.NamedTemporaryFile(delete=False, suffix=".mp3")
        with open(temp_audio.name, "wb") as f:
            f.write(response.content)
        return temp_audio.name
    except Exception as e:
        return f"Erro na síntese de voz: {str(e)}"

# Função para substituir o áudio no vídeo
def replace_audio(video_path: str, new_audio_path: str) -> str:
    try:
        output_path = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name
        ffmpeg.input(video_path).output(
            output_path,
            audio=new_audio_path,
            codec="copy"
        ).run(overwrite_output=True)

        return output_path
    except Exception as e:
        return f"Erro na substituição do áudio: {str(e)}"

# Função para mover o arquivo gerado para um local público
def move_video_to_public(output_video_path: str) -> str:
    try:
        public_path = f"/app/public/{os.path.basename(output_video_path)}"  # Ajuste para o ambiente de produção
        shutil.move(output_video_path, public_path)
        return public_path
    except Exception as e:
        return f"Erro ao mover o vídeo para o diretório público: {str(e)}"

# Pipeline completo
def process_video(video_file):
    try:
        # Verifique se o arquivo tem o método 'read' e é do tipo esperado
        if not hasattr(video_file, 'read'):
            return "Erro: O arquivo fornecido não é válido."

        # Salve o arquivo temporariamente
        with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_video:
            temp_video.write(video_file.read())  # Lê o conteúdo do arquivo de entrada
            video_path = temp_video.name

        # Passo 1: Transcrição do áudio
        transcript = transcribe_audio(video_path)
        if "Erro" in transcript:
            return transcript

        # Passo 2: Tradução do texto
        translated_text = translate_text(transcript)
        if "Erro" in translated_text:
            return translated_text

        # Passo 3: Síntese de fala em português
        new_audio_path = synthesize_speech(translated_text)
        if "Erro" in new_audio_path:
            return new_audio_path

        # Passo 4: Substituição do áudio no vídeo
        output_video_path = replace_audio(video_path, new_audio_path)
        if "Erro" in output_video_path:
            return output_video_path

        # Passo 5: Mover o vídeo para um local público (link acessível)
        public_video_path = move_video_to_public(output_video_path)
        if "Erro" in public_video_path:
            return public_video_path

        # Retorna o link público para o vídeo
        return f"Vídeo processado com sucesso! Você pode visualizar o vídeo no seguinte link: [Clique aqui para ver o vídeo](/{os.path.basename(public_video_path)})"
    except Exception as e:
        return f"Erro inesperado: {str(e)}"

# Interface Gradio
iface = gr.Interface(
    fn=process_video,
    inputs=gr.File(label="Carregar Vídeo (MP4)"),
    outputs=gr.HTML(label="Link para o Vídeo"),
    title="Tradutor de Vídeos para Português",
    description="Faz a transcrição, tradução e substituição de áudio em vídeos automaticamente."
)

iface.launch(share=True)