Todos os projetos projetos/05 · pipeline

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.

Ano
2026
Papel
Do pipeline ao empacotamento
Stack
Python · Whisper · OpenRouter · Edge-TTS / ElevenLabs · MoviePy · FFmpeg
Link
código no GitHub ↗
vinte e seis segundos da saída real do pipeline. Dê play com som: a prova aqui é a voz

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.

dublador.py ver inteiro ↗
# 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.