Video Reel Studio — Um supervisor, portas rigorosas
Este skill não desenha nem edita por si só. Ele é um supervisor sobre cinco skills existentes:
| Skill | O supervisor usa para |
|---|---|
video-ad-editor | Todos os scripts (scripts/), reel com fala, legenda, capa |
montage-video | Montagem de clipes sem fala no ritmo |
podcast-video | Duas câmeras → reels ou episódio 16:9 |
motion-video | Filme de motion a partir de texto (mecanismo motion/) |
thumbnail-video | Capa do reel e thumbnail do YouTube |
Raiz dos scripts: .opencode/skills/video-ad-editor/ — passe caminhos completos.
Plataformas: Windows e Mac
O skill foi escrito para funcionar em ambas. A diferença está toda em como chamar as ferramentas, não na lógica:
| Windows | Mac | |
|---|---|---|
| Python | python | python3 |
Scripts .sh | & "C:\Program Files\Git\bin\bash.exe" … (⛔ NÃO bash normal = WSL) | bash … |
| Chrome | C:\Program Files\Google\Chrome\Application\chrome.exe | /Applications/Google Chrome.app/Contents/MacOS/Google Chrome |
| 3D | GL=gpu (ANGLE/D3D11) | Metal automático |
| Caminhos | D:/work/x ou D:\work\x | /Users/you/work/x |
Antes de qualquer trabalho, uma vez por sessão:
python scripts/preflight.py # Mac: python3
Verifica: Python, ffmpeg/ffprobe, node, bash, Chrome, numpy/scipy, skills irmãos, fonte e pasta de identidades —
e imprime o comando de instalação correto para cada sistema (winget no Windows, brew no Mac). Porta G-2.
Os próprios scripts detectam a plataforma sozinhos: _vision.py escolhe ferramentas Apple no Mac e alternativas abertas no Windows,
e _chrome_flags.js escolhe Metal no Mac e SwiftShader em outros, e 31_device3d.js e motion/render.js procuram o Chrome nos caminhos de ambos os sistemas.
O contrato: uma frase → arquivo pronto
O usuário te dá um arquivo ou link e uma frase. Você segura todas as etapas. Não dê comandos a ele, nem pergunte sobre algo que você pode verificar sozinho. Faça apenas uma pergunta quando a decisão for de gosto, não técnica (qual ângulo, qual gancho, qual frase remover).
Comandos egípcios — se ele disser isso, esse é o modo
| Se disser | Modo |
|---|---|
| «منتج الفيديو ده» · «حوّله لريل» · «اقصّ السكتات» · «هات الكابشن» | talking-reel |
| «اعمل مونتاج من المقاطع دي» · «ركّبهم على الأغنية» | montage |
| «اعمل ريلات من الحلقة» · «عندي كاميرتين» · «الحلقة كاملة» | podcast |
| «اعمل فيديو موشن من النص ده» · «اشرح بالحركة» · «موشن جرافيكس» | motion |
| «اشرح الموقع ده بفيديو» · «ديمو للتطبيق» · «اللينك ده» | web-demo |
| «اعمل كوفر» · «ثمبنيل يوتيوب» · «صورة مصغرة» | cover-only |
| «عايز أعدّل بنفسي» · «اعمله كاب كت» · «افتح الاستوديو» | Modo básico + CapCut / estúdio |
Não é necessário que ele mencione o modo. Se a frase contiver verbo + arquivo, você infere o modo desta tabela e continua.
O fluxo rápido
| # | Fase | Saída | Porta |
|---|---|---|---|
| -2 | Verificação do ambiente: preflight.py (Windows/Mac) | Relatório de ferramentas | G-2 |
| -1 | Identidade (opcional): Pergunte primeiro — salva / nova / padrão | theme.json + brand.md | G-1 |
| 0 | Leia o pedido e escreva brief.json | promise + mode + length | G0 |
| 1 | Fonte: copiar, verificar quadros, iluminação | src.mov | G1 |
| 2 | Corte + transcrição + correção + legenda | cut.json a.json caps.json | G2 · G3 · G3b |
| 3 | Design: movimentos, cenas, pré-visualização | scenes*.js + sheet.jpg | G4b |
| 4 | Renderização completa | out/ = duração×30 | G4 |
| 5 | Codificação + master + tradução | ad-master.mp4 .srt | G5 |
| 6 | Capa + thumbnail + prévia para celular | cover.jpg … | G6 · G6b |
| 7 | Relatório de entrega | gates.md | G8 |
Detalhes e comandos precisos ← references/pipeline.md.
Papéis e quando delegar a um agente ← references/roles.md.
Cada condição de porta e seus limites ← references/gates.md.
Direção artística: Antes da primeira cena, escolha um estilo de styles/pack.json (10) — python scripts/style_pack.py apply "<work>" <id> — o estilo define movimento e textura, e a marca define cor ← references/styles-adapted.md.
-1a) O agente e o modelo — antes da identidade
ai.json é escrito antes de qualquer coisa: o agente é conhecido do ambiente (você está rodando dentro dele), então não pergunte sobre ele.
Pergunte apenas uma pergunta se o modelo não estiver claro:
«Em qual modelo você vai trabalhar? Só o nome — para ajustar o tamanho das cenas e a revisão nele.»
| Resposta | Efeito imediato |
|---|---|
| Modelo forte + vision | 6–8 cenas, momentos de profundidade, revisão visual com agente secundário |
| Forte sem vision | 4–6 cenas, revisão apenas numérica + olho do usuário em sheet.jpg |
| Rápido/barato | 3–5 cenas de padrões fixos, uma prévia, cada porta uma vez |
| Contexto pequeno | Divida a transcrição em janelas, não leia o texto todo |
- O agente:
opencode·claude-code·codex·cursor·gemini-cli— epreflight.pycompara a tag do projeto comai.json. - Se as capacidades não forem conhecidas, deixe como
null→ o skill assume cautela (números + olho). - Detalhes e matriz completa ←
references/ai-fit.md.
-1b) Identidade — Onboarding opcional (não o force)
Primeiro pedido de vídeo, antes de qualquer script, faça apenas uma pergunta:
«Antes de começarmos: Preparamos sua identidade uma vez (5 minutos: cores, fonte, tom, proibições), ou seguimos com uma identidade salva, ou continuamos com o padrão e alteramos depois?»
| Resposta dele | O que fazer |
|---|---|
| «Tem identidade salva» | python scripts/onboard.py list ← mencione o nome ← apply <work> <slug> |
| «Prepara» | As sete perguntas ← new ← card ← exiba o cartão ← apply |
| «Continua com o padrão» | Não pergunte de novo no mesmo projeto; o padrão #0B0C0C · #F4F2EE · #19C3AE · Cairo · chunk |
| «Estou ocupado» | Comece o vídeo e ofereça a identidade após a primeira entrega |
- As sete perguntas (nome, handle, público, tom, chamada, cores, proibições) ←
references/onboarding.md. - Ele tem imagens/logo? Extraia a paleta com
scripts/00_theme_refs.pyem vez de adivinhar. - G-1: Contraste ink/bg ≥ 4.5, acc/bg ≥ 3, onAcc/acc ≥ 4.5.
onboard.py newrecusa salvar se falhar. - A identidade é salva em
~/.config/opencode/brands/<slug>.jsone usada em todo projeto futuro.
⛔ Proibido iniciar o onboarding sem perguntar, ou interromper o projeto por causa das cores, ou fazer mais de 7 perguntas.
G0 — O briefing (não pule)
Escreva <work>/brief.json antes de qualquer script. O template: assets/brief.template.json.
promise= o que o espectador entende nos primeiros 3 segundos. Uma frase. Se não conseguir escrever, é porque não entendeu o pedido.modedos seis. Se o pedido couber em dois modos, escolha o mais próximo da intenção do usuário e diga a ele em uma frase o que entendeu.length_s= faixa realista (reel 45–90 s; clipes longos ← vários reels, não um só).must_keep= nomes e números que não podem ser removidos ou alterados.
Porta G0: Os três existem? Se não, uma pergunta e depois continue.
Liderança: Quem decide
Você lidera. Não espere permissão para cada passo, e não entregue o trabalho a um agente que te dirija.
- Verifique você mesmo tudo que é técnico: duração, quadros, áudio, tamanho, zona segura.
- Delegue o julgamento apenas quando ele for melhor com memória limpa: revisão do árabe e revisão das imagens.
- O agente apenas lê e julga — não escreve nem desenha. O template do prompt está em
references/roles.md.
As portas: fail-closed
python scripts/gate_runner.py "<work>" --safe
- Imprime uma tabela, escreve
gates.json+gates.md, e sai com código 1 se houver blocker. - Nenhuma entrega com qualquer blocker aberto. E nada de "vamos tentar e ver".
- Orçamento de duas tentativas por porta. A terceira = o motivo não é compreendido ← pare e pergunte ao usuário com evidência (captura de tela + texto da porta).
- Proibido desabilitar uma porta ou aumentar
--maxmbou ignorar warn "porque é pequeno". Isso é adulteração.
Regras rígidas
- A legenda é cópia fiel da fala dele — não invente, não remova palavra sem motivo, e a correção mantém o número de palavras.
- A zona segura primeiro — nada de texto em y 0–150 nem y 1620–1920, nem na coluna dos botões à direita.
- As cores vêm apenas de
theme.json— zero ajuste de cor na imagem dele sem aprovação. - Todo número na tela vem de
facts.mdou da fala dele — nenhum número inventado por você. - Sem publicação nem agendamento. A entrega são arquivos.
- A capa é obrigatória — primeiro quadro, e legível no tamanho do celular (
cover_phone.jpg). - Tamanho e loudness fazem parte da qualidade: ≤29 MB, −14 LUFS, pico ≤ −1.0 dBTP.
Modos de operação
- Reel com fala (padrão):
talking-reel— o vídeo completo ocupa a tela inteira, e os gráficos ficam na faixa superior ou atrás dele. - Clipes sem fala:
montage— precisa de 10–20 clipes + trilha de áudio. Não reutiliza o take. - Podcast:
podcast— duas câmeras. O gancho escrito é obrigatório. - Filme de motion:
motion— sem narração por padrão (audio.py --no-bed --lufs -20). 3D precisa deGL=gpu. - Site/aplicativo:
web-demo—27_web_capture.jsdepois30_demo.js(ou31_device3d.js). - Apenas capa:
cover-only.
Relatório de entrega
Duas linhas, depois uma tabela curta:
Duração · Cortes · Tamanho · Loudness · Pico
Portas 7/7 ✅ (ou warn aceitável + motivo)
Arquivos: mp4 · srt · txt · cover.jpg
Nada foi publicado.
Economia de tokens
- Um comando por fase, não 41 comandos separados.
- Uma folha de cenas (
sheet.jpg) em vez de 6 imagens. - Não leia arquivo inteiro:
grep -npara a função,tail -5para o log. - Referências apenas quando necessário — este arquivo + uma referência adequada à fase.
- Não exiba imagem a não ser para uma pergunta visual que não tenha outra forma de responder.
Falhas esperadas (não se surpreenda)
| Sintomas | Causa | Solução |
|---|---|---|
UnicodeEncodeError | Escrita sem utf-8 no Windows | Execute PYTHONUTF8=1 (os scripts estão corrigidos, mas não confie) |
| 3D trava | Caminho do Chrome/caminho /work | CHROME correto + GL=gpu (corrigido em 31_device3d) |
| Legenda atrasada/cortada | O corte mudou após a legenda | Refaça 02_captions.py depois G3 |
| Pico alto após compressão | AAC eleva o pico | alimiter no caminho da capa ou 06c_loudfix.sh |
| Transcrição alucina | Árabe coloquial/termo inglês | 02a_whisper_check.py --fix depois corrija com número fixo de palavras |