Marketing Studio Agent
技能由 ara.so 提供 — Marketing Skills 集合。
Marketing Studio 是专为 Claude Code 设计的 AI 代理视频渲染引擎。在产品仓库中运行 /marketing 即可生成完整的发布资产套件:3D 标志动画、屏幕录制产品演示、含配音/背景音乐的英雄发布视频、按平台适配的社交片段以及 OG 资源。所有渲染均集中在引擎仓库内,使用 Remotion、Blender、Playwright 和 ElevenLabs 完成。
安装
# 克隆引擎仓库
git clone https://github.com/ucsandman/marketing-studio.git
cd marketing-studio
# 安装依赖
cd studio && npm install && cd ..
# 配置(可选:Blender 路径、ElevenLabs API 密钥)
cp .env.example .env
# 将技能安装到 Claude Code 中
node scripts/install-skills.mjs
# 验证工具链
python launch.py --check
安装脚本会将技能复制到 ~/.claude/skills 并链接到引擎仓库的路径。
核心工作流
/marketing 命令
在产品仓库中运行:
claude
> /marketing
该命令会执行完整管道:
- 品牌 onboarding – 从设计系统中推导品牌标记(或提示输入)
- 标志动画 – Blender 3D 动画,在 Remotion 中合成
- 产品演示 – Playwright 捕获运行中的应用并带有镜头缩放效果
- 发布视频 – 30-90 秒的英雄视频,整合演示、标志、文案
- 音频轨道 – ElevenLabs 配音和配乐,同步视频节奏
- 社交片段 – 针对不同平台裁剪(X、LinkedIn、TikTok)
- OG 资源 – 静态图片、循环动画、README GIF
独立技能
可单独运行任意资产类型:
> /logo-reveal
> /product-demo
> /launch-video
> /audio-track
> /social-clip
> /og-assets
品牌配置
品牌定义在 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"]
}
}
在 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(),
// ... 所有 13 种颜色
}),
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);
}
在 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>
);
};
手动渲染
Remotion 命令
直接渲染任意组合:
cd studio
# 标志动画
npx remotion render LogoReveal ../out/myproduct/logo.mp4 \
--props='{"brandId":"myproduct","cta":"Watch the launch"}'
# 产品演示
npx remotion render ProductDemo ../out/myproduct/demo.mp4 \
--props='{"brandId":"myproduct","captureVideo":"../assets/captures/demo.mp4"}'
# 发布视频
npx remotion render LaunchVideo ../out/myproduct/launch.mp4 \
--props='{"brandId":"myproduct","demoVideo":"../out/myproduct/demo.mp4","script":["Hook","Problem","Solution"]}'
# 社交片段
npx remotion render SocialClip ../out/myproduct/social-x.mp4 \
--props='{"brandId":"myproduct","platform":"x","feature":"Real-time sync"}'
# 动画 OG
npx remotion render AnimatedOG ../out/myproduct/og.mp4 \
--props='{"brandId":"myproduct"}'
数据源脚本
捕获产品演示
cd feeders/capture
node capture.mjs \
--url http://localhost:3000 \
--output ../../assets/captures/demo.mp4 \
--brand myproduct \
--script zoom-dashboard,click-feature,pan-results
渲染 Blender 标志
cd feeders/blender
python render_logo.py \
--brand myproduct \
--output ../../assets/blender/logo-frames/ \
--style draw-on
生成音频
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
在 .env 中设置 ELEVENLABS_API_KEY。
Props 构建器
通过构建脚本生成渲染属性:
# 构建发布视频属性
node scripts/build-launch-props.mjs \
--brand myproduct \
--demo-video ./assets/captures/demo.mp4 \
--script "Hook line" "Problem statement" "Solution demo" \
--output ./props/launch-myproduct.json
# 构建社交片段属性
node scripts/build-social-props.mjs \
--brand myproduct \
--platform x \
--feature "Real-time collaboration" \
--output ./props/social-x-myproduct.json
属性文件为 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"
}
环境变量
# .env
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
ELEVENLABS_API_KEY=your_api_key_here
COMFYUI_URL=http://localhost:8188
所有变量均为可选;如果没有配置,数据源脚本会降级运行。
验证与测试
# 完整工具链健康检查
python launch.py --check
# 烟雾测试:渲染每个组合的第 0 帧
node scripts/smoke.mjs
# 品牌 schema 验证
cd studio && npm test
# 启动 Remotion Studio 进行交互式预览
python launch.py
关键模式
失败恢复
管道会将运行进度写入 .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"
}
}
重新运行 /marketing 会从最后一个未完成的步骤继续。
镜头缩放计算
产品演示捕获使用缓动函数实现专业级缩放:
// 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); // 三次缓出
return startScale + (endScale - startScale) * eased;
}
无缝循环规则
动画 OG 循环必须在完全相同的关键帧上首尾相接:
// studio/src/compositions/AnimatedOG.tsx
export const AnimatedOG: React.FC<{brandId: string}> = ({brandId}) => {
const frame = useCurrentFrame();
const {durationInFrames} = useVideoConfig();
const brand = getBrand(brandId);
// 归一化到 [0, 1) 实现无缝循环
const progress = (frame % durationInFrames) / durationInFrames;
const rotation = progress * 360;
return (
<AbsoluteFill style={{backgroundColor: brand.colors.background}}>
<div style={{transform: `rotate(${rotation}deg)`}}>
{/* 标志图 */}
</div>
</AbsoluteFill>
);
};
按平台定制的社交片段
各平台的宽高比和安全区域:
// 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}}>
{/* 内容 */}
</AbsoluteFill>
);
};
故障排除
未找到 Blender
错误:无法在 /Applications/Blender.app 找到 Blender 可执行文件
在 .env 中设置 BLENDER_PATH,或跳过 3D 标志动画(管道会自动降级为 2D)。
ElevenLabs 频率限制
错误:429 请求过多
音频生成是可选的。如果 API 失败,管道会在没有配音的情况下渲染视频。
Playwright 捕获超时
错误:页面未能在 30 秒内加载
确保开发服务器正在正确的端口上运行。捕获脚本会等待 networkidle 状态。
Remotion 内存错误
错误:JavaScript 堆内存不足
设置 Node 内存限制:
export NODE_OPTIONS="--max-old-space-size=8192"
npx remotion render ...
品牌 Schema 验证失败
错误:无效的品牌 JSON
运行 cd studio && npm test 查看 schema 违规详情。所有 13 种颜色、3 种字体和语音规则都是必填项。
文件结构
marketing-studio/
├── brands/ # 每个产品的品牌标记(JSON)
├── studio/ # Remotion 项目(所有组合)
│ ├── src/
│ │ ├── compositions/
│ │ │ ├── LogoReveal.tsx
│ │ │ ├── ProductDemo.tsx
│ │ │ ├── LaunchVideo.tsx
│ │ │ ├── SocialClip.tsx
│ │ │ └── AnimatedOG.tsx
│ │ ├── brands/ # 标志图组件
│ │ └── lib/
│ │ ├── brand.ts
│ │ └── camera.ts
├── feeders/
│ ├── blender/ # 无头 Blender 场景
│ ├── capture/ # Playwright 录制器
│ ├── audio/ # ElevenLabs 客户端
│ └── comfy/ # ComfyUI 客户端(可选)
├── 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/ # 生成的渲染属性(JSON)
├── assets/ # 捕获、音频、Blender 帧
├── out/ # 最终渲染的视频
└── examples/ # 已发布产品的真实输出
最佳实践
- 品牌变更后运行烟雾测试:
node scripts/smoke.mjs能在完整渲染之前捕获 schema 错误 - 使用 props 构建器:切勿手动编辑 props JSON;使用
scripts/build-*-props.mjs - 在 UI 工作最后录制演示:在
/product-demo之前先运行/polish和/frontend-verify - 在画面锁定后编排音频:在发布视频脚本最终确定之前,不要生成配音
- 在
/marketing之前本地测试:运行独立技能(/logo-reveal、/product-demo)调试品牌标记 - 保留运行清单:在活跃运行期间不要删除
.marketing-run.json(用于支持恢复功能)
相关技能
/polish– 在演示录制前进行最终 UI 质量检查/frontend-verify– 无头路由验证(控制台错误、失败的请求)/de-vibe– 发布前移除 AI 生成痕迹/launch– 按渠道生成公告草稿
所有支持技能均可通过 scripts/install-skills.mjs 安装。