ethan-podcast-post

Processa gravações de podcast ou narração feitas pelo usuário (arquivos de áudio local): reduz ruído, corta silêncios nas bordas, equaliza e comprime vocais, normaliza a loudness para aproximadamente -16 LUFS e exporta em MP3; opcionalmente adiciona trilhas sonoras de abertura, encerramento e segmentadas (com tabela de cues e pré-verificação); fornece sugestões de edição para pausas longas e trechos regravados e aplica os cortes conforme tabela confirmada pelo usuário.

O que é ethan-podcast-post?

Esta skill transforma gravações brutas de podcast ou narração em arquivos prontos para publicação, realizando todo o processamento localmente no computador do usuário, sem envio de áudio para servidores externos. O pipeline inclui redução de ruído, remoção de silêncios nas bordas, equalização e compressão vocal, normalização de loudness para aproximadamente -16 LUFS e exportação em MP3. Além do processamento básico, a skill oferece suporte opcional para adicionar música de abertura, encerramento e segmentada (com tabela de cues e verificação de lint), bem como geração de sugestões de edição para cortar pausas longas ou trechos de regravação identificados por uma palavra-chave definida pelo usuário. Os cortes são aplicados somente após confirmação do usuário, garantindo controle total sobre o resultado final. A skill depende de ffmpeg e Python 3.9+ instalados localmente, sendo suportada apenas em macOS e Linux. Também inclui um modo de entrevista para conversas com duas ou mais pessoas, que equaliza automaticamente o volume entre os participantes.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ethanyang9512/ai-creator-studio/tree/main/skills/ethan-podcast-post

Installed? Explore more Programação e Desenvolvimento skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Edição e Masterização de Podcast

Processa gravações de podcast ou narração do usuário para criar um arquivo final pronto para publicação: redução de ruído, remoção de silêncios nas bordas, equalização e compressão vocal, normalização de loudness para aproximadamente -16 LUFS e exportação em MP3. Quando necessário, adiciona música de abertura, encerramento e segmentada, além de fornecer sugestões de edição (quais pausas longas podem ser encurtadas e onde estão os trechos regravados), que o usuário confirma antes de aplicar os cortes.

Os diretórios scripts/ e references/ estão dentro do diretório desta skill. Ao executar, use o caminho completo, por exemplo: bash <caminho_desta_skill>/scripts/edit_podcast.sh.

1. Antes de começar, esclareça com o usuário

  • É necessário ter o ffmpeg instalado localmente (ferramenta de áudio gratuita e de código aberto). Se não estiver instalado, peça ao usuário para instalar: no macOS com brew install ffmpeg, no Linux com o gerenciador de pacotes (ex.: apt install ffmpeg). O script procura nesta ordem: variável de ambiente FFMPEG → ffmpeg no PATH do sistema → locais comuns de instalação como /opt/homebrew/bin e /usr/local/bin. Testado com as versões 6.0 e 8.1.
  • Requer bash e Python 3.9 ou superior, usando apenas a biblioteca padrão (sem necessidade de instalar pacotes Python adicionais).
  • Suporta apenas macOS e Linux: testado no macOS; no Linux deve funcionar; no Windows é necessário WSL (não testado).
  • Na primeira redução de ruído, será baixado um modelo público de redução de ruído (RNNoise) de aproximadamente 300 KB da internet, armazenado em ~/.cache/ethan-podcast-post/, com verificação SHA-256 após o download. Se não for possível baixar ou a verificação falhar, o script usará automaticamente o afftdn nativo do ffmpeg. O script informará qual método está sendo usado; você deve comunicar isso ao usuário. A origem do modelo está em references/third-party.md.
  • Todo o processamento é feito localmente: a gravação não é enviada para nenhum servidor e não há cobrança.
  • O que esta skill não faz: não gera ou clona vozes, não dubla, não faz transcrição (se precisar de legendas, o usuário deve fornecer um arquivo SRT), não publica em nenhuma plataforma, não fornece música (a música de fundo deve ser fornecida pelo usuário, que deve confirmar que tem os direitos de uso).

