Communitygithub.com

RolynTrotter/vibe-podcast

Extraia material de origem (palestras do YouTube, talks, episódios próprios anteriores) para obter citações citáveis e transformá-las em clipes com timestamp e sugestões de lower third para o podcast. Use quando for solicitado a transcrever um vídeo de origem, encontrar o que alguém disse sobre X, extrair citações ou clipes para um episódio, ou fazer citações / lower thirds a partir de uma palestra ou talk.

O que é vibe-podcast?

Esta skill automatiza o fluxo de trabalho de curadoria de citações para podcasts, transformando vídeos de origem (YouTube, talks, episódios anteriores) em citações precisas, clipes com timestamp e sugestões de lower third para edição no Final Cut Pro. Ela utiliza `yt-dlp` para download de áudio, `mlx-whisper` (large-v3-turbo) para transcrição local eficiente (aproximadamente 85x tempo real), e um script `citekit.py` que gerencia todo o pipeline. O usuário primeiro baixa os vídeos manualmente com um comando fornecido (devido a bloqueios do YouTube), depois transcreve, corrige possíveis erros de transcrição (como nomes próprios), e então faz a mineração manual de citações — identificando trechos curtos (5-25 segundos), autocontidos e fiéis ao texto original. O sistema gera automaticamente um conjunto de arquivos: uma planilha de revisão (`citations.md`), dados de clipes (`clips.json`) com timings de inserção e padding, sugestões de lower third (`citation_cues.json`) que podem ser importadas via FCPXML, e um script `download_clips.sh` para baixar apenas os trechos necessários em alta qualidade. A skill é ideal para produtores de podcast que precisam fundamentar afirmações com citações exatas de fontes externas, mantendo consistência temporal e permitindo correções localizadas sem perder o histórico de alterações.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RolynTrotter/vibe-podcast/tree/HEAD/.claude/skills/citations

Perguntar na sua IA favorita

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

Documentação

Citações: fontes → transcrições → citações → cues e clipes

Ferramenta: agent-citations/citekit.py (Python stdlib com mlx_whisper e ffmpeg). Ela nunca sobrescreve entradas e se recusa a substituir suas próprias saídas sem --force.

Layout de lote

Uma pasta por assunto em active_edits/<subject>/:

sources/video_sources.txt          lista de URLs do usuário
sources/audio/<id>.m4a .info.json  do yt-dlp (passo 1)
sources/transcripts/<id>.json .md  passo 2
podcast/<ep>.json .md              legendas do nosso próprio episódio, importadas (passo 2b)
sources/quotes.json                passo 3, escrito por você
sources/citations/                 saídas do passo 4

1. Download (o usuário executa)

O YouTube bloqueia o yt-dlp anônimo aqui. Dê ao usuário este comando em vez de executá-lo. Requer cookies do Firefox e os clientes tv/safari, e mantém o áudio pequeno (Whisper só precisa de 16 kHz mono):

cd active_edits/<subject>/sources && for id in ID1 ID2; do yt-dlp --cookies-from-browser firefox --extractor-args "youtube:player_client=tv,web_safari,mweb" -f "wa/w" -x --audio-format m4a --postprocessor-args "ExtractAudio:-ac 1 -ar 16000" --write-info-json --write-auto-subs --sub-langs en --sub-format json3 --no-overwrites -o "audio/%(id)s.%(ext)s" "https://youtu.be/$id"; done

Para o backlog de um canal, liste primeiro, depois selecione: yt-dlp --flat-playlist --print "%(id)s %(duration_string)s %(title)s" https://www.youtube.com/@CHANNEL/videos. Faça triagem dos títulos com Jev (vibe-classification) se a lista for longa.

2. Transcrever

  • citekit.py transcribe sources/audio/<id>.m4a: mlx-whisper large-v3-turbo, timestamps de palavras. O prompt inicial é o título e a descrição do vídeo, que corrige a maioria das grafias de nomes. Roda cerca de 85× o tempo real neste Mac (um trecho de 15 min leva ~35 s; o modelo é baixado uma vez).
  • citekit.py captions sources/audio/<id>.en.json3: legendas automáticas do YouTube. Instantâneas, mas sem pontuação. O cliente tv geralmente não as salva.
  • 2b. Nossos próprios episódios: citekit.py itt EP.itt --id podcastN --media EP.mp4 --out active_edits/<subject>/podcast --fix 'REGEX=>Right'. As legendas do FCP distorcem nomes. Para o episódio 1: --fix '\bver ?m+[iu]l+e?\b=>Vermeule' --fix '\bvermil\b=>Vermeule' --fix '\bAsian Vermeule=>Adrian Vermeule'. O episódio 1 também tem correções em nível de palavra registradas em podcast/podcast1.fixes.json (Schmidt→Schmitt etc.), reaplicadas na reimportação.

Corrija erros de transcrição conforme avança (não pergunte)

Quando notar um erro claro de audição (um nome, uma citação distorcida, uma gagueira que o Whisper dobrou), corrija: citekit.py fix TRANSCRIPT 'palavras antigas=>palavras novas' [...] [--near SEGUNDOS]. Ele edita <id>.json/.md no local (as palavras novas compartilham o tempo do trecho antigo, correspondências podem cruzar segmentos, pontuação final é preservada), mantém a saída bruta não modificada do motor como <id>.raw.json, e registra cada correção em <id>.fixes.json>. transcribe e itt reproduzem esse registro, então as correções sobrevivem a uma nova execução. Não tem certeza? Re-ouça o ponto em vez de adivinhar: ffmpeg -ss T -to T2 -i audio.m4a x.wav && mlx_whisper x.wav --output-format txt. Corrija primeiro, depois cite as palavras corrigidas: locate corresponde à transcrição.

