demo-reel は何をしますか?
あなた自身が動画全体を制作します。ユーザーは製品と表示したい内容を提供し、投稿可能なMP4ファイルを受け取ります。画面上のすべては実際の製品をライブ録画したものであり、(ウィンドウフレーム、カメラワーク、キャプション、タイトル・エンドカードといった)仕上げは録画後に追加されます。
パイプラインと各ステップで生成されるファイル:
| ステップ | コマンド | 生成物 |
|---|---|---|
| 1. ストーリーボード | あなたがユーザーと共同で作成 | 3~5の機能、それぞれにキャプション1つ |
| 2. シナリオ | scenario.mjs を記述 | ユーザーが取る手順 |
| 3. テイク | bin/reel take scenario.mjs takes/take1 | take1.mov(映像+アプリの音声)、take1.json(イベント、要素の位置) |
| 4. 編集 | edit.json を記述 | シーン、ショット、キャプション、ブランド情報 |
| 5. スチル | bin/reel check edit.json、bin/reel layers edit.json、次に bin/reel stills edit.json 1,4,9 | 問題の早期発見;プレビューフレーム |
| 6. 字幕 | bin/reel subtitles edit.json、その後 build/subtitles.srt を確認・修正 | 発言内容をキャプションとして出力 |
| 7. レンダリング | bin/reel render edit.json renders/x.mp4 --format all | 各フォーマットの動画とその .srt ファイル |
| 8. 確認 | bin/reel sheet renders/x.mp4 1,4,9,… | コンタクトシート、長さ、ラウドネス |
examples/sawt/ は完全な実例(記事を音声読み上げするChrome拡張機能)です。自分の scenario.mjs や edit.json を書く前に、この例のファイルを開いて参照してください。docs/edit-format.md は編集ファイルのリファレンス、docs/lessons.md には初回に発生した問題が記載されているため、録画前に必ず読んでください。
0. セットアップ(一度だけ)
まず bin/reel doctor を実行します。これにより、すべてのツールと権限をチェックし、修正すべき点を表示します。
bin/reel setup はレコーダー(Swift、ScreenCaptureKit)をビルドし、playwright-core と Chrome for Testing をインストールします。さらに、ffmpeg、uv、Google Chrome(オーバーレイレイヤーのレンダリング用)が必要です。あなたを実行しているターミナルには画面およびシステムオーディオ録音の権限が必要です(システム設定 → プライバシーとセキュリティ);レコーダーが許可されていないと報告した場合、ユーザーに権限を付与してもらい、ターミナルを再起動するよう依頼してください。
1. ストーリーボード
録画前に、いくつかの行で以下を合意します。
- 機能を順番に、それぞれにキャプションを付けます。短いキッカ―(「ワードズーム」)と、最大2行の見出し、そして
<b>で囲んだ成果(「読み上げに合わせて各単語が拡大します」)を含めます。 - デモに使用する実際のコンテンツ:公開ページ、サンプルアカウント、シードデータなど。機能が最もよく見えるコンテンツを選び、事前に確認します(Sawtの場合:難しい単語にカードが表示される記事で、そのカードが列の横に配置されるサイトを選びます)。
- ブランド:アクセントカラー、その薄いバリアント、背景の色合い、ロゴ;タイトルカードとエンドカードのテキスト。
デフォルトフォーマット:1080×1350(4:5)、25~35秒 — これはスマートフォンのフィードで最も多くのスペースを占め、ほとんどのユーザーがミュートで視聴するため、キャプションだけでストーリーが伝わる必要があります。投稿先を尋ねてください。1:1、9:16、16:9 は同じ編集から --format で生成できますので、提案してください。レンダリングする各フォーマットのスチルを確認します。4:5でうまくフレーミングされたショットでも、1:1では見出しが切れることがあります。その場合はフォーマットごとに微調整します("1:1": {"dy": 20})。
製品に音声がある場合(またはテイクにナレーションが含まれる場合)、字幕を作成します。reel subtitles を実行し、.srt ファイルを読んで名前や専門用語を修正してからレンダリングしてください — 文字起こしは良好ですが、完璧ではありません。難しい単語は subtitles.words に追加して認識精度を高めます。
2. シナリオ
シナリオはESモジュールです(完全なAPIは drive/take.mjs を参照):
export const config = { url: "https://…", width: 1700, height: 1090, extension: "./ext" };
export async function setup(api) { /* 設定、ログイン;カメラターゲット用に api.rect("title", "h1") */ }
export async function run(api) { /* デモ;カットのタイミングごとに api.mark("step") */ }
export async function after(api) { /* 画像シーンとして表示するスチル(例:3倍のポップアップ) */ }
- カットまたはカメラ移動を行うすべての瞬間にマークを付けます(
api.mark("sentence", {n}))。編集はこれらのマークを基準にするため、テイクの速度が速くても遅くても、正しい位置でカットされます。 - カメラターゲットは
api.rect(name, selector | fn, arg)でビューポートピクセル単位で記録します。 クローズドシャドウルート内の要素は測定できません。その場合は、それらが表示される位置を計算してください(Sawtカードの例を参照)。 - クリック駆動の製品には可視のポインターが必要です。 自動化では実際のカーソルは動かないため、図形が表示されたりボタンが自動で押されたりします。
setupでapi.pointer.show()を呼び出し、その後api.pointer.click(selector | [x, y])、.drag(from, to)、.move(x, y)、.type(text)、.key(k)で操作します。画面上の矢印が追従し、クリック時に波紋が広がり、移動はイージングされ、タイピングは人間らしいリズムになります。クリック操作はセレクタ(titleやaria-labelが通常安定)で行い、その位置はページから取得されます。 - キャンバスコンテンツ(描画、チャート、地図)には測定可能な要素がありません。その場合は
api.rect(name, {x, y, width, height})でCSSピクセル単位で領域を記録します。 - Chrome拡張機能:拡張機能独自のコードでアクションを実行するには
api.inWorker(fn)を使用します。activeTabに依存する拡張機能は、ホストアクセス権を持つ録画用コピーが必要です。これは自動化がブラウザのショートカットを押せないためです(examples/sawt/prepare.shを参照)。視聴者に見える部分は一切変更しないでください。 - ポップアップやその他の小さいUI:
after()内でCDPを使用してデバイスピクセル比3でキャプチャし(例を参照)、画像シーンとして表示します。トグルの両方の状態を同時にキャプチャするには、リロードせずに実際のコントロールをクリックします。
シナリオを実行した後は、編集前にテイクを確認します:ffmpeg -ss 6 -i takes/take1.mov -frames:v 1 x.png でPNGを生成し、読み取ります。ページがスタイル適用されているか、機能が発動しているか、カバーされていないかを確認します。テイクは自由に取り直してください — 1テイクに数分しかかかりません。
3. 編集
edit.json を記述します(リファレンス:docs/edit-format.md)。録画ではなく制作したように見せるためのルール:
- 間でカットします。
bin/reel speech take1.movで音声がある場所をリストアップします。テイクの断片は、各ステップの直前から始まり、次のステップが始まる直前に終わります。マークを基準にアンカーを設定します:"sentence#5-0.15"。 - 横並びのコンテンツは縦長のウィンドウに収まりません。 左のツールバーと右の図が、4:5のウィンドウで表示可能な幅よりも広くなることがあります。
reel checkはフォーマットごとに、フィットさせたショットで失われる量を警告します。表示する要素を減らすか、そのフォーマットに合わせてショットを微調整します。 - 矩形からのショット。
{"fit": ["title", {"rect": "card1", "dh": 330}], "pad": 60}。最初にワイドなエスタブリッシングショットを入れ、キャプションが説明している内容にズームインします。出力でテキストの高さは少なくとも約20ピクセル以上を維持します。ワイドショットでは一時的に小さくなることはありますが、長時間続けてはいけません。 - シーンごとに1つのキャプションを表示し、シーン全体にわたって表示。キャプションの切り替えはカメラ移動時のみ。
- 動きに余白を持たせます: カメラ移動は1.0~1.5秒、移動後は最低1.5秒間静止します。
- タイトルカードは2~2.5秒、エンドカードは3~3.5秒。画像シーン(ポップアップ、設定パネルなど)は3~4秒。
速度
30秒の4:5レンダリングは、6コアのノートPCで約3分かかります。フレームは並列チャンクでレンダリングされ(デフォルト4、--jobs N で変更)、再エンコードなしで結合され、変更のないレイヤーは再利用されます。編集がまだ確定していない間は、reel render … --draft(15fps、高速エンコーダ、約半分の時間)と reel stills を使用し、スチルが適切に見えるようになってから本番レンダリングを行います。
4. 毎回の確認手順
bin/reel layersとbin/reel stillsを各シーンの開始、中間、終了、および各カメラ移動時に行います。すべてのPNGを確認します。フレーム端でのテキストやUIの欠け、上部の見出しが半分しか見えない、キャプションが重要な要素を覆っている、フレーム全体が空のページになっているなどの問題を探します。- レンダリング後、
bin/reel sheetで動画全体を確認します。 - 長さが計画通りであること、また製品が音声を出力する場合はラウドネスが約-16 LUFSであることを確認します。
- 同期:画面上のステップの表示とその音声の開始がテイクと一致していることを確認します。
その後、MP4とサムネイル(build/layers/title.png)をユーザーに提示し、実際の製品と録画のために変更した点を明確に伝えます。
音楽
デフォルトでは、システムが動画に適したBGMを自動選択します(docs/music.md)。動画の長さ、音声、テンポ、キャプションの単語をプロファイリングし、ライセンスされたインストゥルメンタル候補をランク付けします。優先順位は、ユーザー自身の music/ フォルダ、次にバンドルされたCC0ライブラリ(library/)、ローカルに適切なものがない場合のみオンライン楽曲です。テンポ、エネルギー、安定性を測定して評価し、最適なものを採用します。reel music auto edit.json --audition renders/x.mp4 を実行してランキングを表示し、トップトラックのプレビューを聞くことができます。あなたは音声を聞けないため、動画が完成する前にプレビューをユーザーに渡してください。最適なトラックがリンクのみ提供される場合(サイトがスクリプトによるダウンロードをブロックしている場合)、ユーザーにリンクを渡します。ユーザーがダウンロードしたら、reel music add <file> --candidate N で追加します。ユーザーが自作のトラックを持ち込んだ場合は、そのライセンスを reel music add で記録し、編集に含めます。常にレンダリングファイルと一緒に .credits.txt を提供し、そのライセンスが公開クレジットを必要とする場合はその旨を伝えます。
制限事項
- 録画はmacOSのみ対応(ScreenCaptureKit)。コンポジットとレイヤー処理はどのプラットフォームでも動作します。
- 現時点ではブラウザ製品のみ対応。デスクトップアプリには独自のドライバー(アクセシビリティスクリプティング)が必要ですが、レコーダー(
--app <bundle id>)および後続のすべての処理は既に任意のアプリで動作します。 - 音楽生成(
reel music generate)はローカルモデルの接続が必要です。ACE-Stepが推奨されていますが、demo-reelでのテストはまだ行われていません。