Seamless AI Dub
Vídeo em inglês entra, vídeo dublado em português sai. Sem edição manual em nenhum ponto do caminho.
O problema
Muito material técnico bom só existe em inglês. Legenda resolve em parte, mas compete com a tela: num vídeo em que você precisa olhar o que a mão da pessoa está fazendo, ler embaixo atrapalha.
Dublar à mão resolve melhor, mas uma hora de vídeo vira um dia de estúdio.
A decisão
Montar o caminho inteiro como pipeline, sem passo manual no meio: o áudio sai do vídeo, o Whisper transcreve em segmentos com marca de tempo, cada segmento é traduzido, a voz é sintetizada, os cortes voltam posicionados pelo timestamp original e o vídeo final é renderizado. A ausência de passo manual é o que dá valor ao projeto: com um humano no meio do caminho, ele seria só um editor de vídeo pior do que os que já existem.
Português é mais longo que inglês
Esse problema só aparece quando você roda o pipeline pela primeira vez. A tradução de uma frase inglesa costuma ficar mais comprida em português, e a voz sintetizada dela não cabe no espaço de tempo do segmento original. Cada segmento vaza alguns décimos pro seguinte, o erro vai se somando, e lá pelo minuto três a dublagem está falando de uma coisa que saiu da tela há muito tempo.
A saída foi acelerar cada corte de voz individualmente, só o quanto ele precisa pra caber, sem deixar o pitch subir a ponto de virar desenho animado. Assim o sincronismo se recupera segmento a segmento, em vez de esticar o vídeo ou cortar pedaço da tradução. O áudio original fica embaixo, bem baixo, o que mantém o ambiente da cena.
# o pydub encurta as ondas sonoras sem achatar a frequência
def acelerar_audio_sem_esquilo(arquivo_mp3, fator):
audio = AudioSegment.from_file(arquivo_mp3)
# speedup funciona perfeitamente mantendo o timbre humano grave
audio_rapido = audio.speedup(playback_speed=fator, chunk_size=150, crossfade=25)
audio_rapido.export(arquivo_mp3, format="mp3")
# ... dentro do laço, para cada segmento que o Whisper devolveu:
# Mede quanto tempo a IA gerou de áudio cru
duracao_ia = len(audio_temporario) / 1000.0 # Em segundos
# Descobre quanto tempo a pessoa original (em inglês) levou para falar
tempo_original_falando = segmento["end"] - inicio
if duracao_ia > tempo_original_falando:
fator_aceleracao = duracao_ia / tempo_original_falando
# O limite garante que a voz não fique ofegante ou robótica
fator_aceleracao = min(fator_aceleracao, 1.45)
acelerar_audio_sem_esquilo(nome_arquivo_voz, fator_aceleracao)
# Posiciona a voz já tratada no tempo exato
clip_voz = AudioFileClip(nome_arquivo_voz).with_start(inicio)
Dois provedores de voz, um fallback
A síntese usa ElevenLabs quando tem chave configurada e cai pro Edge-TTS quando não tem. Os dois provedores existem por razão econômica: um cobra por caractere, o outro é gratuito, e a escolha muda no meio do uso conforme o que você está disposto a gastar. Quem só quer ver o pipeline rodando não precisa botar cartão em lugar nenhum.
Sobre o vídeo aqui de cima
É conteúdo técnico de outra pessoa, e está aqui como demonstração curta do que o pipeline produz, não como material meu. Botei um trecho porque esse é o único projeto do portfólio em que print nenhum prova coisa alguma: a qualidade está inteira na faixa de áudio, então ou você ouve ou não dá pra avaliar.