Como o fluxo funciona
Você coloca um vídeo em incoming/, executa o launcher, o Python extrai áudio e três frames por minuto, usa a OpenAI para criar seções, consolida o artigo, envia o vídeo ao YouTube e Vimeo e grava um post.mdx. O Antigravity lê esse MDX como especificação e cria a página React do blog.
Custos e o que pode ser gratuito
Valores oficiais consultados em 18 de julho de 2026; impostos, câmbio e promoções podem alterar o total.
GitHub Free
Repositórios públicos e privados e 2.000 minutos mensais de GitHub Actions. Para este projeto, normalmente basta.
Netlify Free
300 créditos/mês. Cada deploy de produção consome 15 créditos, além de banda e compute.
Antigravity
O material oficial consultado informa uso sem custo para indivíduos durante a public preview. Confirme no aplicativo.
Domínio .br
Opcional para começar. O Netlify entrega primeiro um endereço gratuito .netlify.app.
OpenAI API
Novas contas usam créditos pré-pagos. Os modelos do scaffold não têm free tier de API. ChatGPT Plus não inclui API.
YouTube
A API não cobra por upload, mas tem quota. Projetos não auditados podem deixar uploads automáticos privados.
Vimeo Free
Até 1 GB de armazenamento vitalício. Upload por API exige aprovação e “Unlisted” não está disponível no plano gratuito.
Vimeo Starter
Cobrado anualmente; ou US$ 20 no mensal. Permite vídeo não listado e oferece 2 TB de armazenamento.
Python, Git e FFmpeg
Ferramentas gratuitas. Os launchers tentam instalar Python e FFmpeg; Git/Node devem ser preparados para o site.
Calculadora estimada por vídeo
A OpenAI cobra por tokens, não por minuto fixo. A calculadora usa hipóteses editáveis para planejamento. O valor real depende da quantidade de fala, resolução dos frames, tamanho das respostas, repetição, cache e reprocessamentos.
Preparar computador, contas-base e arquivos
Faça isto antes de configurar as APIs.
sudo apt update sudo apt install -y git unzip curl node --version git --version
node --version git --version winget --version
O run_video.bat tenta instalar Python e FFmpeg pelo winget. Feche e reabra o terminal se o PATH não atualizar.
Criar conta e repositório no GitHub
O GitHub guarda o site, scripts, MDX, metadados e imagens finais. Os vídeos e segredos ficam fora do Git.
cd /caminho/do/site git init git branch -M main git remote add origin https://github.com/SEU-USUARIO/SEU-REPOSITORIO.git git add . git status git commit -m "Estrutura inicial do site e pipeline de vídeo" git push -u origin main
Registrar o domínio
Pode ser feito depois que o site já estiver funcionando no endereço gratuito do Netlify.
Criar conta e publicar no Netlify
O repositório de referência já possui configuração de build e prerenderização.
Instalar e preparar o Antigravity
Ele lê o repositório local, executa as skills e cria os posts.
Criar conta, billing e API key da OpenAI
A assinatura do ChatGPT e a API são produtos com cobrança separada.
| Modelo | Uso no pipeline | Preço oficial |
|---|---|---|
| GPT‑4o Transcribe | Transcrição do áudio | US$ 2,50/1M tokens de entrada de áudio; US$ 10/1M tokens de saída |
| GPT‑5.6 Luna | Análise multimodal e artigo | US$ 1/1M tokens de entrada; US$ 6/1M tokens de saída |
Configurar canal e upload automático no YouTube
A autenticação é OAuth 2.0; não existe uma “API key simples” para enviar vídeos à sua conta.
Configurar Vimeo como fallback
O script usa PyVimeo, upload resumível e espera da transcodificação.
Baixar e integrar o pipeline Python
O ZIP deve ser incorporado na raiz do repositório do site.
cd ~/Downloads unzip video_to_mdx_scaffold.zip cd /caminho/do/seu-site git switch -c feat/video-to-blog cp -a ~/Downloads/video_to_mdx_scaffold/. . chmod +x run_video.sh cp .env.example .env mkdir -p .secrets incoming video-posts git status
$zip = "$HOME\Downloads\video_to_mdx_scaffold.zip" $temp = "$HOME\Downloads\video_to_mdx_scaffold" Expand-Archive -Path $zip -DestinationPath $temp -Force Set-Location "C:\caminho\do\seu-site" git switch -c feat/video-to-blog Copy-Item "$temp\video_to_mdx_scaffold\*" . -Recurse -Force Copy-Item ".env.example" ".env" -Force New-Item -ItemType Directory -Force ".secrets","incoming","video-posts" git status
Arquivo .env
# OpenAI OPENAI_API_KEY=COLE_A_CHAVE_AQUI OPENAI_TRANSCRIPTION_MODEL=gpt-4o-transcribe OPENAI_SECTION_MODEL=gpt-5.6-luna OPENAI_ARTICLE_MODEL=gpt-5.6-luna OPENAI_LANGUAGE=pt # YouTube YOUTUBE_CLIENT_SECRETS_FILE=.secrets/youtube-client-secret.json YOUTUBE_TOKEN_FILE=.secrets/youtube-token.json YOUTUBE_PRIVACY_STATUS=unlisted YOUTUBE_CATEGORY_ID=28 # Vimeo — Starter VIMEO_CLIENT_ID= VIMEO_CLIENT_SECRET= VIMEO_ACCESS_TOKEN= VIMEO_PRIVACY_VIEW=unlisted VIMEO_PRIVACY_EMBED=public VIMEO_WAIT_TRANSCODE=true # Em Vimeo Free, troque unlisted por anybody # VIMEO_PRIVACY_VIEW=anybody
Executar o primeiro vídeo
Comece sem uploads, valide o MDX e só depois ative as duas plataformas.
cp "/caminho/do/teste-mvp.mp4" incoming/ ./run_video.sh "teste-mvp.mp4" --skip-youtube --skip-vimeo
./run_video.sh "proximo-video.mp4"
./run_video.sh "video-posts/slug-do-video/source/original.mp4" \ --force-sections \ --force-upload \ --force-mdx
Copy-Item "C:\caminho\teste-mvp.mp4" "incoming\" .\run_video.bat "teste-mvp.mp4" --skip-youtube --skip-vimeo
.\run_video.bat "proximo-video.mp4"
Skills para copiar no Antigravity
O pacote desta página já contém as skills em .agents/skills/. Você também pode copiar ou baixar individualmente.
Skill 1 — Criar ou validar a estrutura do blog
Use uma vez no site novo ou quando a arquitetura estiver incompleta.
--- name: shinier-blog-foundation description: Analisa ou cria a estrutura de blog da Shinier em projetos Vite, React e TypeScript. Use ao iniciar o blog, corrigir sua arquitetura, configurar SEO, rotas, sitemap, prerenderização e publicação no Netlify. --- # Skill: Estrutura de Blog Shinier ## Objetivo Criar ou adequar uma arquitetura de blog profissional no repositório atual, preservando o padrão visual, os componentes existentes e a implantação no Netlify. Esta skill deve ser usada antes da skill `shinier-video-mdx-post` quando o projeto ainda não possui uma estrutura de blog validada. ## Princípio central Primeiro inspecione o repositório. Não substitua a arquitetura existente por um framework novo sem necessidade. Quando o projeto já usar Vite, React, TypeScript, React Router, React Helmet, React Markdown, Tailwind e componentes próprios, preserve esse stack. O arquivo `.mdx` produzido pelo pipeline de vídeo é uma especificação editorial de entrada. Ele não precisa ser renderizado diretamente em produção. Em projetos que já usam páginas React dedicadas, converta o conteúdo para um componente `.tsx` compatível com o padrão do repositório. ## Padrão arquitetural esperado Procure e preserve, quando existirem: - uma página de listagem em `src/pages/Blog.tsx`; - uma rota pública `/blog`; - uma rota pública `/blog/:slug`; - um registro central de metadados em `src/data/blog`, `src/data/blog.ts`, JSON ou estrutura equivalente; - um renderer genérico como `BlogPost.tsx` para artigos simples; - páginas React dedicadas em `src/pages/blog/` para artigos ricos; - componentes reutilizáveis como `BlogPostHeader`, `TwoColumnTextSidebar`, `FullWidthSection`, `ReferencesList` e `BlogPostCTA`; - `react-helmet` ou mecanismo equivalente para SEO; - geração de `sitemap.xml` e `robots.txt`; - prerenderização/SSG das páginas públicas; - configuração de build e redirects no `netlify.toml`. ## Fluxo obrigatório ### 1. Fazer inventário do repositório Antes de editar: 1. Leia `package.json`. 2. Localize o router e todas as rotas do blog. 3. Leia `Blog.tsx`, `BlogPost.tsx` e pelo menos um post dedicado. 4. Localize o registro de posts e seus tipos TypeScript. 5. Leia `vite.config.ts`, `netlify.toml`, scripts de prerender e scripts de sitemap. 6. Localize os componentes visuais do blog e as variáveis de design. 7. Execute `git status` e não altere arquivos não relacionados. ### 2. Criar ou validar o modelo de dados Cada post deve possuir, no mínimo: - `slug`; - `title`; - `metaTitle`; - `metaDescription`; - `excerpt`; - `category`; - `date`; - `dateISO`; - `updatedDate` e `updatedDateISO`, quando houver; - `image`; - `author`; - `readTime`; - `keywords`; - `relatedPosts`; - indicação de renderer genérico ou componente dedicado. Categorias devem reutilizar as existentes. Não invente uma nova categoria sem verificar o filtro da página de listagem. ### 3. Criar a listagem do blog A listagem deve: - manter a identidade visual do projeto; - permitir filtrar pelas categorias existentes; - usar links canônicos `/blog/<slug>` sem barra final; - exibir imagem, categoria, título, excerpt, data e tempo de leitura; - usar `loading="lazy"` depois dos primeiros cards; - incluir `width`, `height`, `alt`, `srcSet` e `sizes` quando disponíveis; - ter SEO próprio com title, description, canonical, Open Graph e Twitter Card. ### 4. Criar o modelo de página de artigo A página deve: - usar o layout público do projeto; - ter cabeçalho editorial com categoria, título, resumo, autor, data e leitura; - usar hierarquia única de H1 e H2/H3 sem saltos; - ter largura de leitura confortável; - ter CTA editorial depois de aproximadamente três seções, sem quebrar o raciocínio; - permitir artigos relacionados e referências; - usar imagens responsivas e texto alternativo descritivo; - funcionar em mobile, tablet e desktop; - evitar layout shift; - preservar acessibilidade de teclado e contraste. ### 5. SEO obrigatório Cada post deve conter: - `<title>`; - meta description; - meta keywords quando o projeto já usa; - canonical; - `og:title`, `og:description`, `og:image`, `og:type=article`, `og:url`; - `article:published_time`, `article:modified_time` e `article:author`; - Twitter Card; - JSON-LD `Article`; - JSON-LD `FAQPage` somente quando houver perguntas e respostas reais; - imagem absoluta no Open Graph e no JSON-LD; - `mainEntityOfPage`; - publisher com nome e logotipo da Shinier. Não crie FAQ fictícia apenas para SEO. ### 6. Player de vídeo resiliente Crie um componente reutilizável `VideoPlayer` que aceite: - `youtubeId`; - `youtubeEmbedUrl`; - `vimeoId`; - `vimeoEmbedUrl`; - `title`. Regras: 1. YouTube é a fonte principal. 2. Use a YouTube IFrame Player API para detectar erros de reprodução/incorporação. 3. Faça fallback para a URL completa de embed do Vimeo. 4. Nunca remonte uma URL Vimeo não listada apenas pelo ID; preserve o hash recebido pela API. 5. Use contêiner responsivo 16:9. 6. Mostre estado de carregamento acessível. 7. Evite trocar de player por um simples evento `iframe.onload`. 8. Registre o motivo do fallback apenas no console, sem exibir detalhes técnicos ao visitante. 9. Caso só exista uma plataforma, use-a sem erro. 10. Não exponha tokens ou segredos no frontend. ### 7. Rotas, sitemap e prerenderização Para cada rota pública: - registre a rota no router; - atualize a lista explícita de rotas do sitemap, quando existir; - preserve prioridade de blog em `0.8`, salvo regra diferente do projeto; - inclua a rota na prerenderização; - use URL sem trailing slash; - confirme que `robots.txt` não bloqueia `/blog`; - confirme que o HTML prerenderizado contém title, description, canonical e conteúdo principal. ### 8. Netlify Preserve o `netlify.toml` existente. Antes de alterá-lo: - confirme o build command real do `package.json`; - confirme o diretório de publicação; - preserve redirects 301 existentes; - preserve a regra que remove trailing slash; - não adicione redirect SPA genérico que destrua páginas prerenderizadas; - valide o build local antes de publicar. ### 9. Validação final Execute, quando existirem: ```bash npm install npm run lint npm run build npm run test ``` Depois: 1. valide `/blog`; 2. abra um post; 3. valide links relacionados; 4. valide o player; 5. inspecione o HTML gerado; 6. confirme sitemap e robots; 7. confirme que nenhuma chave foi versionada; 8. apresente uma lista objetiva dos arquivos criados e modificados. ## Restrições - Não remova posts existentes. - Não altere fatos editoriais sem autorização. - Não introduza Next.js, Astro ou outro framework em um projeto Vite já funcional. - Não instale runtime MDX se o arquivo for usado somente como entrada para gerar TSX. - Não duplique registros de slug. - Não use URLs temporárias de preview como canonical. - Não faça commit nem push sem solicitação explícita.
Use a skill shinier-blog-foundation. Analise todo o repositório antes de editar. Crie ou valide a estrutura completa do blog, preservando Vite, React, TypeScript, os componentes existentes, o padrão visual da Shinier, o sitemap, a prerenderização e o Netlify. Não faça commit nem push. Ao final, execute lint e build e informe todos os arquivos alterados.
Skill 2 — Criar cada post com base no MDX
Use depois que o Python gerar um novo arquivo em video-posts/<slug>/post.mdx.
--- name: shinier-video-mdx-post description: Converte um post.mdx gerado pelo pipeline de vídeo em uma página React completa do Blog Shinier, incluindo player YouTube com fallback Vimeo, SEO, dados estruturados, registro do post, rota, sitemap e prerenderização. --- # Skill: Criar Post Shinier a partir de MDX ## Entrada obrigatória Receba o caminho exato de um arquivo como: ```text video-posts/<slug>/post.mdx ``` O diretório normalmente também contém: ```text video-posts/<slug>/ ├── post.mdx ├── metadata.json └── assets/ ``` Trate o MDX como fonte editorial e contrato de dados. Não suponha que o projeto possua runtime MDX. ## Fluxo obrigatório ### 1. Inspecionar antes de editar 1. Leia integralmente o `post.mdx`. 2. Leia `metadata.json`, quando existir. 3. Liste e inspecione as imagens de `assets/`. 4. Leia a estrutura atual do blog. 5. Leia pelo menos um post React dedicado com layout rico. 6. Leia o registro central dos posts. 7. Localize router, sitemap, prerender e configuração Netlify. 8. Execute `git status`. Se a arquitetura de blog ainda não estiver pronta, use primeiro a skill `shinier-blog-foundation`. ### 2. Validar o MDX Confirme: - slug válido e único; - título; - description/excerpt; - SEO title e description; - palavras-chave; - IDs e URLs de YouTube/Vimeo; - caminhos das imagens; - existência de um único H1; - seções H2/H3; - ausência de fatos contraditórios; - ausência de transcrições brutas ou segredos. Se faltar dado editorial essencial, não invente. Use o conteúdo existente e registre a pendência. ### 3. Escolher o renderer correto Use uma página React dedicada em `src/pages/blog/` quando houver: - vídeo incorporado; - cards; - tabelas; - CTAs; - FAQs; - referências; - imagens distribuídas; - layout editorial rico. Use o renderer genérico apenas se ele suportar integralmente o conteúdo sem perda. Para os posts de vídeo, prefira a página dedicada. ### 4. Criar o componente do post Gere um componente com nome PascalCase derivado do slug. Preserve: - título e subtítulos; - ordem argumentativa; - listas; - citações; - tabelas; - textos alternativos; - conclusão; - referências; - FAQ; - links; - URLs completas de embed. Melhore apenas a diagramação. Não acrescente estatísticas, leis, datas ou referências externas sem pesquisa e citação. O post deve seguir o padrão visual da Shinier e reutilizar componentes existentes, priorizando: - `PublicLayout`; - `Helmet`; - `SSGSignal`; - `BlogPostHeader`; - `TwoColumnTextSidebar`; - `FullWidthSection`; - `ReferencesList`; - `BlogPostCTA`; - componentes de UI já existentes. Não recrie componentes equivalentes sem necessidade. ### 5. Imagens 1. Mova ou copie os assets para a convenção já usada pelo projeto. 2. Não aponte o site publicado para `video-posts/...` se essa pasta não fizer parte do bundle público. 3. Use nomes estáveis e sem espaços. 4. Preserve proporção. 5. Inclua `width`, `height`, `loading`, `decoding`, `srcSet` e `sizes` quando aplicável. 6. A imagem principal deve ter preload ou prioridade alta. 7. Imagens internas devem usar lazy loading. 8. Não use frame irrelevante apenas porque ele existe. ### 6. Player com fallback Insira o componente existente ou crie `VideoPlayer` conforme a skill de fundação. Regras: - YouTube principal; - Vimeo fallback; - URLs completas vindas do front matter/metadata; - YouTube IFrame Player API para detectar indisponibilidade; - Vimeo não listado com hash preservado; - proporção 16:9; - título acessível; - sem autoplay com som; - sem chaves no cliente. Se o YouTube estiver privado por restrição de projeto não auditado, o Vimeo deve continuar funcional. ### 7. SEO e dados estruturados Gere: - title; - description; - keywords; - author; - canonical `https://shinier.com.br/blog/<slug>`; - Open Graph; - Twitter Card; - `Article` JSON-LD; - `FAQPage` JSON-LD quando houver FAQ real; - published/modified dates; - publisher e logo; - imagem absoluta. Calcule o tempo de leitura com base no texto final, arredondando para cima. ### 8. Registrar o post Atualize o registro central sem duplicar slug. Inclua todos os campos exigidos pelo tipo TypeScript atual, como: - slug; - title; - metaTitle; - metaDescription; - excerpt; - category; - date/dateISO; - updatedDate/updatedDateISO; - image; - author; - readTime; - keywords; - relatedPosts; - componente/renderizador dedicado. Escolha de dois a três posts relacionados já existentes por proximidade temática. Não use o próprio post. ### 9. Registrar rota e build - adicione `/blog/<slug>` ao router; - adicione a rota à lista de sitemap do `vite.config.ts`, quando explícita; - adicione à prerenderização; - preserve URL sem barra final; - não altere redirects não relacionados; - confirme que o build gera a página. ### 10. Posicionar CTA Insira um CTA Shinier após aproximadamente a terceira seção, desde que não interrompa uma lista ou raciocínio. O CTA deve apontar para a área mais coerente: - `/accelerator` para estratégia, validação, startups e negócios; - `/academy` para formação; - `/methodology` para desenvolvimento e arquitetura. Não coloque múltiplos CTAs repetitivos. ### 11. Verificação Execute: ```bash npm run lint npm run build ``` Quando houver testes relevantes, execute-os. Valide: - página de listagem; - rota do novo post; - imagens; - player e fallback; - links; - responsividade; - HTML prerenderizado; - canonical; - JSON-LD; - sitemap; - ausência de segredos; - ausência de modificações em posts não relacionados. ## Relatório final obrigatório Ao terminar, informe: 1. caminho do MDX lido; 2. componente criado; 3. assets copiados; 4. registros e rotas alterados; 5. comandos de validação executados; 6. resultado do build; 7. pendências reais; 8. URL final esperada. ## Restrições - Não inventar conteúdo. - Não remover conteúdo relevante. - Não publicar automaticamente sem solicitação. - Não fazer commit ou push sem solicitação. - Não expor `.env`, tokens, OAuth ou API keys. - Não reconstruir URL Vimeo não listada sem o hash. - Não substituir a arquitetura existente por outro framework.
Use a skill shinier-video-mdx-post para criar o post a partir de: video-posts/COLOQUE-O-SLUG-AQUI/post.mdx Leia também metadata.json e assets/. Preserve integralmente o conteúdo factual. Gere uma página React dedicada seguindo o padrão visual e técnico dos posts existentes da Shinier. YouTube deve ser o player principal e Vimeo o fallback, usando as URLs completas do MDX. Atualize o registro central do blog, a rota, o sitemap e a prerenderização. Não faça commit, push nem deploy. Execute lint e build e apresente o relatório final.
Revisar, versionar e publicar
O deploy deve ocorrer somente depois da validação local.
npm install npm run lint npm run build git status git diff --stat git add src video-posts vite.config.ts netlify.toml git status git commit -m "Adiciona post do vídeo: slug-do-post" git push -u origin feat/video-to-blog
Rotina para cada próximo vídeo
Depois da configuração inicial, o processo fica curto.
Fontes oficiais e referências técnicas
Use estas páginas para confirmar alterações de preço, políticas e interfaces.