Marketing Studio Agent
ara.soによるスキル — Marketing Skillsコレクション。
Marketing Studioは、Claude Code用のエージェント駆動型ビデオレンダリングエンジンです。製品リポジトリで/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
これによりパイプライン全体が実行されます:
- ブランドオンボーディング – デザインシステムからブランドトークンを抽出(またはプロンプトで指定)
- ロゴリビール – 3D Blenderアニメーションを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ビルダー
ビルダースクリプトでレンダリングプロパティを生成:
# ローンチビデオのpropsをビルド
node scripts/build-launch-props.mjs \
--brand myproduct \
--demo-video ./assets/captures/demo.mp4 \
--script "フック" "問題提起" "ソリューションのデモ" \
--output ./props/launch-myproduct.json
# ソーシャルクリップのpropsをビルド
node scripts/build-social-props.mjs \
--brand myproduct \
--platform x \
--feature "リアルタイムコラボレーション" \
--output ./props/social-x-myproduct.json
PropsファイルはJSON形式:
{
"brandId": "myproduct",
"demoVideo": "./assets/captures/demo.mp4",
"logoRevealVideo": "./out/myproduct/logo.mp4",
"script": [
{"type": "hook", "text": "数日で出荷、数ヶ月ではない", "duration": 3},
{"type": "problem", "text": "マーケティングアセットに数週間かかる", "duration": 4},
{"type": "solution", "text": "ワンコマンドで完全スイート", "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
# ブランドスキーマの検証
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が見つからない
Error: Blender executable not found at /Applications/Blender.app
.envにBLENDER_PATHを設定するか、3Dロゴリビールをスキップします(パイプラインは2Dにフォールバックします)。
ElevenLabsレート制限
Error: 429 Too Many Requests
オーディオ生成はオプションです。APIが失敗した場合、パイプラインはボイスオーバーなしでビデオをレンダリングします。
Playwrightキャプチャタイムアウト
Error: Page did not load within 30s
開発サーバーが正しいポートで実行されていることを確認してください。キャプチャスクリプトはnetworkidle状態を待機します。
Remotionメモリエラー
Error: JavaScript heap out of memory
Nodeのメモリ制限を設定:
export NODE_OPTIONS="--max-old-space-size=8192"
npx remotion render ...
ブランドスキーマ検証エラー
Error: Invalid brand JSON
cd studio && npm testを実行してスキーマ違反を確認してください。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で完全レンダリング前にスキーマエラーを検出 - 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でインストールされます。