SaaSデモメーカー は何をしますか?
概要
このスキルは、任意のWebアプリケーションまたはローカルアプリケーションのスクリーンショットをキャプチャし、洗練された無音のSaaSデモ動画(MP4)をレンダリングします。これは実績のあるCastifyパイプライン(~/SaaS/castify/generate_castify_demo.py)をモデルにしており、どのAperoneプロジェクトでも使用できるように一般化されています。
呼び出された場合は、セッション終了までに必ずMP4を生成しなければなりません。「ここに計画があります」で止まらず、実行まで完了してください。
使用タイミング
以下のいずれかに該当する場合は必ず起動する(部分一致・言い換えも含む)。
日本語トリガー
- デモ動画 / デモMP4 / デモ動画を作って / デモ動画を生成して
- プロモ動画 / 紹介動画 / サービス紹介動画
- スクショ撮って動画にして / スクリーンショットを動画にして
- 動画を作って(SaaSやアプリの文脈)
- 既存のスクショから動画を作って
- 画面録画(静止画合成で代替する旨を伝えてから対応)
英語トリガー
- demo video / demo MP4 / product demo
- promotional video / promo video / intro video
- screenshot to video / capture and render
- make a video from screenshots
/saas-demo-maker コマンド直接指定
判断が難しいケース(起動してよい)
- 「動画」「MP4」「スクショ」を含み、アプリ・SaaS・ツールの文脈がある
- ローカルアプリや公開URLへの言及がある
- 「既存の画像から動画にして」という依頼
入力値
ユーザーメッセージからパースする:
| 入力 | デフォルト | 備考 |
|---|---|---|
url | — | 完全なURLまたはhttp://localhost:3000 |
product_name | プロジェクトから推測 | ピルや設定で使用 |
brand_color | #7c3aed | VIOLET定数を上書き |
screens | 5 | キャプチャするスクリーンショットの数 |
output_path | output/saas_demo.mp4 | プロジェクトルートからの相対パス |
mode | full | full / capture / render |
locale | 日本語メッセージの場合はja、それ以外はen | ステップテキストに影響 |
steps | templates.mdのプリセットから | ユーザー指定のテキストが優先 |
assets_dir | output/screenshots | レンダーモードのソース画像 |
モード
fullモード
ライブURLまたはローカルアプリからスクリーンショットをキャプチャし、ビデオをレンダリングします。
トリガー例:
/saas-demo-maker https://castify.aperone.com からサービスカード用デモ動画を作って。5画面、20秒以内、ブランドカラーは#7c3aed、出力はoutput/castify_demo.mp4
/saas-demo-maker http://localhost:3000 のLP、ログイン、ダッシュボード、入力、結果画面を撮って、無音ループ用のSaaSデモMP4を作って
captureモード
スクリーンショットのキャプチャのみ — ビデオレンダリングは行いません。
トリガー例:
/saas-demo-maker スクショだけ撮って。LP、ログイン、ダッシュボード、入力、結果の5枚
renderモード
既存のスクリーンショットからビデオをレンダリング — キャプチャステップはありません。
トリガー例:
/saas-demo-maker assetsの既存スクショ5枚から動画だけ作って。プロダクト名はAperone Academy、ブランドカラーは#7c3aed
/saas-demo-maker assetsの5枚から動画だけ作って。プロダクト名はCastify、出力はoutput/castify_demo.mp4
ワークフロー
ステップ0 — 事前準備
- カレントプロジェクトに
demo_config.jsonが存在する場合は読み込む。 output/screenshots/またはassets/に既存のスクリーンショットがあるか確認する。- ユーザーメッセージからモードを検出する(デフォルト:
full)。 output/ディレクトリが存在することを確認するか、作成する。
ステップ1 — 設定を生成
プロジェクトルートにdemo_config.jsonを書き込む:
- ユーザーメッセージからパースした値を使用する。
product_nameに一致するtemplates.mdプリセットからステップテキストを選択するか、スクリーン数に応じた汎用テンプレート、またはユーザー指定のテキストを使用する。- スクリプト生成の前に、今すぐファイルを書き込む。
ステップ2 — スクリプトを書き込む(fullまたはcaptureモード)
プロジェクトルートにcapture_screenshots.pyを書き込む。
プロジェクトルートにgenerate_saas_demo.pyを書き込む。
プロジェクトルートにREADME_demo_video.mdを書き込む(初回のみ。既存の場合はスキップ)。
renderモードの場合は、capture_screenshots.pyはスキップする。
ステップ3 — 依存関係をインストール(不足している場合)
必要に応じて確認およびインストール(コマンドはreference.mdを参照):
ffmpeg—which ffmpeg || brew install ffmpegpillow—python3 -c "import PIL" || python3 -m pip install pillow- TypeScriptキャプチャの場合:
node_modules/playwrightが存在することを確認する
ステップ4 — キャプチャ(fullまたはcaptureモード)
キャプチャスクリプトを実行する:
python3 capture_screenshots.py
または、プロジェクトに既存のPlaywright TypeScriptキャプチャスクリプト(例:scripts/demo-screenshots.ts)がある場合は、そちらを優先する:
npx tsx scripts/demo-screenshots.ts
キャプチャ後にoutput/screenshots/に少なくとも2つのPNGファイルが含まれていることを確認する。
キャプチャに失敗した場合は、エラーを読み、capture_screenshots.pyを修正して再試行する。
ステップ5 — レンダリング(fullまたはrenderモード)
実行する:
python3 generate_saas_demo.py
エラーに注意する。スクリプトがクラッシュした場合は、トレースバックを読み、スクリプトを修正して再実行する。ユーザーに尋ねず、最大3回まで自己修復を試みる。
ステップ6 — 品質チェック
ffprobeを実行して確認する:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,duration,codec_name,pix_fmt \
-of default output/saas_demo.mp4
reference.mdの品質チェックリストの10項目すべてを確認する。
いずれかの項目が失敗した場合は、修正して再レンダリングする。
ステップ7 — 報告
最終レスポンスを出力する(下記「最終レスポンス形式」を参照)。
スクリーンショットキャプチャ仕様
解像度
1280 × 720(Chromiumビューポート)
ブラウザ
Playwright Chromium、ヘッドレス。
待機戦略
await page.goto(url, wait_until="networkidle")
await page.wait_for_timeout(800) # 追加の安定化時間
候補となるローカルURL(順に試行)
http://localhost:3000
http://localhost:5173
http://localhost:8000
http://localhost:8080
出力ディレクトリ
プロジェクトルートからの相対パスoutput/screenshots/。
標準ファイル名
01-landing.png
02-login.png
03-dashboard.png
04-input.png
05-result.png
06-options.png (6画面以上の場合)
07-processing.png (7画面の場合)
ローカルアプリの起動
package.jsonを読み込んで開発スクリプト(dev、startなど)を見つける。- 開発サーバーをバックグラウンドで起動する。
- 候補のURLが応答するまで待機する(最大30秒)。
- スクリーンショットをキャプチャする。
- 開発サーバーを停止する。
認証処理
.envにテスト認証情報と開発バイパスフラグ(例:DEV_BYPASS_AUTH=true)が含まれている場合は、起動前に環境変数に設定する。- ログイン画面の場合:デモメールアドレス(
demo@<product>.io)を入力し、送信はしない — 入力済みの状態をログイン画面としてキャプチャする。 - 実際の認証バイパスやブルートフォースログインは試みない。
- ページがサインインにリダイレクトし、バイパスが利用できない場合は、ログイン画面をデモ画面の1つとして使用する(信頼性のある見た目になる)。
開発モードのアーティファクト
Clerk開発モードバナー、Next.js開発インジケーター、デバッグオーバーレイ — ブラウザ上で削除しようとしない。代わりに、レンダリングステップでカード下部のグラデーションオーバーレイまたはダークパネルでカバーする。
レンダリング仕様
アーキテクチャ
すべてのフレームをPNGファイルとしてoutput/frames/に生成し、その後ffmpegでエンコードする。
エンコードにmoviepyは使用せず、ffmpegサブプロセスを直接使用する。
画像サイズ調整
card = ImageOps.fit(image.convert("RGBA"), (card_w, card_h),
method=Image.Resampling.LANCZOS)
これが唯一許可される画像サイズ調整方法です。スクリーンショットは各シーン内で完全に静止している必要があります — ズーム、パン、Ken Burns効果は一切禁止です。
Ken Burns — 禁止
スクリーンショットに対して、フレームごとのスケール係数や位置オフセットを適用してはいけません。 シーンのフレーム0からフレーム98まで、スクリーンショットのピクセル内容は変更されてはいけません。アニメーションが許可されるのはオーバーレイ(キャプション、ピル、プログレスバー、グロー)のみです。
キャプションアニメーション(許可)
キャプションパネルは、シーンの最初の20%(scene_t < 0.2)の間、フェードインおよび8ピクセルの上方向への移動が許可されます。これが画像レイヤーで唯一許可されるアニメーションです。
タイミング
SCENE_SECONDS = 3.3 # 固定 — 変更しない
TRANSITION_SECS = 0.4 # 固定 — 変更しない
FPS = 30
SCENE_FRAMES = 99
TRANSITION_FRAMES = 12
トランジション
水平スライド:終了フレームは左に退出し、開始フレームは右から進入します。
ease_in_out_cubicを使用します。切り替え境界に細い継ぎ目を和らげるベールを追加します。
完全なアルゴリズムはreference.mdを参照してください。
ffmpegコマンド
reference.mdの正確なコマンドを使用します。主要フラグ:
-c:v libx264 -pix_fmt yuv420p -movflags +faststart -an -crf 18
ビジュアルデザインルール
背景
#020617 (BG) — カードの背後を塗りつぶす
カードレイアウト
card_box = (34, 22, WIDTH-34, HEIGHT-22)
radius = 30
上部クロームアクセントラインはcard_box[1] + 48。
カードの境界線:1ピクセルCARD_EDGE。
オーバーレイ(すべて必須)
- プログレスバー — セグメント化、カード上部、完了ステップは紫色で塗りつぶし
- キャプションパネル — 左下、ガラス調ダークパネル、STEP N / 名前 / 本文
- 製品ピル — 右下、ブランドカラーのドット + プロダクト名
- フォーカスグロー — 主要なUI要素の周りに紫色のグロー(推測方法はreference.mdを参照)
- ビネット — フルフレームの端に微妙なダークラウンドエッジ
- 下部グラデーション — 必要に応じて、カード下部の開発モードアーティファクトをカバー
禁止デザイン要素
- 無地の黒いボックスに白いテキスト(ガラス効果なし)
- 過度なブルーム / 飽和しすぎたグロー
- 3D変換またはパースペクティブワープ
- スクリーンショットのUIの歪み
- スクリーンショット内の表示テキストの編集または置き換え
設定ルール
スクリプトを実行する前にdemo_config.jsonを書き込む。
renderモードで再実行する場合は、既存の設定を最初に読み込み、上書きではなくユーザーの上書き値をマージする。
スキーマ:
{
"product_name": "string",
"brand_color": "#7c3aed",
"output_path": "output/saas_demo.mp4",
"screenshots": ["output/screenshots/01-landing.png"],
"steps": [{ "step": 1, "name": "...", "body": "...", "focus": null }],
"fps": 30,
"resolution": [1280, 720],
"mode": "full",
"locale": "ja"
}
実装要件
capture_screenshots.pyの責任:
- Playwright Chromiumをヘッドレスで起動
- ビューポートを1280 × 720に設定
- 各ターゲットURLにナビゲートし、networkidle + 800ミリ秒の安定化を待機
- PNGを
output/screenshots/に標準ファイル名で保存 - 各スクリーンショットの前にマウスを画面外に移動(
page.mouse.move(1400, 800)) - スクリーンショットごとに成功/失敗を表示
- 成功時は終了コード0、失敗時は1
generate_saas_demo.pyには、reference.mdにリストされているすべての関数を含める必要があります。
主要な不変条件:
SCENE_SECONDS = 3.3— ハードコード、設定による上書き不可TRANSITION_SECONDS = 0.4— ハードコード、設定による上書き不可fit_cover()はImageOps.fit()を呼び出す — ズーム演算は行わないrender_scene()はフレームごとにスケールを変更しないencode_video()はffmpegサブプロセスを-anフラグで呼び出す
品質チェックリスト
encode_video()が成功した後、完了を報告する前に以下のすべてを確認する:
output/saas_demo.mp4が存在し、サイズが100 KBを超えている- 再生時間が(画面数 × 3.3秒)の±2秒以内である
- 幅=1280、高さ=720(ffprobeで確認)
- 音声ストリームがない
- codec_name = h264
- pix_fmt = yuv420p
- すべてのスクリーンショットが正しい順序で表示されている
- 目立つ開発モードバナーが表示されていない(必要に応じてオーバーレイでカバー)
- 結果/出力画面が製品の価値を明確に伝えている
- キャプションテキストがすべてのシーンで読みやすい
このチェックを実行する:
ffprobe -v error -select_streams v:0 \
-show_entries stream=width,height,duration,codec_name,pix_fmt \
-of default output/saas_demo.mp4
障害回復
| 障害 | 回復方法 |
|---|---|
ffmpegが見つからない | brew install ffmpeg、その後再試行 |
PILが見つからない | python3 -m pip install pillow、その後再試行 |
| node_modulesにPlaywrightがない | npm install playwright、その後再試行 |
| キャプチャスクリプトが失敗する | エラーを読み、スクリプトを修正して再実行 |
| レンダリングスクリプトがクラッシュする | トレースバックを読み、スクリプトを修正して再実行(最大3回) |
| 品質チェックに失敗する | 失敗した項目に応じてスクリプトを修正し、再レンダリング |
| ローカルURLが応答しない | package.jsonを確認し、開発サーバーが正しく起動しているか検証 |
| 動画ファイルが破損している | ffmpegコマンドとフレームファイルを確認し、再レンダリング |
ライセンス
MIT