Communitygithub.com

tobilafinhangit/skill-master

無料の製品デモ動画をスクリプトで作成します。Playwrightでブラウザを操作し、ffmpegでMP4に変換。有料ツールや手動録画、人間は不要です。「デモ動画」「機能デモ」「アプリを録画」などのトリガーで動作。Vite/React/Supabaseスタックに最適ですが、エンジン自体はフレームワーク非依存です。

skill-master とは?

このスキルは、実際のWebアプリをスクリプトで操作し、無音の製品デモ動画(MP4)を生成するためのものです。Playwrightがブラウザを駆動して機能フローを実行し、ffmpegが動画ファイルをレンダリングします。有料のSaaSツールや手動の画面録画、人間の操作が一切不要で、UIが変更された際に再レンダリングすることで、多数の機能デモを継続的に作成する持続可能な方法を提供します。このスキルは主にVite、React、Supabaseを使用したアプリケーション(VettedAIおよびCongratsスタック)向けに設計されていますが、エンジン自体はフレームワークに依存しないため、他の技術スタックでも使用できます。デモ動画の作成に加えて、UXスモークテストとしても機能し、一度スクリプトを作成すれば、UIの変更に応じて動画を簡単に再生成できます。

対応~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/tobilafinhangit/skill-master/tree/HEAD/.agent/skills/recording-demo-videos

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

デモ動画の録画(無料、スクリプトベース)

実際のアプリの無音製品デモ動画を、ブラウザをスクリプトで操作してMP4にレンダリングします。 無料でローカル実行:Playwright がアプリを駆動し、ffmpeg が動画を作成します。有料SaaS不要、ナレーション不要、 人間のクリック操作不要。同じスクリプトはUXスモークテストとしても機能し、UIが変更されたときに再レンダリングします。 これこそが、多数の機能デモを持続的に作成する方法です。

使用タイミング

  • ユーザーが1つまたは複数の機能デモ/ウォークスルー動画を必要としており、有料ツールにお金を払いたくない場合。
  • 「新しい機能ができるたびに誰かが画面録画しなければならない」という繰り返しの問題。
  • 機能が実際のUIでエンドツーエンドで動作することを迅速に視覚的に確認したい場合。

以下の場合には不向き:ナレーション付きのアニメーション豊富なマーケティング動画(実際の編集ツールを使用)、またはカメラ前で反応する人間が必要なもの。

基本構造

ログインセッションを取得 → Playwrightでアプリを操作(.webmを録画) → ffmpeg → .mp4

ターゲットリポジトリの demo/ の下に3つのファイルが配置されます(resources/ からコピー):

  • record.mjs — エンジン。CONFIGブロック(リポジトリ固有)+ FLOWSマップ(動画ごとに1エントリ)。
  • polish.sh — .webm → .mp4、ログインリードインのトリミング、オプションのキャプション焼き付け。
  • run.sh — 1つのコマンド:開発サーバーをステージングに向け、録画、ポリッシュ、後片付け。
  • README.md — リポジトリごとの使用方法。

新しい動画を作成するには:FLOWSエントリをコピーし、url + steps を変更するだけです。これがループ全体です。

セットアップチェックリスト(リポジトリごとに1回実行)

  1. ツールのインストール(1回):npm install -D @playwright/test && npx playwright install chromium。ffmpeg が必要(Homebrew)。キャプション焼き付けには libfreetype でビルドされたffmpegが必要です。それ以外の場合はキャプションは自動スキップされ、他のすべては機能します。
  2. リポジトリの詳細を確認し、record.mjs のCONFIGブロックを埋めます:
    • 開発コマンド — アプリをローカルで実行する方法(npm run dev、多くの場合 congrats/ のようなサブディレクトリ内)。
    • Supabaseクライアントモジュールパス — 通常は src/integrations/supabase/client.ts。レコーダーはこれをページ内でインポートしてログインします(後述の注意点1を参照)。
    • 録画に使用するDB — ステージングを使用し、本番は絶対に使用しないこと(実際のユーザーの個人情報は含まれない)。そのURL、anon/publishableキー、サービスキー、直接DB URLを確認します。この組織では、それらはauditionリポジトリの .env.local にあります(VettedAIステージング用の VETTED_SUPABASE_*、Congratsステージング用の STAGING_CONGRATS_SUPABASE_*)。
    • ログインメールアドレス — デモデータを所有する合成/テストアカウント。セッションを作成する前に常にユーザーにどのアカウントを使用するか尋ねてください(プロジェクトルール:許可なしに実際のユーザーテストを行わないこと)。
    • ルート — 記録するフローのディープリンクパス。
  3. ローカル開発サーバーをステージングに向ける(後述の注意点2を参照)。
  4. フローを作成し、bash demo/run.sh <flow> を実行して、フレームを抽出して検証します(後述の注意点8を参照)。

注意点(苦心して得た知見 — デバッグ前に読んでください)

1. アプリ自身のクライアント経由でログインし、localStorageを偽装しないこと