3. Mineração de citações (seu julgamento)

  1. Leia a transcrição do nosso episódio, se houver, e liste as afirmações que os apresentadores fazem sobre o assunto, cada uma com seu tempo no episódio. Esses são os momentos que um clipe pode apoiar ou refutar.
  2. Para cada afirmação, citekit.py search 'regex' sources/transcripts/ para encontrar candidatos, depois leia o .md ao redor do resultado. Leia palestras inteiras também: as melhores falas nem sempre são aquelas que os apresentadores nomearam.
  3. Uma boa citação é curta (5–25 s falados), autocontida, inconfundivelmente a posição do próprio palestrante (não ele resumindo um oponente), e citável em um lower third. Mantenha as palavras exatas da transcrição. Não as limpe, ou o locate não conseguirá encontrá-las.
  4. Escreva sources/quotes.json:
{"project": "Ep1 Citações Vermeule", "fps": 29.97, "episode": "../podcast/podcast1.json",
 "quotes": [{"id": "publius-weak-exec", "source": "Bw9M01S8MFI", "approx": 1234,
   "text": "palavras exatas da transcrição",
   "episode_at": 2575, "episode_context": "apresentadores sobre Hamilton e o ditador romano",
   "why": "sua própria declaração da tese", "tags": ["executive", "Federalist"],
   "citation": {"author": "~Adrian Vermeule", "title": "O Paradoxo de Públio", "date": "5 de junho de 2018",
                "publication": "Chorley Lecture, LSE"}}]}

episode (relativo a quotes.json) é a transcrição do nosso episódio. Com ele, cada episode_at da citação (aproximadamente quando os apresentadores levantam o ponto) se torna um ponto de inserção: o final da frase do apresentador que está sendo dita naquele momento. Cite pensamentos completos. Se a próxima frase completa a imagem ou o argumento, inclua-a (um clipe de 5–25 s é o alvo, não um limite rígido).

citation usa como padrão o título do vídeo, data de upload e canal. Coloque o local e a data reais (da descrição) uma vez por palestra em um "sources": {"<id>": {"citation": {...}}} de nível superior. O próprio citation de uma citação substitui esse valor. Autores recebem o prefixo ~ do programa, e \n quebra um título longo em duas linhas.

Verifique qualquer coisa que ele esteja citando (Hamilton, Kafka, o Digesto) em relação ao texto original. O Whisper ouve palavras erradas plausíveis: na palestra sobre Públio, ele deu "vasos de sacrifício" de Kafka como "quadros".

4. Cues e clipes

citekit.py cues sources/quotes.json ajusta cada citação aos timestamps das palavras (aproximado; avisa se a pontuação de correspondência for < 0,8) e escreve em sources/citations/:

ArquivoPara
citations.mdfolha de revisão em ordem de episódio: tempo de inserção (como gravado e após inserções anteriores), palavras dos apresentadores imediatamente antes do corte, a citação, horários da fonte/clipe, link do YouTube ?t=
clips.jsonedição por agente: entrada/saída da fonte, entrada/saída com padding (padrão 5 s de cada lado, --pad-before/--pad-after, pad_before/pad_after por citação), insert_at, insert_at_after_earlier_inserts, insert_after
citation_cues.jsonagent-motion/titles_fcpxml.py: lower thirds Estilo Citação v2 com temporização para o episódio com clipes inseridos, surgindo conforme ele começa a falar. Citações não posicionadas são colocadas uma após a outra
download_clips.sho usuário executa: vídeo em qualidade total apenas para os intervalos com padding (--download-sections)

Depois citekit.py audio-clips sources/citations/clips.json corta prévias de áudio com padding a partir do áudio local, para verificar de ouvido. Para posicionar os lower thirds no FCP, siga a skill motion-graphics: python3 agent-motion/titles_fcpxml.py sources/citations/citation_cues.json -o citations.fcpxml.

Notas

  • transcribe decodifica para WAV de 16 kHz por conta própria e recusa áudio que decodifica muito mais curto que o vídeo. Um download do yt-dlp retomado com um -f diferente emenda dois codecs em um único .m4a (visto em 2026-10-18: AAC-LC e depois HE-AAC), e o ffmpeg descarta silenciosamente tudo após a troca. Refaça o download com --no-continue. Nunca retome entre mudanças de formato.

  • Verifique um clipe de ouvido, ou de forma barata: mlx_whisper citations/audio_clips/<id>.m4a --output-format txt deve mostrar a citação com alguns segundos de lead-in e tail.

  • Os timestamps do Whisper são precisos em cerca de ±0,3 s no nível da palavra. É por isso que os paddings do clipe existem. As legendas iTT do FCP só temporizam linhas inteiras, então itt espalha as palavras uniformemente ao longo de cada linha.

  • O conector Wispr Flow lê apenas transcrições do Meeting Recorder. Não pode transcrever um arquivo.

Habilidades Relacionadas