Shorts Video Studio
Produz um MP4 + SRT + roteiro de 30 a 60 s, 1080x1920. Tudo é procedural (Python + OpenCV + PIL + ffmpeg), orientado por um motor de animação baseado em cues, de modo que os visuais coincidam com a palavra exata falada.
Arquivos nesta skill
scripts/shorts_engine_template.py– mecanismo de referência funcional (9 cenas, 9 fundos, 8 transições, áudio, sincronização de voz). Copie e edite; não reescreva do zero.scripts/tts_elevenlabs.py– gera a narração via REST API (requerELEVENLABS_API_KEY). Use--checke--list-voicesprimeiro.scripts/review_frames.py– contato + evidências de QA: duração, codec, resolução, LUFS integrado, faixa de loudness, pico verdadeiro. Sai com código não-zero em caso de falha.scripts/setup.sh– cria.venv, instala dependências, verifica ffmpeg e fontes. Executesource .venv/bin/activatedepois.assets/fonts/– 15 arquivos de fonte OFL-1.1 / 12 famílias + Noto Color Emoji (ícones reais). Licenças incluídas, indexadas emassets/fonts/LICENSES.md.references/design-bible.md– paletas, fontes, vocabulário de ícones, fundos, transições, efeitos, grade de layout. Leia antes de projetar as cenas.references/script-and-voice.md– fórmula do roteiro, regras de Hinglish, regras de verificação de fatos, voz e detalhes de alinhamento. Leia antes de escrever o roteiro.
Pipeline (siga as etapas em ordem)
- Pesquisa – se o tópico for notícia/tendência, pesquise na web 3+ fontes, colete fatos com datas e números ("em "). Nunca invente números. Marque alegações que não pôde verificar e suavize o texto ("report ke mutabik").
- Roteiro – 120–140 palavras para ~45–50 s, gancho nos primeiros 2,5 s, 7–9 blocos curtos, CTA no final. Consulte
script-and-voice.md. Salve comoscript.txt(um parágrafo por cena). - Plano de cenas – uma cena por parágrafo. Para cada cena decida: estilo de fundo, paleta, 2 fontes, ícones (emoji), animação principal, palavras-cue, transição para a próxima. Aplique as REGRAS DE VARIEDADE abaixo. Escreva o plano em
plan.md. - Voz – gere uma ÚNICA gravação de narração do roteiro inteiro (
tts_elevenlabs.pyou o MCP ElevenLabs). Salve comovoice.mp3. Se não puder baixar o áudio (sandbox), peça ao usuário para enviar o arquivo; enquanto isso, construa com temporização estimada. - Construção – copie o template para
video.py, substitua o texto de SCENES, escreva funçõesbgN/dN, definaHITeTRANS. Use consultas de cueC(scene_idx, "palavrafalada", ocorrência, segundos_padrão)para cada início de animação. - Render de TESTE –
TEST=1 python video.pyescreve PNGs (estado final, estado intermediário e um quadro por transição). Executereview_frames.py/ analise-os. Corrija tudo que o gate de QA sinalizar. - Render final –
VOICE=voice.mp3 python video.py. Execute-o em detached (setsid nohup ... &) e monitore o log; chamadas em foreground podem ser mortas por timeouts da ferramenta. ~1,5–3 min por 50 s em uma CPU. A mixagem é normalizada automaticamente paraLUFS(padrão -16). - Gate de QA (abaixo) no mp4 final, então entregue
video.mp4,captions.srt,script.txt,plan.md,qa_report.md.
REGRAS DE VARIEDADE (isto é o que faz parecer humano, não feito por IA)
Violar qualquer uma delas é FALHA no gate de QA.
- Cada cena tem sua própria técnica de fundo e paleta (raios, grade synthwave, explosão solar halftone, chuva de código, gradiente + blobs, grade de blueprint, listras de perigo, anéis de radar, confetes...). Nunca duas vizinhas iguais. Nunca uma cor global única.
- >= 7 fontes diferentes ao longo do vídeo, misturando categorias: condensada de impacto, display encorpada, display larga, grotesca, serifada, serifada itálica, monoespaçada, pixel, cursiva. Máximo 2–3 fontes dentro de uma cena.
- >= 5 tratamentos de texto diferentes: preenchimento gradiente, contorno grosso + sombra projetada dura, brilho, salto letra por letra, máquina de escrever, chips adesivo/pílula, carimbo rotacionado, inclinação cursiva.
- Ícones reais, não formas geométricas: emoji colorido (Noto Color Emoji) como ícones, animados (aparecer com overshoot, girar, flutuar, orbitar, balançar). Nunca entregue cenas só com texto. Nunca use logotipos de marcas (Adobe, octocat do GitHub etc.); use ícones genéricos.
- 8+ transições diferentes, uma por mudança de cena: glitch, whip-pan blur, zoom-through, íris + anel, slats wipe, flash + shake, pixelizar, push-up. Nunca a mesma duas vezes.
- Momentos de impacto recebem efeitos combinados: explosão de faíscas + anel de onda de choque + tremor de câmera + separação RGB + boom SFX.
- Legendas: 2–3 palavras por vez, grandes e grossas com contorno grosso, palavra atual destacada na cor da cena, pequena escala de pop em cada bloco.
- Movimento em tudo: nada aparece sem animação, nada fica perfeitamente parado (balanço/flutuação lenta / zoom lento 0 → 3,5%).
Layout e zonas seguras (canvas de trabalho 720x1280, ampliado para 1080x1920)
- Topo 0–130 px: mantenha livre (UI da plataforma). Apenas chip de tag em y ~62.
- Zona de conteúdo y 150–830. Zona de legendas centro y = 950 (H-330). Base 250 px: livre (UI da plataforma).
- Orçamento de largura 640 px. Use
TXF(texto, tamanho, fonte, maxw)para qualquer linha que possa transbordar. Largura estimada = caracteres x 0,55–0,75 x tamanho, dependendo da fonte (fontes display largas ~0,75). - Contadores: tamanho de fonte fixo, nunca encolher automaticamente durante a contagem (evitar tremor).
Voz + sincronização (resumo; detalhes nas referências)
- Uma única gravação, depois alinhar:
apply_voice_peaksdetecta picos de energia silábica e faz correspondência DP com as sílabas do roteiro (estável dentro de ~0,2 s).ALIGN=pausesé o fallback para vozes lentas com pausas claras. - As cues usam a primeira palavra cujo texto em minúsculas e sem pontuação começa com o token (dígitos: correspondência exata). Use
ocorrênciapara palavras repetidas. - Início da cena = primeira palavra da cena - 0,45 s. Duração total segue a voz (+1,2 s de cauda).
- A música é sintetizada (pad + kick + hats + baixo + arp) e sofre ducking de ~55% sob a voz; a voz recebe high-pass + compressão + loudnorm (-15 LUFS). Whoosh em cada transição, boom em impactos, ticks de digitação, ding em contadores, pop no CTA.
Gate de QA (um agente juiz/QA deve passar TODOS antes da entrega)
python scripts/review_frames.py out/video.mp4 out/contact.png 12deve imprimir PASS (sai não-zero caso contrário). Loudness e pico vêm dele, não devolumedetect.- Duração 30–60 s, 1080x1920, h264+aac, loudness integrada aproximadamente -18 a -13 LUFS, pico verdadeiro < -1 dBTP (sem clipping).
- Folha de contato com >= 9 quadros + cada quadro de transição visualizada: nenhum texto cortado/transbordando, nenhum elemento sobreposto, nada nos 130 px do topo ou 250 px da base exceto tag/legendas, legendas legíveis em todos os fundos.
- Regras de variedade satisfeitas (liste as fontes, paletas, fundos e transições realmente usados em
plan.md). - Fatos: todo número/data/nome no roteiro rastreável até uma fonte anotada em
plan.md; alegações suavizadas quando não verificadas; nenhum termo "copy"/"stole" a menos que com fonte; alpha/limitações declaradas quando relevante. - Sincronização spot-check: escolha 5 cues (palavra de gancho, um número, um nome, uma transição, CTA) e confirme que o visual começa dentro de 0,25 s da palavra falada (compare tempos de SRT/
SWcom timestamps dos quadros). Se qualquer verificação falhar: corrija, re-renderize, reexecute o gate. Relate problemas conhecidos remanescentes honestamente.
Armadilhas já encontradas (evite)
pip installno Python do sistema falha em Debian/Ubuntu moderno (externally-managed-environment, PEP 668). Usescripts/setup.sh(cria.venv) esource .venv/bin/activate; não use--break-system-packages.- Comparar
mean_volumedoffmpeg volumedetect(dBFS não ponderado) com um alvo LUFS é sem sentido e fez com que versões anteriores falhassem seu próprio gate. Sempre meça comebur128(review_frames.pyjá faz isso). Image.fromarrayem uma imagem PIL ou em um recorte não contíguo ->TypeError: expected string or buffer. Mantenha sprites como arrays numpy contíguos;rcard()retorna uma imagem PIL, não um array.- Fatias de array vazias em
cv2.add-> erro de asserção; protejab > aantes de fatiar bandas. - Processos em background iniciados sem
setsid nohupmorrem quando a chamada da ferramenta retorna. - Geração de áudio em sandbox (MCP) não pode ser baixada pelo sandbox: peça ao usuário para enviar o mp3/wav.
- Sincronização baseada em pausa falha em vozes de IA rápidas (apenas 4 pausas encontradas a -35 dB); o alinhamento baseado em picos é o padrão por esse motivo.
- Janelas de cue sobrepostas: se dois elementos compartilham uma palavra falada, desloque o segundo em 0,2–0,4 s.
- Emoji com seletores de variação (ex.: escudo, aviso) renderizam bem com
embedded_color=True; redimensione comINTER_AREApara reduzir /INTER_CUBICpara ampliar. - Uma fonte ausente cai silenciosamente para DejaVu/Liberation com uma linha
[warn]– verifique o log de renderização em busca de[warn]antes de culpar o layout.