2. Segurança dos arquivos (obrigatório)

  1. Gravação original somente leitura: o script apenas lê o arquivo, não o modifica, move ou exclui.
  2. Saída sempre em um novo diretório: crie um novo diretório ao lado da gravação (ex.: Episodio3_pos-producao/) e não o coloque no mesmo diretório da gravação ou da música de fundo. O script para se o diretório de saída for o mesmo do arquivo de entrada.
  3. Não sobrescrever sem permissão: se o diretório de saída já contiver o arquivo final, audio_raw.wav ou voice_master.wav, o script para e não sobrescreve. Para sobrescrever, informe ao usuário quais arquivos serão substituídos e que os antigos não poderão ser recuperados. Com a concordância do usuário, execute novamente com OVERWRITE=1. O mesmo vale para sugestões de edição, cortes e processamento de voz: se o arquivo de saída já existir, o script para; o usuário deve concordar antes de usar --overwrite.
  4. Confirmar antes de excluir: qualquer exclusão (incluindo limpeza de arquivos grandes como audio_raw.wav) deve ser comunicada ao usuário (qual arquivo, por que) e só realizada após sua autorização. Os arquivos intermediários do script ficam em um subdiretório temporário dentro do diretório de saída, e apenas este subdiretório é limpo ao final.
  5. O que cortar é decidido pelo usuário: as sugestões de edição são apenas uma lista de candidatos; nenhum corte é aplicado sem a confirmação do usuário.

3. Fluxo de processamento

Execute uma verificação do ambiente e informe o resultado ao usuário:

bash <caminho_desta_skill>/scripts/edit_podcast.sh --check

Isso listará o ffmpeg encontrado, sua versão, se a equalização dinâmica de 250 Hz está habilitada (veja seção 6) e se o modelo de redução de ruído está pronto. Se o ffmpeg não for encontrado, uma mensagem indicará como instalá-lo; instale antes de prosseguir.

Passo 1: Primeira passagem – produzir master vocal e versão de prova

