プロダクトビデオ(およびその周辺アセット)、エンドツーエンド
あなたは出荷可能なプロダクトアセットを制作しています — 洗練されたビデオ、正確なサイズの静止画、またはその両方を、vos CLI を使ってライブのウェブページから制作します。すべてはデータです。フロースクリプトを書き、CLI が録画と計画を行い、JSON を調整し、再レンダリングします。ペーシングやズームを修正するために再録画する必要はありません — doc.json を編集して再レンダリングするだけです。 品質基準: references/taste.md — その品質ループに従い、静止画をマルチモーダルで評価します。
セットアップ
npm i -D @vosjs/cli
ワンコマンド、ワンパッケージ: @vosjs/cli は、エンジン動詞、ここで使用するテイクパイプライン(録画/計画/フレーム/スクリーンレコーディングのレンダリング)、および vos.so プラットフォーム動詞を備えたオープンソース (MIT) の vos バイナリです。(バージョン0.9までは、テイクパイプラインは @vosso/vos-plugin として別途提供されていました。それをまだリストしているプロジェクトは削除できます。)要件:
- Chromium: システムの Chrome が自動的に検出されます。それ以外の場合は
npx playwright install chromiumを実行するか、VOS_BROWSER_PATHで Chromium を指定します。終了コード3はブラウザが見つからなかったことを意味します。 - レンダリング時のネットワーク: レンダリングページは esm.sh から three/mediabunny を読み込みます。録画もターゲット URL に到達する必要があります。完全にオフラインのサンドボックスではレンダリングできません — 何も出荷しない代わりにその旨を伝えてください。
慣例: ログ → stderr、結果 → stdout。--json は {"event":"done",…} で終わる NDJSON をストリームします。終了コード: 0 ok / 1 エラー / 2 使用法または厳格な失敗 / 3 ブラウザなし / 4 レコーダーがページの代わりにサインインに遭遇(SESSION がないか期限切れ — スクリプトのバグではありません: references/sessions.md)。vos <verb> --help でその動詞のフラグを表示します(@vosjs/cli 0.41.1 以降)。
ステップ0 — 宛先を選ぶ(それがすべてを決める)
| 宛先 | ビューポート | 出力 | その他 |
|---|---|---|---|
| ランディングページクリップ(ヒーロー/セクション埋め込み) | 2560×1440(フッテージネイティブ2K) | webm → VP9 再エンコード + ポスター | 無音ループ;references/destinations.md を参照 |
| ローンチビデオ(PH、ソーシャル、ストアプロモーション) | 2560×1440 または 1280×720 | mp4(--format mp4、システム Chrome が必要) | doc.audio による音楽背景 |
| ローンチキット静止画(ストアスクリーンショット、タイル、OG) | アセットに合わせたサイズ | 同じテイクから frames --frame <t> --size WxH で PNG | 1テイク → すべてのアセット |
| クイックデモ(課題、PR、チャット) | 1280×720 | webm、デフォルト | スピード優先、洗練度は二の次。ここでのみドラフト可 |
チャンネルごとの寸法とバイト予算: references/destinations.md。
コアループ(すべての宛先に共通)
-
ターゲットページを自分のツールで探索する(HTML を取得 / Playwright)。1つのストーリーを伝える3〜6のモーメントを特定します。安定したセレクタ(
a[href='…']、id、role — 子チェーンではない)を収集します。 コンテンツをセットのように準備する: スクリプトは、製品が誇りを持ってスクリーンショットを撮れる状態になるようにしなければなりません — ラベルが入力され、実際のデータが表示され、機能がストーリーの途中であること。空のキャンバスは高速に録画されますが、何もデモになりません。下流のどんな合成でもそれを救うことはできません。ログインが必要な場合? スクリプトの前にセッションを解決する。 セッションのないレコーダーは壁(サインインページ、またはサイトが見知らぬ人に送る公開ページ)を録画し、唯一の症状はスキップされたセレクタです。
references/sessions.mdのラダーを上から下までたどり、保持する最初のラングで停止します: 壁なし(デモモード、認証オフのローカルサーバー)→ プロジェクトがすでに持っているテスト認証からセッションを MINT する(playwright/.auth、auth.setup.ts、シードスクリプト: 誰かに何かを依頼する前に調べてください)→actions.jsonのsetupでオフカメラでサインインする(パスワードは{ "env": "NAME" }から、決してリテラルではない)→ 人間が一度サインインする(vos session open <url> --name <app>、その後録画時に--session <app>)→ 人間がショットリストvos actions script actions.jsonの出力から拡張機能で録画し、あなたがそれをカットします。すべてのラングはsetup、--storage-state用の状態ファイル、または--session用の名前付きセッションで終わります。プロダクションパスワードを入力したり受け入れたりしないでください。状態ファイルをテイクディレクトリや git の外に保管し、デモアカウントから録画してください。アカウントが表示するものがビデオに出荷されます。すでに agent-browser で機能を検証済みですか? そのウォークを保持し、2番目のスクリプトをスキップしてください。agent-browser の
--json結果は何が実行されたかを示しません(scrollは{scrolled:true}を返します)。そのため、各呼び出しをラップして、コマンドが結果と一緒に表示されるようにしてから変換します:ab() { agent-browser "$@" --json | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{const r=JSON.parse(s);process.stdout.write(JSON.stringify({command:process.argv.slice(1),...r})+"\n")})' -- "$@" >> steps.jsonl; } ab open https://target.example; ab snapshot -i -u; ab click @e27 ab wait 800; ab snapshot -i # ページが変わった: 参照が再番号付けされる ab fill @e2 query; ab press Enter vos actions from-agent-browser steps.jsonl --out actions.json(パス全体を1つの
agent-browser batch … --json > steps.jsonlとして実行すると、すでにその形状になっています)。ログはカレントディレクトリのsteps.jsonlなので、1つのディレクトリからウォークします。参照は、それらの前にある最後のsnapshot -iを通じて解決され、ナビゲーション後、さらにダイアログ内で再番号付けされます(RENUMBER)。ページを変更する何かがあった後は再スナップショットを取り、参照を名付ける前に読み取ってください(-uはリンクに href を与えます)。コントロールをクリックし、ショートカットは押さないでください。⌘K は人間のためにダイアログを開きますが、キーストロークはレコーダーが再生できない唯一のステップです。レコーダーが追従できないもの(ショートカットキー、ドラッグ、2回目のopen)は、出力で NAMED され、決してドロップされません。メモを読み、それらのステップを手動で書き、その後録画してください。 -
actions.jsonを書く:{ "url": "https://target.example", "viewport": { "width": 1280, "height": 720 }, "steps": [ { "do": "wait", "ms": 800 }, { "do": "hover", "selector": "a[href='/pricing']", "ms": 700 }, { "do": "click", "selector": "#cta" }, { "do": "wait", "ms": 1500 }, { "do": "scroll", "dy": 400 }, { "do": "move", "x": 640, "y": 320 }, { "do": "wait", "ms": 900 } ] }動詞:
waithoverclicktypescrollmovedrag(type={do:'type', selector, text, delayMs?, ms?, focus?}: フィールドをクリックし、次にtextを入力します。focus:falseは既にフォーカスされているものに入力します。Enter 送信用。) (drag = 実際の編集:{do:'drag', selector|x,y, tx, ty, ms}— 範囲入力をスライド、キャンバス要素をドラッグ、タイムラインクリップを移動)。ペーシングはズーム計画です: オープンwait ≥700ms。重要なものに700–900msホバー(滞留はズームになります)。クリックのmsは読む時間であり、ページの最後の変更から保持されます(@vosjs/cli0.47以降。レコーダー自体がセトルを支払います)。そのため、ビートとしてサイズ設定します: ナビゲーション後は約1000ms、コントロール後は600ms、遅いページのためにパディングしないでください。settled で終了します。ホバーでトリガーされるメニューからカーソルを遠ざけます(taste.md、フロールール)。vos validate actions.jsonで確認します。次にリハーサルを行います(
@vosjs/cli0.39以降):vos record --actions actions.json --out take --dry-run。すべてのステップが実際のページに対して順番に実行されます。なぜなら、後のセレクタは通常、以前のクリックの後にのみ存在するからです。ただし、何もキャプチャされず、何も書き込まれません。見逃されたセレクタは、リアルタイムのテイクとそのエンコードの後ではなく、数秒で名前が付けられます(終了コード2)。また、--out内の既存のテイクは、そのフッテージとカットを保持します。各ステップの rect をキャプチャピクセルで出力します。これは固定レイヤーが読み取るものです。スクリプトを編集するたびに再度リハーサルし、合格したスクリプトのみを録画します。サインインした製品も同様にリハーサルします。--storage-stateと--browser-arg=も適用され、リハーサルはフレームが EXPOSE するもの(アドレス、キー、カード)をリストして終了します。録画する前にmaskでそれらを非表示にします:references/sessions.md。 -
録画:
vos record --actions actions.json --out take --strict --json--strictは常に指定します: スキップされたセレクタ / ネットワークアイドルタイムアウト → 完了イベントでskipped[]とともに終了コード2。スキップはフローが壊れていることを意味します — 修正し、回避して出荷しないでください。テイクは自動的にエンコードされ、自動的に計画されます。 (vos create --actions actions.json out.webm --strictはワンショットの録画+レンダリング動詞です — クイックな最初のパスには問題ありませんが、このスキルのループはレンダリング前にフレームをレビューするため、ここでは別々の動詞を推奨します。) -
doc.jsonを調整する(JSON Schema は@vosjs/clinpm パッケージに同梱:schema/doc.schema.json):zoom:[{in, out, level, cx, cy, source}]、SOURCE 秒。レベル 1.4–2.8。cx/cyは NORMALIZED [0..1](0.5,0.5 = 中央)— ピクセルではありません。触れるスパンに"source": "manual"を設定します(再計画後も存続)。segments(トリム)・speed(rate0.1–16)・frame.*・cursor。tilt:[{in, out, rx, ry, source}]、SOURCE 秒 — 3Dカードがアクティブな間ポーズに傾き、間で休止位置に戻ります。度(±5..18 でプレミアム感): +rx = 上端が近づく、+ry = 左端が近づく(右側のフォーカスに向かって傾ける = 負のry)。スパン ≥ 0.8s。ズームモーメントとペアにします(同じ in/out で動きを連鎖)、約5秒のビートごとに1つのポーズ変更。触れるスパンに"source": "manual"。tiltStyle: "subtle"|"medium"|"strong"で自動ワンドを記録します。frame.backgroundMedia: カードの背後にあるビデオループ/画像 —{"kind":"video","key":"/bg.webm","duration":10,"dim":0.2}。key= テイクディレクトリにドロップされたファイル("/bg.webm")またはメディア URL。ビデオにはdurationが必要です(OUTPUT アンカー、modulo ループ)。dim0..1 スクリム。雰囲気であり、主題ではありません — 密なUIの背後では暗くします。audio: OUTPUT アンカーのクリップ。keyはテイクディレクトリにドロップされたファイル("/music.mp3")でも可。ゲイン/フェード/ループ。フルレンダリング時にミックス(Opus/AAC)。--rangeは無音のまま。シングルフライトを強制。- 書き出し:
{"resolution": "720p|1080p|2k|4k", "fps": 30}— フッテージを超えてはいけません(バリデートが警告します)。 次にvos validate take --json— lint がパスする必要があります。
-
レンダリングの前に確認する(taste.md 品質ループ):
vos frames take --at-zooms --times 0,25%,50%,75%,100% --json→ taste.md に対してすべての静止画を判定し、ズーム頂点を最も厳しく判定します。- 反復: doc.json を編集 →
vos render take check.webm --range a..b --draft(秒、半分の解像度 — ドラフトを出荷しないでください)→ 変更された領域を再フレームします。 - プレゼンテーションを試しますか? スクラッチスクリプトではなく、フラグを使用してください。
render/framesは doc のオーバーライドを受け入れます —--set <path>=<value>(繰り返し可能。JSON または文字列)、--frame <macos|windows|minimal|none>(render)、--background <url>— これらはメモリ内の doc にパッチを適用し(doc.json はそのまま)、lint でゲートされます。したがって、vos frames take --frame 2.0 --set frame.browserBar.kind=mac-light --set tilt[0].rx=8は、ファイルに触れることなく、フレームされ傾いたカードをプレビューします。
-
最終レンダリング:
vos render take out.webm --json(または--format mp4)。完了を宣言する前に、最終版を taste.md に対して再フレームします(frames --at-zooms)。レンダリングは決定論的です — 出力を変更するのはあなたの編集だけです。
6b. 人間によるレビューラウンド(依頼にレビューが含まれる場合): vos open take はテイクをスタジオに提供します — あなたの doc.json 編集はそのまま到着します