/demo — 自動デモ動画パイプライン
あなたはWebアプリケーションのナレーション付きデモ動画を作成しています。探索、録画、ナレーション、レンダリングの全フローが、この単一のコマンドで行われます。
引数
$ARGUMENTS から解析:
- 第1位置引数: デモ対象の URL (必須)
--login <credentials>:email:password形式のログイン認証情報。指定された場合、録画前にログインします。--brief <"何を表示するか">: デモでカバーすべき内容の自然言語での説明。「ダッシュボードを表示してプロジェクトを作成」のように非常に短くても構いません。省略した場合は自由に探索します。--name <name>: 出力名 (デフォルト: URLのホスト名から生成)--duration <秒>: 目標動画時間 (デフォルト: 60)--voice <voice>: TTS音声 (デフォルト:en-US-GuyNeural)--preset <draft|production>: 品質プリセット (デフォルト:draft)
引数はURLの後に自然言語として渡すこともできます。以下はすべて同等です:
/demo https://app.com --login [email protected]:pass123 --brief "請求ページを表示して支払い方法を追加"
/demo https://app.com — [email protected] / pass123 としてログイン、請求を表示して支払い方法を追加
/demo https://app.com login: [email protected] pass123。請求ページを表示。
解析できるものは解析してください。ユーザーが平易な英語で認証情報と指示を与えた場合、それらを使用します。
パイプライン
フェーズ 1: アプリを探索
録画前に、何を扱っているのかを理解します:
new_pageまたはnavigate_pageでURLを開く- 認証情報が提供された場合 (
--login)、ログインフォームを見つけて先にサインインします。一般的なパターン (/login,/sign-in, 「サインイン」リンクなど) を探します。メール/パスワードフィールドにfillを使用し、送信ボタンをクリックします。続行する前にダッシュボード/ホームページが読み込まれるのを待ちます。 - スクリーンショットとスナップショットを取得してアプリを理解する
- ブランドを取得: アプリのロゴとアクセント/ブランドカラーを特定します。
- ロゴ画像を出力ディレクトリ (フェーズ2で解決) に
logo.png(または .svg/.webp) としてダウンロードしてみます。探索中は一時的な場所に保存し、一意の名前が解決されたら最終的な出力ディレクトリに移動します。evaluate_scriptを使用してロゴ<img>の src URL を見つけ、Bashのcurlまたはwgetを使用して保存します。パイプラインが自動検出し、イントロカードで使用します。 - アプリのプライマリボタン/ブランドカラーからアクセントカラーを選び、
narration.jsonでaccentColorとして使用します (rgba形式)。
- ロゴ画像を出力ディレクトリ (フェーズ2で解決) に
- 概要が提供された場合 (
--brief)、それを探索のガイドとして使用します。概要はユーザーが何を気にしているかを示します — それらの機能を優先します。概要がない場合は自由に探索します。 - 主要な機能、ナビゲーション、興味深いフローを特定する
- 約
duration秒のナレーションでアプリを紹介する3〜6個のデモセグメントを計画する
魅力的なデモにするためのポイント:
- 概要がある場合はそれに従う — ユーザーは何を見せたいか分かっている
- 最も視覚的に印象的な、またはユニークな機能から始める
- 広さ (異なるセクションをナビゲート) を示し、深さ (1つのフォームに固執しない) を示さない
- 全体をまとめるもの (ダッシュボード、設定、結果) で終わる
- 録画ではログイン画面、ローディングスピナー、エラー状態をスキップする —
screencast_startの前のセットアップで処理する
フェーズ 2: 録画
出力ディレクトリを設定し、録画を開始:
出力ディレクトリ: screencast-output/<name>/
録画: screencast-output/<name>/recording.mp4
- 一意の出力ディレクトリを選びます。 ディレクトリを作成する前に、
screencast-output/<name>/が既に存在するか確認します。存在する場合は、インクリメントするサフィックスを追加します:<name>-v2,<name>-v3など。最初に利用可能な名前を使用します。例:解決された# 確認して次に利用可能な名前を見つける NAME="trafficstores" DIR="screencast-output/$NAME" if [ -d "$DIR" ]; then V=2; while [ -d "screencast-output/${NAME}-v${V}" ]; do V=$((V+1)); done NAME="${NAME}-v${V}" DIR="screencast-output/$NAME" fi mkdir -p "$DIR"<name>(必要に応じてサフィックス付き) を、この実行の後続のすべてのパス — 録画、narration.json、構成、レンダリング出力など — に使用します。 - 出力ディレクトリを作成する
screencast_startをパスscreencast-output/<name>/recording.mp4で呼び出す- アプリを自然に操作 — 計画した機能をクリックしていく
- 各重要な画面で少し (1〜2秒) 一時停止し、視聴者が読めるようにする
- ボタンをクリックし、フォームに現実的なデータを入力し、セクション間を移動する
- MCPフォークがカーソルアニメーションと自動セグメンテーションを自動的に処理する
- 終了したら
screencast_stopを呼び出す
録画のヒント:
- 急がない — パイプラインが退屈な部分を自動的に高速化する
- 視覚的に興味深い画面で一時停止する (パイプラインはこれらをナレーションに合わせてスローダウンする)
- クロスオリジンiframe内でのスクロールは避ける — 代わりに直接ナビゲートする
- 読み込みに時間がかかる場合、自動セグメンターが待機時間をカットする
フェーズ 3: ナレーションを書く
録画した内容に基づいて screencast-output/<name>/narration.json を書きます。自分が行ったことなので、正確に何が起こったか分かっています。
{
"introTagline": "短くインパクトのある見出し",
"introSubtitle": "製品名または会社名",
"outroHeading": "行動を促す質問",
"outroUrl": "website.com",
"outroCtaText": "今すぐ始める",
"accentColor": "rgba(59, 130, 246, 1)",
"captionStyle": "pop",
"voice": "en-US-AndrewNeural",
"introLogoSrc": "screencast-output/<name>/logo.png",
"segments": [
{
"text": "このセグメントのナレーション。人間がプレゼンするように会話調で書いてください。",
"sceneIndex": 0,
"sceneLabel": "機能名"
}
],
"fullText": "すべてのセグメントテキストをスペースで結合したもの。"
}
ナレーションガイドライン:
- 肩越しに誰かにプレゼンしているように書き、ドキュメントを読んでいるようには書かない
- 現在形を使用: 「ここでは...が表示されます」ではなく「ここでは...が表示されています」
- 視聴者が注目すべき特定のUI要素を具体的に挙げる
- ナレーション全体を目標の
--durationに近づける - 各セグメントは5〜20秒のスピーチ (約15〜50語) にする
accentColorはアプリのブランドカラーに合わせる (見たものから選ぶ)- 各セグメントの
sceneLabelは動画内でアニメーションする「Lower Third」になる — 短く (最大2〜3語) 保つ: 「サインアップ」「AIビルダー」「ライブサイト」 introLogoSrcをフェーズ1でダウンロードしたロゴファイルに設定する — イントロカードでスプリングアニメーションとともに表示されるcaptionStyleをアプリの雰囲気に合わせる:"pop"(弾むような遊び心),"clean"(すりガラスのエレガント),"bold"(大きくインパクトのある),"minimal"(控えめ),"karaoke"(背景なし),"outline"(グローシャドウ)- アプリのトーンに合う
voiceを選ぶ:en-US-AndrewNeural— 温かみのある自信 (良いデフォルト)en-US-BrianNeural— 親しみやすいカジュアル (スタートアップ、親しみやすいアプリ)en-US-ChristopherNeural— 信頼できる権威 (エンタープライズ、フィンテック)en-US-AriaNeural— ポジティブで自信 (マーケティング、消費者アプリ)en-US-EmmaNeural— 明るくはっきり (Eコマース、ソーシャル)en-US-AvaNeural— 表現力豊かで思いやり (健康、ウェルネス、コミュニティ)en-US-JennyNeural— フレンドリーで思慮深い (教育、サポート)en-US-EricNeural— 合理的 (アナリティクス、データツール)en-US-GuyNeural— 情熱的 (クリエイティブツール、メディア)en-GB-RyanNeural/en-GB-SoniaNeural— 英国風 (国際的、高級)
フェーズ 3.5: カスタム動画構成の設計
この特定の動画用にカスタムRemotion構成を書きます。screencast-output/<name>/composition.tsx として保存します。パイプラインはデフォルトのMarketingDemoテンプレートの代わりにこれを使用します。
最初にRemotionスキルをロード: demo-render/.agents/skills/remotion-best-practices/rules/ からルールを読んでください — 特に animations.md, timing.md, text-animations.md, transitions.md, sequencing.md。
構成は以下の条件を満たす必要があります:
VideoComposition(Reactコンポーネント) とcalculateMarketingDemoDuration(時間関数) をエクスポートするMarketingDemoProps型をエクスポートする (./MarketingDemoから再エクスポート)- MarketingDemoと同じpropsを受け入れる — パイプラインは同じJSONを渡す
利用可能なビルディングブロック (./components/ からインポート):
DeviceMockup— ブラウザchrome内の画面録画 (videoSrc,accentColor,displayUrl,zoomRegions,layout)IntroCard/OutroCard— デフォルトのイントロ/アウトロテンプレート (tagline,subtitle,accentColor,logoSrc)WordHighlightCaptions— 単語ごとのキャプション (wordTimings,style,accentColor)LowerThird— シーンラベルオーバーレイ (label,accentColor,leftOffset)ProgressBar— 進行状況インジケーター (accentColor)AudioWaveform— オーディオ反応ビジュアライザー (variant,accentColor,samples)FeatureCallout— 注釈コールアウト (label,side,y,accentColor)ChapterCard— シーン区切りカード (chapterNumber,title,accentColor)Presenter— リップシンク付き2Dキャラクター (mouthCues,side)AvatarPip— アバターのピクチャーインピクチャーSceneBreak— シーン境界での短い視覚的フラッシュ
構成ファイル内にカスタムコンポーネントをインラインで書くこともできます。
動画ごとに行う設計上の決定:
- イントロスタイル: カスタムイントロを書くか、IntroCardを使用する。アプリの個性に合わせる — アーシー/オーガニック、テクニカル/クリーン、温かみ/魅力的、大胆/インパクト。
- アウトロスタイル: カスタムアウトロを書くか、OutroCardを使用する。同じ個性のマッチング。
- 含めるオーバーレイ: すべての動画にすべてのオーバーレイが必要とは限らない。クリーンなSaaSデモではAudioWaveformをスキップ。ショート動画ではProgressBarをスキップ。セグメントが明らかな場合はLowerThirdをスキップ。
- オーバーレイの位置: LowerThirdは左上である必要はない。キャプションは中央下部である必要はない。録画内の重要なUI要素と重ならない位置を選ぶ。
- アニメーションのバリエーション: 常に同じスプリングインを使用しない。フェード、スライド、ワイプ、タイプライター、スタガーを混ぜる。Remotionスキルがパターンを示している。
- イントロ → コンテンツ → アウトロのトランジション: フェード、スライド、ワイプ、またはライトリーク。合うものを選ぶ。
composition.tsx のテンプレートリテラル例:
import React from "react";
import { AbsoluteFill, Audio, Sequence, interpolate, staticFile } from "remotion";
import { TransitionSeries, linearTiming } from "@remotion/transitions";
import { fade } from "@remotion/transitions/fade";
// ビルディングブロックをインポート
import { DeviceMockup } from "./components/DeviceMockup";
import { WordHighlightCaptions } from "./components/WordHighlightCaptions";
import { ProgressBar } from "./components/ProgressBar";
// カスタムイントロ/アウトロをインポート (インラインまたは別コンポーネントとして書く)
// 型をインポート
import type { MarketingDemoProps } from "./MarketingDemo";
export type { MarketingDemoProps };
export function calculateMarketingDemoDuration(props: MarketingDemoProps) {
return props.introDurationFrames + props.videoDurationFrames + props.outroDurationFrames - 20;
}
// カスタムイントロコンポーネント (インライン)
const MyIntro: React.FC<{...}> = (...) => { ... };
export const VideoComposition: React.FC<MarketingDemoProps> = (props) => {
// ここに独自の構成レイアウト
};
従うべきRemotionルール:
- すべてのアニメーションは
useCurrentFrame()によって駆動される —useCurrentFrame()を使用せずにフレーム依存の計算を行わない