Marketing Studio Agent
Skill por ara.so — Coleção Marketing Skills.
Marketing Studio é um mecanismo de renderização de vídeo orientado a agente para Claude Code. Execute /marketing a partir do seu repositório de produto para gerar um conjunto completo de ativos de lançamento: revelação de logotipo 3D, demonstração de produto com captura de tela, vídeo de lançamento hero com narração/música, clipes sociais por plataforma e ativos OG. Toda a renderização acontece em um repositório central de engine usando Remotion, Blender, Playwright e ElevenLabs.
Instalação
# Clone o repositório da engine
git clone https://github.com/ucsandman/marketing-studio.git
cd marketing-studio
# Instale as dependências
cd studio && npm install && cd ..
# Configure (opcional: caminho do Blender, chave da API ElevenLabs)
cp .env.example .env
# Instale os skills no Claude Code
node scripts/install-skills.mjs
# Verifique a toolchain
python launch.py --check
O script de instalação copia os skills para ~/.claude/skills e os vincula ao caminho do repositório clonado.
Fluxo de Trabalho Principal
O Comando /marketing
A partir do seu repositório de produto:
claude
> /marketing
Isso executa o pipeline completo:
- Onboarding de marca – Deriva tokens de marca do seu sistema de design (ou solicita-os)
- Revelação de logotipo – Animação 3D no Blender composta no Remotion
- Demonstração do produto – Playwright captura sua aplicação em execução com zooms de câmera
- Vídeo de lançamento – Vídeo hero de 30 a 90s combinando demonstração, logotipo e texto
- Trilha de áudio – Narração ElevenLabs e música sincronizadas ao vídeo
- Clipes sociais – Cortes específicos por plataforma (X, LinkedIn, TikTok)
- Ativos OG – Imagem estática, loop animado, GIF para README
Skills Individuais
Execute qualquer tipo de ativo de forma independente:
> /logo-reveal
> /product-demo
> /launch-video
> /audio-track
> /social-clip
> /og-assets
Configuração de Marca
As marcas são definidas em brands/<id>.json:
{
"id": "myproduct",
"name": "MyProduct",
"tagline": "Ship faster, break less",
"colors": {
"primary": "#3b82f6",
"secondary": "#8b5cf6",
"accent": "#f59e0b",
"background": "#000000",
"foreground": "#ffffff",
"muted": "#6b7280",
"success": "#10b981",
"warning": "#f59e0b",
"error": "#ef4444",
"text": "#f9fafb",
"textMuted": "#9ca3af",
"border": "#374151",
"surface": "#111827"
},
"fonts": {
"heading": "Inter",
"body": "Inter",
"mono": "JetBrains Mono"
},
"voice": {
"tone": "confident, technical, no fluff",
"avoid": ["AI slop", "game-changer", "revolutionary"]
}
}
Registre a marca em studio/src/lib/brand.ts:
import { z } from 'zod';
export const BrandSchema = z.object({
id: z.string(),
name: z.string(),
tagline: z.string(),
colors: z.object({
primary: z.string(),
secondary: z.string(),
accent: z.string(),
// ... todas as 13 cores
}),
fonts: z.object({
heading: z.string(),
body: z.string(),
mono: z.string(),
}),
voice: z.object({
tone: z.string(),
avoid: z.array(z.string()),
}),
});
export type Brand = z.infer<typeof BrandSchema>;
export function getBrand(brandId: string): Brand {
const brandData = require(`../../brands/${brandId}.json`);
return BrandSchema.parse(brandData);
}
Adicione um componente de marca do logotipo em studio/src/brands/<id>Mark.tsx:
import React from 'react';
export const MyProductMark: React.FC<{
size?: number;
color?: string;
}> = ({ size = 100, color = '#3b82f6' }) => {
return (
<svg width={size} height={size} viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" fill={color} />
</svg>
);
};
Renderização Manual
Comandos Remotion
Renderize qualquer composição diretamente:
cd studio
# Revelação de logotipo
npx remotion render LogoReveal ../out/myproduct/logo.mp4 \
--props='{"brandId":"myproduct","cta":"Watch the launch"}'
# Demonstração do produto
npx remotion render ProductDemo ../out/myproduct/demo.mp4 \
--props='{"brandId":"myproduct","captureVideo":"../assets/captures/demo.mp4"}'
# Vídeo de lançamento
npx remotion render LaunchVideo ../out/myproduct/launch.mp4 \
--props='{"brandId":"myproduct","demoVideo":"../out/myproduct/demo.mp4","script":["Hook","Problem","Solution"]}'
# Clipe social
npx remotion render SocialClip ../out/myproduct/social-x.mp4 \
--props='{"brandId":"myproduct","platform":"x","feature":"Real-time sync"}'
# OG animado
npx remotion render AnimatedOG ../out/myproduct/og.mp4 \
--props='{"brandId":"myproduct"}'
Scripts de Alimentação (Feeders)
Capturar Demonstração do Produto
cd feeders/capture
node capture.mjs \
--url http://localhost:3000 \
--output ../../assets/captures/demo.mp4 \
--brand myproduct \
--script zoom-dashboard,click-feature,pan-results
Renderizar Logotipo Blender
cd feeders/blender
python render_logo.py \
--brand myproduct \
--output ../../assets/blender/logo-frames/ \
--style draw-on
Gerar Áudio
cd feeders/audio
node generate.mjs \
--script "Ship your product in days, not months" \
--voice-id "ELEVENLABS_VOICE_ID" \
--output ../../assets/audio/voiceover.mp3
node generate.mjs \
--type music \
--mood energetic \
--duration 60 \
--output ../../assets/audio/music.mp3
Defina ELEVENLABS_API_KEY no .env.
Construtores de Props (Props Builders)
Gere props de renderização por meio de scripts construtores:
# Construir props de vídeo de lançamento
node scripts/build-launch-props.mjs \
--brand myproduct \
--demo-video ./assets/captures/demo.mp4 \
--script "Linha de gancho" "Declaração do problema" "Demonstração da solução" \
--output ./props/launch-myproduct.json
# Construir props de clipe social
node scripts/build-social-props.mjs \
--brand myproduct \
--platform x \
--feature "Colaboração em tempo real" \
--output ./props/social-x-myproduct.json
Os arquivos de props são JSON:
{
"brandId": "myproduct",
"demoVideo": "./assets/captures/demo.mp4",
"logoRevealVideo": "./out/myproduct/logo.mp4",
"script": [
{"type": "hook", "text": "Ship in days, not months", "duration": 3},
{"type": "problem", "text": "Marketing assets take weeks", "duration": 4},
{"type": "solution", "text": "One command, full suite", "duration": 5}
],
"voiceover": "./assets/audio/voiceover.mp3",
"music": "./assets/audio/music.mp3"
}
Variáveis de Ambiente
# .env
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
ELEVENLABS_API_KEY=your_api_key_here
COMFYUI_URL=http://localhost:8188
Todas são opcionais; os feeders degradam graciosamente sem elas.
Verificação e Testes
# Verificação completa da toolchain
python launch.py --check
# Renderizar o frame 0 de cada composição (teste de fumaça)
node scripts/smoke.mjs
# Validação do esquema de marca
cd studio && npm test
# Iniciar Remotion Studio para pré-visualização interativa
python launch.py
Padrões Principais
Retomar em Caso de Falha
O pipeline escreve um manifesto de execução em .marketing-run.json:
{
"brand": "myproduct",
"timestamp": "2026-07-10T12:00:00Z",
"completed": ["logo-reveal", "product-demo"],
"current": "launch-video",
"props": {
"logoRevealVideo": "./out/myproduct/logo.mp4",
"demoVideo": "./out/myproduct/demo.mp4"
}
}
Reexecutar /marketing retoma a partir da última etapa incompleta.
Matemática de Zoom de Câmera
As capturas de demonstração do produto usam easing medido para zooms profissionais:
// studio/src/lib/camera.ts
export function calculateZoom(
frame: number,
duration: number,
startScale: number = 1,
endScale: number = 1.2
): number {
const progress = frame / duration;
const eased = 1 - Math.pow(1 - progress, 3); // cubic ease-out
return startScale + (endScale - startScale) * eased;
}
Regras de Loop Contínuo
Os loops OG animados devem começar e terminar em frames idênticos:
// studio/src/compositions/AnimatedOG.tsx
export const AnimatedOG: React.FC<{brandId: string}> = ({brandId}) => {
const frame = useCurrentFrame();
const {durationInFrames} = useVideoConfig();
const brand = getBrand(brandId);
// Normalizar para [0, 1) para loop contínuo
const progress = (frame % durationInFrames) / durationInFrames;
const rotation = progress * 360;
return (
<AbsoluteFill style={{backgroundColor: brand.colors.background}}>
<div style={{transform: `rotate(${rotation}deg)`}}>
{/* marca do logotipo */}
</div>
</AbsoluteFill>
);
};
Clipes Sociais Específicos por Plataforma
Proporções de tela e zonas seguras por plataforma:
// studio/src/compositions/SocialClip.tsx
const PLATFORM_SPECS = {
x: { width: 1280, height: 720, safeZone: 0.1 },
linkedin: { width: 1280, height: 720, safeZone: 0.1 },
tiktok: { width: 1080, height: 1920, safeZone: 0.15 },
instagram: { width: 1080, height: 1920, safeZone: 0.12 },
};
export const SocialClip: React.FC<{
brandId: string;
platform: keyof typeof PLATFORM_SPECS;
feature: string;
}> = ({brandId, platform, feature}) => {
const spec = PLATFORM_SPECS[platform];
const safeWidth = spec.width * (1 - 2 * spec.safeZone);
return (
<AbsoluteFill style={{width: spec.width, height: spec.height}}>
{/* conteúdo */}
</AbsoluteFill>
);
};
Solução de Problemas
Blender Não Encontrado
Error: Blender executable not found at /Applications/Blender.app
Defina BLENDER_PATH no .env ou pule as revelações de logotipo 3D (o pipeline usa fallback para 2D).
Limite de Taxa ElevenLabs
Error: 429 Too Many Requests
A geração de áudio é opcional. O pipeline renderiza vídeo sem narração se a API falhar.
Timeout na Captura Playwright
Error: Page did not load within 30s
Certifique-se de que seu servidor de desenvolvimento esteja rodando na porta correta. O script de captura aguarda o estado networkidle.
Erro de Memória Remotion
Error: JavaScript heap out of memory
Defina o limite de memória do Node:
export NODE_OPTIONS="--max-old-space-size=8192"
npx remotion render ...
Validação de Esquema de Marca Falhou
Error: Invalid brand JSON
Execute cd studio && npm test para ver as violações do esquema. Todas as 13 cores, 3 fontes e regras de voz são obrigatórias.
Estrutura de Arquivos
marketing-studio/
├── brands/ # tokens de marca por produto (JSON)
├── studio/ # projeto Remotion (todas as composições)
│ ├── src/
│ │ ├── compositions/
│ │ │ ├── LogoReveal.tsx
│ │ │ ├── ProductDemo.tsx
│ │ │ ├── LaunchVideo.tsx
│ │ │ ├── SocialClip.tsx
│ │ │ └── AnimatedOG.tsx
│ │ ├── brands/ # componentes de marca do logotipo
│ │ └── lib/
│ │ ├── brand.ts
│ │ └── camera.ts
├── feeders/
│ ├── blender/ # cenas Blender headless
│ ├── capture/ # gravador Playwright
│ ├── audio/ # cliente ElevenLabs
│ └── comfy/ # cliente ComfyUI (opcional)
├── skills/ # skills Claude Code
│ ├── marketing.md
│ ├── logo-reveal.md
│ ├── product-demo.md
│ └── ...
├── scripts/
│ ├── install-skills.mjs
│ ├── build-launch-props.mjs
│ ├── build-social-props.mjs
│ └── smoke.mjs
├── props/ # props de renderização geradas (JSON)
├── assets/ # capturas, áudio, frames Blender
├── out/ # vídeos renderizados finais
└── examples/ # saídas reais de produtos lançados
Melhores Práticas
- Execute teste de fumaça após alterações na marca:
node scripts/smoke.mjsdetecta erros de esquema antes de renderizações completas - Use construtores de props: Nunca edite props JSON manualmente; use
scripts/build-*-props.mjs - Filme a demonstração por último no trabalho de UI: Execute
/polishe/frontend-verifyantes de/product-demo - Pontue o áudio após o bloqueio de imagem: Não gere narração até que o roteiro do vídeo de lançamento esteja final
- Teste localmente antes de
/marketing: Execute skills individuais (/logo-reveal,/product-demo) para depurar tokens de marca - Mantenha o manifesto de execução: Não exclua
.marketing-run.jsondurante execuções ativas (permite retomada)
Skills Relacionados
/polish– Passada final de qualidade na UI antes da filmagem da demonstração/frontend-verify– Verificação de rota headless (erros de console, requisições com falha)/de-vibe– Remover impressões digitais de IA antes do envio/launch– Gerar rascunhos de anúncio por canal
Todos os skills de suporte instalam com scripts/install-skills.mjs.