Supabase-jsはブラウザ内の非デフォルトキー/エンベロープにセッションを書き込みます。localStorage['sb-<ref>-auth-token'] = JSON.stringify(session) を手動で注入しても正しく見えますが、クライアントがそれを読み取らず、アプリは /login にリダイレクトされます。代わりに、サーバーサイドでセッションを作成し(管理者 generateLink → verifyOtp で access_token + refresh_token を取得、パスワード不要)、次にページ内でアプリのSupabaseクライアントを import し、supabase.auth.setSession({access_token, refresh_token}) を呼び出します。これにより正しいストレージが書き込まれ、セッションはナビゲーション後も持続します。これが最も重要なステップです。

2. --mode staging が黙って無視される可能性がある → .env.development.local を使用する

vite-react-ssg dev(および一部のセットアップ)は、環境ファイルの読み込みで --mode を無視するため、.env.staging が読み込まれず、アプリは本番環境を指したままになります(本番Supabaseホストへのリクエストが表示されます)。Viteは開発時に .env.development.local を .env/.env.local よりも高い優先度で常に自動読み込みします。そのため run.sh は録画のためにステージング設定を .env.development.local にコピーし、終了時に削除します(そうしないと、以降のすべての npm run dev が黙ってステージングを指したままになり、これは重大な問題です)。プレーンな vite リポジトリは --mode を尊重する場合があります。アプリが呼び出すSupabaseホストを監視してテストしてください。

3. ステージングのスキーマがフロントエンドに追いついていない可能性がある → 対象を絞った追加的な整合

ステージングブランチに、フロントエンドが選択する最近のカラムがない場合があります → データクエリが400エラー(column X does not exist)になり、画面が空でレンダリングされます。マイグレーションを再実行しないでください。画面が読み取る少数のテーブルのカラムを比較し(ステージング vs 本番、information_schema.columns 経由)、不足しているものだけを追加的でNULL許容の ALTER TABLE ... ADD COLUMN IF NOT EXISTS として適用します。ユーザーの許可を得てください — これはステージングDBの変更です。

4. シードデータのスケールが合わない可能性がある

合成シードのスコア/値が、UIフォーマッターが期待するものと一致しない場合があります(例:スコアが0–100で保存されているのにUIが value/5*100 を実行 → 「1392%」と表示される)。フォーマッターの期待範囲を本番の実際の値と照合し、必要に応じてシードデータのスケールを変更します(事前に確認してください — これはデータの変更です)。

5. Playwrightの動画にマウスカーソルが表示されない

addInitScript を使用して偽のカーソルオーバーレイを注入します(mousemoveに追従し、mousedownで拡大するドット)。テンプレートはすでにこれを行っています。クリック前にマウスを実際の座標に移動して、追跡されるようにします。

6. ffmpegに drawtext がない場合がある

libfreetypeなしでビルドされたものは、キャプション焼き付けでエラーになります。polish.sh は drawtext を検出し、ない場合はキャプションをスキップします — キャプションの失敗がMP4出力を妨げないようにしてください。

7. ログイン/起動リードインを自動トリミングする

録画にはログインとアプリ起動(無駄な秒数)が含まれます。record.mjs がリードインを測定し .trim サイドカーファイルを書き込みます。polish.sh がそれをカットします(ffmpeg -ss)。

8. フレームで検証し、「録画された」という事実だけで検証しないこと

ffmpeg -ss <t> -i out.mp4 -frames:v 1 frame.png を数箇所のタイムスタンプで実行し、実際に目視確認してください。最初の実行では /login、スケルトン、または間違ったタブにランディングすることがよくあります — フレームでそれを発見します。

9. データと認証の安全性

ステージングで合成データ(例:seed_…@test.vetted.com)を使用して録画し、実際の顧客のプロジェクト(個人情報)は決して使用しないでください。常にユーザーにどのアカウントでログインするか確認してください。認証セッションの作成は実際のアクションです — 最初に確認してください。

フローの作成

record.mjs では、FLOWS は { label, url, steps(page, ui) } のマップです。ui ヘルパーがほとんどのニーズをカバーします:

  • ui.settle(what, [words]) — コンテンツを待機(networkidle + 画面が読み込まれたことを証明する単語)
  • ui.scrollThrough(fraction, steps) — スムーズにスクロールダウンして戻る
  • ui.clickFirstCandidate() / ui.clickFirst(selectors) に一般化 — ベストエフォートなクリック、決してハードフェイルしない
  • ui.beat(ms) — 動画が読みやすくなるように意図的に一時停止

フローはセレクターを軽く、ベストエフォートに保ちます(クリックをtry/catchで囲む)。これにより、セレクターが見つからなくても「それでも十分なスクロールデモ」に劣化し、クラッシュしません。ペースは generously に(800–1800msのビート)。優れた無音デモは15~35秒です。

出力と受け渡し

MP4は demo/output/ に生成されます(gitignore対象)。open demo/output/<flow>.mp4 で再生します(相対マークダウンリンクはIDEでは再生されません — エディタでファイルが開かれます)。パスを共有するか、open でユーザーに渡します。

このスキルの伝播(skill-master内に存在)

このスキルは submodules/skill-master/.agent/skills/recording-demo-videos/ に正規のものがあり、各リポジトリの .agent/skills/ にシンボリックリンクされています。編集後、最初にサブモジュールをコミットしてプッシュし、次に親リポジトリのポインターをプッシュし、/distribute-skill を実行して兄弟リポジトリに反映します(プッシュ前にユーザーに確認してください)。skill-master-submodule-sync ルールを参照してください。

関連スキル