ナレーション付きデモ動画を作成する
シーンファイルを作成します。各シーンは、ナレーションとその再生中に行われるクリック操作で構成されます。スクリプトは、ナレーションを音声に変換し、固定解像度 1600×900 のヘッドレス Chromium でアプリを操作して画面をキャプチャし、音声と字幕を埋め込んだ MP4 を構築します。さらに、可視カーソル、クリックリップル、ハイライトリング、タイトルカードが画面上に追加されます。
以下のすべてのコマンドでは、PY は Windows では python、macOS では python3 を意味し、DV は "${CLAUDE_SKILL_DIR}/scripts/demo_video.py" を意味します。各コマンドはプレーンなステータス行(SCENE …、RECORDED …、CHECK OK、ERROR …)を出力します。それらを読んで判断してください。
1. セットアップ(マシンごとに一度だけ実行)
PY "${CLAUDE_SKILL_DIR}/scripts/setup_env.py"
これにより、~/.claude-demo-video 内に Playwright、Chromium、edge-tts を含むプライベート環境が作成され、ffmpeg のチェックが行われます。READY で終了するか、不足しているものが正確に表示されます。ffmpeg はシステムツールです。インストール前にユーザーに確認を取ってください(Windows では winget install --id Gyan.FFmpeg -e、macOS では brew install ffmpeg)。スクリプトは通常のインストールフォルダ(WinGet、Chocolatey、Scoop、Homebrew)も検索します。ffmpeg が別の場所にある場合は、すべてのコマンドで DEMO_VIDEO_FFMPEG_DIR にそのフォルダを設定してください。
2. 何かを書く前に、ユーザーと動画の内容を合意する
以下の内容を尋ねるか、文脈から確認してください。
- 誰が何のために見るのか(機能を承認するレビュワー、クライアント、新しいスタッフなど)。それによってトーンと説明すべき内容が決まります。
- 何を、どの順序で表示するか。 各シーンを一行で説明したリストを提案し、承認を得てください。3~8分を目安にしてください。
- 音声。 デフォルトは自然な英語のニューラル音声(edge-tts)です。ナレーションテキストは音声を生成するために Microsoft の音声サービスに送信されることをユーザーに伝えてください。 テキストには機能の説明のみを含め、データは絶対に含めないでください。代替手段として、オフラインシステム音声(
--offline)があります。これはマシン外に何も送信されませんが、音声はロボット的になります。 - データ。 デモデータのみを記録します。架空の人物、
@example.comのメールアドレス、明らかに偽のプロジェクトを使用します。実際の顧客や従業員の記録を決して記録せず、カメラを本番環境に向けないでください。
3. アプリの準備
- アプリが実行中であり、このマシンからアクセス可能である必要があります(通常はローカルビルド)。
- 画面にデータが必要な場合は、デモデータ用のシードスクリプト と 対応するクリーンアップスクリプトを作成し、シードを実行してください。デモ行にはタグを付けて(たとえば
DEMO-で始まる ID)、クリーンアップが他のデータに触れないようにしてください。 - 送信メールと通知がオフになっているか、ダミーアドレスにのみ送信されるようにしてください。ウォークスルーでは実際のボタン(送信、承認など)をクリックするためです。
- データを変更するシーン(承認、削除など)は、シードごとに一度しか記録できません。リテイクのたびに再シードしてください。
4. シーンファイルを書く
ユーザーのプロジェクト内に作成してください。例:demo-videos/<name>.py。スキルフォルダ内には絶対に作成しないでください。${CLAUDE_SKILL_DIR}/reference/scenes-template.py をテンプレートとして使用してください。実際の完全な例については、${CLAUDE_SKILL_DIR}/reference/zentrio-timesheet-example.py を参照してください。この例では6分の承認動画が作成されました。
CONFIG = {'url': 'https://localhost:7101/MyTimesheet', 'ready': '#tsCards .tsw-card', 'sign_in': True}
async def week(r):
await r.click('.tsw-row:has-text("Approval screen")')
await r.spot('.tsw-panel', 3)
SCENES = [
('week', "タスク行をクリックすると、その下にログパネルが開きます。", week),
]
CONFIG['url']は最初のページです。readyは、そのページが読み込まれ かつ サインインが完了したときにのみ表示されるセレクターです。これによってレコーダーはサインインが成功したことを認識します。- ナレーション:シーンごとに1~3の短い話し文にしてください。画面上のものだけでなく、なぜそれが重要なのかを説明してください。数字や記号は発音通りに書いてください(例:「に てん さん ぜろ」)。ナレーションにデータは含めないでください。
- アクションはナレーションの再生中に実行されます。アクションはナレーションよりも短くしてください。レコーダーはナレーションが終了してから次のシーンを開始します。
シーンヘルパー(r はレコーダーです。その他は r.page(Playwright のページ)として利用可能です):
| ヘルパー | 動作 |
|---|---|
await r.goto('/path', wait_for=sel) | ページを開く(CONFIG['url'] からの相対パス) |
await r.click(target, dx=.5, dy=.5) | 可視カーソルを移動してクリック。dx/dy で要素内の位置を指定 |
await r.move_to(target) | クリックせずにカーソルを移動 |
await r.type(target, 'text') | フィールドをクリックして、テキストを可視状態で入力 |
await r.select(target, value) | ドロップダウンオプションを選択 |
await r.press('ControlOrMeta+K') | キーボードショートカット(Windows では Ctrl、macOS では Cmd) |
await r.spot(target, seconds, pad) | オレンジ色のハイライトリング |
await r.card(kicker, title, lines, bullets) / await r.uncard() | 全画面タイトルカード(イントロ、サマリー、アウトロ) |
await r.confirm_click(target, show=4) | confirm() を呼び出すボタン用:類似のダイアログを表示し、受け入れ |
await r.download(target) | ダウンロードをクリックし、保存されたファイルのパスを返す |
await r.show_file(path) | ローカルファイルを表示(例:ダウンロードしたレポートのHTMLプレビュー) |
await r.scroll_top()、await r.scroll_x(selector, px) | スムーズスクロール |
await r.clear_toasts(selector) | ボタンを覆う通知トーストを削除 |
await r.wait(seconds) | 一時停止 |
target は CSS または Playwright のセレクター文字列('button:has-text("Approve")')、または Locator(r.page.locator('tr', has_text='Aarav').first)です。
5. ナレーションの生成、録画、レビュー
PY DV voice demo-videos/<name>.py # シーンごとの音声。各シーンの長さを出力
PY DV record demo-videos/<name>.py # アプリを操作してフレームをキャプチャ
PY DV stills demo-videos/<name>.py # シーンごとに2枚のスチル画像を <name>-video/stills/ に出力
サインイン。 'sign_in': True の場合、アプリがサインインしていなければブラウザウィンドウが開き、レコーダーは SIGN_IN_NEEDED と表示します。そのウィンドウでユーザーにサインインするよう伝えてください。絶対に認証情報を入力したりパスワードを尋ねたりしないでください。 セッションは <name>-video/.profile に保存されるため、リテイクのたびに再度サインインする必要はありません。
ビルド前にすべてのスチル画像を確認し、画像を読んでください。
- 正しいページ、パネルが開いている、ナレーション通りの位置にカーソルがある。
- アクションを覆うものがない(トースト、クッキーバナー、プロファイルメニューなど)。
- 画像が引き伸ばされたり、切り取られたりしていない。
- 画面上に実際の個人データが表示されていない。
SCENE_ERROR 行や間違ったスチル画像がある場合は、そのシーン関数を修正して再度録画してください(シーンがデータを変更した場合は最初に再シードしてください)。reference/lessons.md にはこれまでに発生した障害とその修正方法がリストされています。何かおかしいと感じたら参照してください。
6. ビルド、チェック、引き渡し
PY DV build demo-videos/<name>.py [--out "path/Name.mp4"]
PY DV check "path/Name.mp4" --size 1600x900
run は、シーンが正常に動作することが確認できたら、voice、record、stills、build、check を一度に実行します。動画のパスと長さ、および内容をユーザーに伝えてください。ユーザーが依頼しない限り、どこにもアップロードまたは共有しないでください。
7. クリーンアップ
PY DV clean demo-videos/<name>.pyは保存されたサインインを削除します。実際のセッションを保持しているため、終了時に必ず実行してください。--allはフレーム、スチル画像、音声も削除します。- デモデータのクリーンアップスクリプトを実行し、起動したアプリプロセスを停止してください。
プラットフォームに関する注意
- macOS:
python3を使用してください。字幕は Chromium によって描画され、動画の上に重ねられます。そのため、どこでも同じように見え、libass でビルドされた ffmpeg(Homebrew のものは違います)は必要ありません。録画はヘッドレスで行われるため、Retina ディスプレイでも動画サイズは変わりません。 --headedは可視ウィンドウで録画します。アプリがヘッドレスブラウザを拒否する場合にのみ使用し、録画中はユーザーにウィンドウに触れたりサイズを変更したりしないよう依頼してください。DEMO_VIDEO_HOMEはプライベート環境の場所を変更します。DEMO_VIDEO_FFMPEG_DIRは ffmpeg フォルダを指定します。