KEEP_MASTER=1 bash <caminho_desta_skill>/scripts/edit_podcast.sh <arquivo_de_audio> <diretorio_saida>/pass1 <nome>
  • O áudio pode ser wav, m4a, mp3, mp4 ou qualquer formato que o ffmpeg leia. Para conversas com duas ou mais pessoas, adicione INTERVIEW_MODE=1 (compressão mais forte e equalização automática do volume entre os participantes).
  • Ordem do processamento: extrair para WAV 48 kHz → verificação de qualidade → remoção de silêncios nas bordas (pausas internas não são tocadas) → remoção de cliques labiais e dentais → filtro passa-alta de 80 Hz → redução de ruído → equalização dinâmica de 250 Hz → de-esser → compressão → realce de 5 kHz → ganho linear para -16 LUFS → limitador → exportação MP3 → nova medição de loudness.
  • Saídas:
    • <nome>_final.mp3: arquivo final sem música (também serve como versão de prova);
    • voice_master.wav: master vocal (já com silêncios das bordas removidos) – usado para transcrição, sugestões de edição e cortes;
    • audio_raw.wav: cópia da gravação original convertida para WAV (escrita no diretório de saída somente após todo o processamento bem-sucedido) – útil para refazer o processo; arquivo grande.
  • Verifique os seguintes itens na saída e informe ao usuário:
    • Volume da cauda abaixo de -80 dB: a gravação pode ter sido interrompida no meio; confirme com o usuário;
    • Método de redução de ruído: RNNoise ou afftdn;
    • A loudness do arquivo final deve estar dentro de -16 LUFS ±1, e o pico verdadeiro não deve exceder -1,5 dBTP. Se os valores estiverem fora, o script emitirá um aviso; informe o usuário.
  • Se a gravação estiver muito baixa ou for silenciosa, o script emitirá um erro e parará, sem gerar um arquivo final vazio. A mensagem de erro incluirá um valor sugerido para INPUT_GAIN com base no pico da gravação: primeiro confirme com o usuário que há fala na gravação e, em seguida, execute novamente com INPUT_GAIN=<valor_sugerido> (em dB, já considerando o `INPUT_GAIN atual) para elevar o volume geral. O diretório de saída não conterá arquivos após o erro, portanto o mesmo diretório pode ser reutilizado. Aproveite para sugerir ao usuário que aumente o volume de entrada nas gravações futuras.

Passo 2: Sugestões de edição (apenas lista de candidatos – nenhum áudio é modificado)

A transcrição deve ser feita a partir do voice_master.wav do passo 1 (ou do MP3 final do passo 1 sem música, pois ambos têm a mesma linha do tempo). Não use a transcrição da gravação original: os silêncios das bordas não foram removidos no original, portanto os tempos não coincidirão e as marcações ficarão incorretas.

Encontrar pausas longas que podem ser encurtadas:

python3 <caminho_desta_skill>/scripts/edit_cuts.py suggest <diretorio_saida>/pass1/voice_master.wav \
    [--srt legenda.srt] [--protect 15:00.0-15:03.0 ...]
  • Por padrão, pausas com mais de 1,5 segundos são listadas como candidatas, com sugestão de encurtar para 1,2 segundos (mantendo metade do silêncio de cada lado para preservar o ruído ambiente).
  • Pausas intencionais do usuário (ex.: silêncio após uma frase importante) podem ser protegidas com --protect inicio-fim, deixando 0,5 segundos de margem em cada lado; elas não serão sugeridas para corte.
  • Se pausas longas óbvias não forem encontradas, o ruído de fundo pode estar alto: ajuste --noise de -45 para -40 e execute novamente.
  • Se houver mais de 15 candidatos ou um total acumulado de mais de 60 segundos a cada 40 minutos de áudio, o script sugerirá que os parâmetros estão muito agressivos: aumente --min-pause e não corte todos os candidatos.

Encontrar trechos de regravação marcados por uma palavra-chave (requer legenda):

python3 <caminho_desta_skill>/scripts/edit_cuts.py retakes <diretorio_saida>/pass1/voice_master.wav --srt legenda.srt [--phrase sua_palavra_chave]
  • Convenção durante a gravação: quando algo é dito errado → pausa de 1 segundo ou mais → a palavra-chave de regravação é dita calmamente → pausa de 1 segundo ou mais → a frase é dita novamente do início.
  • A palavra-chave padrão é "de novo". Para usar sua própria palavra-chave, use --phrase. Se o software de transcrição frequentemente escrever a palavra-chave com homófonos, use --phrase várias vezes com as diferentes grafias. Escolha uma palavra-chave que não apareça no corpo do texto; repeti-la duas vezes torna a detecção mais precisa.
  • O script procura a palavra-chave na legenda, encontra o início da nova tentativa e tenta identificar a frase errada anterior, fornecendo o intervalo do corte e um nível de confiança (high / mid / low). Candidatos com confiança "low" devem ser ouvidos pelo usuário para confirmação.

Os dois comandos geram, respectivamente, voice_master_suggested_cuts.tsv e voice_master_retake_cuts.tsv (não sobrescrevem se já existirem; use --overwrite com a autorização do usuário). Apresente cada candidato ao usuário (tempo, contexto, quantos segundos podem ser economizados). Após o usuário confirmar quais cortes deseja, copie as linhas correspondentes para um novo arquivo cuts.tsv (separado por tabulações: início, fim, observação; tempo no formato MM:SS.s).

Passo 3: Aplicar cortes

python3 <caminho_desta_skill>/scripts/edit_cuts.py apply <diretorio_saida>/pass1/voice_master.wav --cuts cuts.tsv [--srt legenda.srt]
  • Os cortes são aplicados com precisão de amostra, com crossfade de potência igual de 15 milissegundos nas emendas. Gera voice_master_edited.wav em 24 bits e o mapa de edição voice_master_edited.edit_map.json (registra a origem e posição de cada segmento mantido).
  • Se --srt for fornecido, as legendas completas serão deslocadas para corresponderem ao áudio editado. Se alguma legenda for cortada ao meio, o script se recusará a executar – execute sem --srt e, após o corte, peça ao usuário para gerar uma nova transcrição a partir do master editado.
  • Após o corte, peça ao usuário para ouvir alguns segundos antes e depois de cada emenda: não deve haver cliques, duas inspirações consecutivas ou mudanças bruscas no timbre.

Passo 4 (opcional): Aplicar textura sonora diferenciada em trechos (citações, memórias, etc.)

python3 <caminho_desta_skill>/scripts/voice_fx.py <master_editado.wav> --fx fx.tsv
python3 <caminho_desta_skill>/scripts/voice_fx.py --list     # Ver os cinco presets
  • Presets: quote (leitura de cartas, textos de outras pessoas), archive (jornais antigos, documentos oficiais), telephone (relato por telefone), memory (recordação, sonho), radio (rádio antigo – no máximo uma vez por episódio).
  • fx.tsv: cada linha contém preset, início, fim, fade-in, fade-out, observação (separados por tabulação; use "-" para valores padrão de fade).
  • O processamento não altera a duração nem a loudness; a saída é <nome_original>_fx.wav.

Passo 5 (opcional): Música e tabela de cues

Só deve ser feito se o usuário fornecer música de fundo. Primeiro, crie a tabela de cues; depois, faça a pré-verificação. A tabela de cues deve estar no diretório de saída da segunda passagem e o nome do arquivo deve ser <nome>_cues.tsv.

Tabela de cues: 7 colunas separadas por tabulação; linhas iniciadas com # são ignoradas; use "-" para usar o valor padrão. time no formato MM:SS.s, relativo à linha do tempo do master vocal. Os exemplos abaixo são ilustrativos:

# type	time	src	dur	vol	fade_in	fade_out
stinger	02:00.0	-	3	-	-	-
break	12:00.0	-@20	8	0.5	2	2
bed	18:00.0	-@40	30	0.08	-	-
ending	40:00.0	-@90	-	-	-	-
TipoFunçãodurVolume padrão
stingerUm pequeno trecho musical, sobreposto à falaPadrão 6 s0,12
bed / postMúsica de fundo; quando a fala aparece, o volume é automaticamente reduzidoObrigatório0,12
breakNeste ponto, a fala é interrompida para inserir um trecho de música pura; após o fim da música, a fala retorna. O arquivo final fica dur segundos mais longoObrigatório0,5
endingMúsica de encerramento: volume reduzido durante a fala, sobe após a fala terminar e faz fade-out no finalUse "-"0,22
  • src com "-" significa usar a música de fundo fornecida nesta execução; -@20 significa iniciar a partir do segundo 20 da música de fundo; também é possível usar o caminho completo de outro arquivo de música, com ou sem @segundo (sem @, começa do início).
  • Para stinger, se src for "-" sem @, o trecho será retirado a partir do segundo 60 da música de fundo; para outros tipos, sem @, começa do início.
  • Após criar a tabela, faça a pré-verificação. Corrija qualquer ❌ antes de prosseguir:
python3 <caminho_desta_skill>/scripts/cues_lint.py <nome>_cues.tsv --master <master_editado.wav> --bg <musica_de_fundo>

Isso verificará formato, limites, existência dos arquivos de áudio, sobreposição de janelas, proporção total de música (recomendado não ultrapassar 15%) e fornecerá uma tabela de conversão "master → arquivo final" para facilitar a edição da linha do tempo do programa.

Passo 6: Segunda passagem – gerar o arquivo final

MASTER_WAV=<master_editado.wav> bash <caminho_desta_skill>/scripts/edit_podcast.sh - [musica_de_fundo] <diretorio_saida>/final <nome>
  • O primeiro argumento é "-". Com MASTER_WAV definido, o script pula a extração, redução de ruído e normalização, aplicando diretamente os cues, mixando a música e exportando.
  • Se houver música de fundo e o áudio for mais longo que 80 segundos, a abertura e o encerramento são adicionados automaticamente: a música de abertura toca por 3 segundos antes da fala entrar; após a fala terminar, a música continua por cerca de 7 segundos com fade-out; o volume da música é automaticamente reduzido quando a fala aparece.
  • Se não houver cortes nem música, o arquivo final do passo 1 já é o resultado final; este passo não é necessário.

Passo 7: Verificação final

O script já faz uma medição ao final. Para uma medição independente adicional (use o caminho do ffmpeg exibido em --check):

"<caminho_do_ffmpeg>" -hide_banner -nostats -i <arquivo_final.mp3> -filter_complex ebur128=peak=true -f null - 2>&1 | tail -12
  • Critérios de aceitação: Integrated entre -16 LUFS ±1, True peak não superior a -1,5 dBFS (ou dBTP).
  • Peça ao usuário para ouvir com fones de ouvido: a música não deve abafar a fala; a música não deve retornar abruptamente durante pausas da fala; cada ponto de corte deve soar natural; o final não deve ser cortado abruptamente; as pausas intencionais devem permanecer.
  • Ao entregar, informe ao usuário: local do arquivo final, método de redução de ruído, valores medidos de loudness e pico verdadeiro, e quais cortes foram aplicados. Se os critérios não forem atendidos, informe honestamente, sem dizer que passaram.

4. Princípios de edição

  • Corte apenas acidentes, não respirações: cortes são para erros de fala, leitura do roteiro com distração, trechos regravados descartados. Respirações, "hmm" de pensamento, hesitações entre frases e silêncios intencionais devem ser mantidos. Em caso de dúvida, mantenha.
  • Pausas de até 0,8 segundo não são alteradas; pausas entre frases de 0,8 a 1,5 segundo são mantidas por padrão; pausas mais longas só devem ser encurtadas se houver evidência de hesitação ou distração.
  • Os pontos de corte devem ser escolhidos em locais de pausa natural para respiração, sem cortar o início ou o final de palavras. Respirações devem ser mantidas ou removidas por completo.
  • A música de fundo deve ficar abaixo da fala, evitando músicas com vocais ou com muita energia na faixa média (1-3 kHz). Músicas com melodia são preferencialmente colocadas entre parágrafos (break), não sobrepostas à fala. A duração total da música geralmente não deve ultrapassar 15% do arquivo final.
  • Para detalhes, consulte references/editing-style-guide.md (estilo e apresentação) e references/editing-essentials.md (execução da edição e verificação). Consulte references/audio-glossary.md para termos técnicos.

5. Variáveis de ambiente (todas opcionais)

VariávelPadrãoFunção
FFMPEGBusca automáticaCaminho do ffmpeg
DENOISErnnoisernnoise / afftdn / off
RNNOISE_MODEL~/.cache/ethan-podcast-post/bd.rnnnLocalização do modelo de redução de ruído; se já existir, pode apontar diretamente para ele
RNNOISE_URLModelo público no GitHubURL alternativa para download (a verificação SHA-256 ainda será feita)
INPUT_GAIN0Aumentar (ou diminuir) o volume geral da gravação antes do processamento (dB); use o valor sugerido no erro caso a gravação esteja muito baixa
TRIM_THRESHOLD-50Limiar (dB) para remoção de silêncios nas bordas; se sons suaves no início/fim forem cortados, reduza o valor (ex.: -60)
INTERVIEW_MODE01 = conversa com duas ou mais pessoas
KEEP_MASTER01 = manter o master vocal voice_master.wav
MASTER_WAVvazioCaminho do master vocal para a segunda passagem
MUSIC_VOLUME0,12Proporção de volume da música de fundo
INTRO_DURATION40Janela (em segundos) para música de abertura e encerramento; se o áudio for mais curto que o dobro deste valor, a música não é adicionada
PREROLL / TAIL3 / 7Segundos de música antes da fala / segundos de música após a fala terminar
OUTRO_SEEKvazioA partir de qual segundo da música de fundo começar a música de encerramento
MP3_BITRATE160kTaxa de bits do MP3 final
OVERWRITE01 = permitir sobrescrita de arquivos existentes (após obter consentimento do usuário)

6. Perguntas frequentes

  • ffmpeg não encontrado: peça ao usuário para instalar (macOS: brew install ffmpeg; Linux: gerenciador de pacotes) ou especifique o caminho com FFMPEG=/caminho/completo/ffmpeg.
  • Versão do ffmpeg: o script lê o número da versão. O significado dos parâmetros da equalização dinâmica de 250 Hz mudou entre o ffmpeg 6 e 8; ambas as implementações foram calibradas com um sinal senoidal e produzem o mesmo resultado. Para versões não testadas (ex.: 7.x), esta etapa será ignorada com um aviso, mas o restante do processamento continua normalmente. Os parâmetros de remoção de silêncios das bordas também foram ajustados para o comportamento das versões recentes; 6.x e 8.x cortam de forma idêntica.
  • Erro "após remover silêncios das bordas, quase nada restou" ou "loudness não pôde ser medida": a gravação está muito baixa ou é silenciosa. Confirme se há fala e execute novamente com o valor de INPUT_GAIN sugerido no erro (quando a loudness está abaixo de -70 LUFS, não é possível medir; apenas ajustar o limiar de corte não é suficiente). Se a gravação realmente não tiver som, o erro persistirá e nenhum arquivo vazio será gerado.
  • Redução de ruído usando afftdn: significa que o modelo RNNoise não foi baixado com sucesso. Defina RNNOISE_URL para um espelho alternativo ou use RNNOISE_MODEL para apontar para um arquivo de modelo existente e execute novamente (pergunte ao usuário antes de sobrescrever arquivos existentes).
  • Volume da cauda abaixo de -80 dB: a gravação provavelmente foi interrompida no meio; confirme com o usuário, não trate como um problema de edição.
  • Nenhum trecho de regravação encontrado: verifique se a transcrição foi feita a partir do voice_master.wav e veja como a palavra-chave foi escrita na transcrição; adicione essa grafia com --phrase.
  • Ver cada comando executado: use bash -x <caminho_desta_skill>/scripts/edit_podcast.sh ....
  • Ao escrever parâmetros de filtro do ffmpeg no shell zsh: quando uma variável é seguida imediatamente por dois pontos, escreva ${VAR}:...; caso contrário, o zsh interpretará $VAR:a e $VAR:r como modificadores, alterando silenciosamente os parâmetros.

Licença: código MIT, documentação CC BY 4.0.

Habilidades Relacionadas