PT EN

Papotech Editor

Automação de edição de podcasts com Python

Ferramenta de linha de comando que automatiza a parte repetitiva da edição dos episódios do Papotech, podcast de um projeto de extensão. Ela recebe as gravações de dois microfones e devolve os áudios sincronizados, com pausas longas encurtadas, transcrição e uma lista de trechos para revisar.

Tipo
Ferramenta de linha de comando
Papel
Desenvolvimento individual
Contexto
Podcast do projeto de extensão Papotech
Stack
Python · FFmpeg · Whisper

Como funciona

Com os arquivos mic1.wav e mic2.wav na pasta de entrada, um único comando (python main.py) executa todo o fluxo:

  1. GravaçõesLê os dois microfones do episódio.
  2. SincronizaçãoEncontra as palmas do início e alinha os arquivos.
  3. ProcessamentoEncurta pausas longas com o mesmo corte nos dois áudios.
  4. TranscriçãoTranscreve com Whisper e marca trechos para revisar.
  5. Arquivos de saídaWAVs editados, mix de referência e relatórios.

Problema e objetivo

O problema

Cada episódio é gravado com dois microfones, em dois arquivos separados. Antes de editar de verdade, era preciso alinhar os arquivos, encontrar e encurtar pausas longas e ouvir tudo procurando erros de fala — tarefas repetitivas que se repetem em todo episódio.

O objetivo

Reduzir esse trabalho manual: automatizar a sincronização, a redução de pausas e a localização de erros de fala, deixando para a edição humana apenas o acabamento final no CapCut.

Minha participação

Desenvolvi a ferramenta sozinho, a partir da minha própria rotina de edição do podcast: levantei as etapas repetitivas, escrevi o pipeline em Python e organizei o código em módulos de sincronização, cortes, transcrição e relatórios, com os parâmetros centralizados em config.py.

Tecnologias

  • Python
  • FFmpeg
  • Pydub
  • NumPy
  • SciPy
  • OpenAI Whisper
  • PyTorch

Funcionalidades

  • Sincronização automática dos dois microfones a partir das palmas.
  • Redução de pausas longas, com os mesmos cortes nos dois arquivos.
  • Mix de referência normalizado para conferir o resultado.
  • Transcrição com Whisper em português, com timestamps por palavra.
  • Marcações de repetições, gaguejos e do aviso “corta” dito durante a gravação.
  • Timestamps no tempo do CapCut, já somando a duração da vinheta de abertura.
  • Relatórios em TXT, SRT e CSV, incluindo a lista de pausas encurtadas.
  • Resumo final com a duração prevista do episódio e aviso se ficar abaixo de 1 hora.

Decisões técnicas

  • Um comando, etapas separadas. main.py só orquestra; cada etapa fica em um módulo (audio/, analysis/, reports/, utils/).
  • Parâmetros em config.py. Limiares, durações e caminhos mudam sem mexer na lógica.
  • Falhar cedo. Se a sincronização não for confiável, o programa para com uma mensagem clara em vez de gerar um episódio errado.
  • A transcrição aponta, não corta. Erros de fala viram marcações para revisão; a decisão de cortar continua humana.

Desafios e soluções

Desafio

Encontrar as palmas com confiança

As palmas são a referência de sincronização, mas o começo da gravação também tem fala, ruído e outros sons fortes.

Solução

Energia RMS + detecção de picos

Só os primeiros 20 s são analisados. O áudio vira energia RMS em janelas de cerca de 10 ms, os picos são encontrados com scipy.signal.find_peaks e o programa escolhe o par mais forte com intervalo entre 350 ms e 1,2 s.

Desafio

Nunca entregar áudio dessincronizado

Um alinhamento errado estraga o episódio inteiro, e é difícil perceber o erro só ouvindo um trecho.

Solução

Validar antes de cortar

Se o intervalo entre as palmas difere mais de 150 ms entre os microfones, o processo para com uma mensagem de erro. Se passa, o deslocamento é calculado pelo centro do par de palmas, as palmas são removidas e os dois arquivos ficam com a mesma duração.

Desafio

Encurtar pausas sem picotar a fala

Remover todo silêncio deixa a conversa artificial, e um limiar fixo não funciona para gravações com volumes diferentes.

Solução

Limiar adaptativo e corte pelo meio

Só pausas acima de 2,5 s são alteradas. O limiar de silêncio sai do volume médio da gravação (dBFS − 18, entre −50 e −32 dBFS). O programa remove só o meio da pausa e mantém de 0,8 s a 1,2 s, conforme a duração original.

Desafio

Manter os microfones alinhados depois dos cortes

Se cada microfone fosse cortado com base no próprio áudio, os arquivos voltariam a ficar fora de sincronia.

Solução

Um único mapa de cortes

O mapa de cortes é calculado uma vez, sobre o mix dos dois microfones, e aplicado igualmente aos dois arquivos.

Desafio

Achar erros de fala em um episódio longo

Ouvir mais de uma hora de áudio procurando repetições e trechos para cortar é lento e cansativo.

Solução

Transcrição normalizada + regras

A transcrição é normalizada (minúsculas, sem acentos e pontuação) e comparada com expressões como “corta”, “vou repetir” e “pera aí”. Palavras e frases curtas repetidas também são marcadas, cada uma com 1,5 s de margem antes e depois.

Resultados verificáveis

  • Código público e organizado em módulos no repositório do projeto.
  • Pipeline completo de oito etapas executado com um único comando.
  • Oito arquivos de saída prontos para o acabamento no CapCut: áudios editados, mix de referência, transcrição, legendas e relatórios.

Aprendizados

  • Processamento de áudio na prática: energia RMS, detecção de picos e limiares em dBFS.
  • Validar a entrada e falhar com uma mensagem clara em vez de gerar um resultado errado.
  • Separar o código em módulos com responsabilidades claras e centralizar parâmetros.
  • Automatizar só o que é repetitivo e deixar as decisões criativas para a edição humana.

O que o programa entrega

saida/
├── 01_MIC1_EDITADO.wav     # microfone 1 com os cortes
├── 02_MIC2_EDITADO.wav     # microfone 2 com os mesmos cortes
├── 03_MIX_REFERENCIA.mp3   # mix para conferência
├── 04_transcricao.txt
├── 05_transcricao.srt
├── 06_marcacoes.txt        # trechos para revisar
├── 07_marcacoes.csv        # início e fim no tempo do CapCut
└── 08_cortes_pausas.csv    # cada pausa encurtada

Arquivos gerados na pasta saida/, com os nomes definidos no código do projeto.