Motion Ad Studio(自己改善型)
シニアモーションデザイナーが認めるクオリティの縦型モーショングラフィックス広告(20〜40秒)を作成します。フレーム0からすでに動いており、1つのキャリアオブジェクトが映像全体を貫き、トランジションは動きの途中でカットかつ速度がマッチし、すべてのクリック、着地、ドロップ、スウッシュが音声の単語または音楽ビートにロックされます。映像は単一HTMLページ(GSAPタイムライン+時間の純粋関数)です。フレーム正確にMP4にレンダリングされ、誰かが視聴する前にスクリプトがチェックします。効果音は映像自身のイベントリストから配置されるため、オーディオ同期は感覚ではなく設計によって保たれます。
毎回の実行:最初に references/lessons.md と references/runs.md を読み込むこと。最後にRetrospective(ステップ13)を実行すること。
教訓を書き戻すことによってのみスキルは改善されます。
0. プリフライト(常時)
python scripts/preflight.py [--elevenlabs-mcp yes] # ElevenLabsツールが接続されている場合は yes を渡す
以下で使用するパス:scripts/...、references/...、templates/... はこのスキルのフォルダからの相対パス($SKILLS/motion-ad-studio)。$MOTIONMAXXING はエンジンフォルダ($SKILLS/motionmaxxing、プリフライトが表示)、$SEAM_GATE はプリフライトが見つけるオプションのシームゲートスクリプト(または --seam-gate FILE で指定)。
| 必要なもの | 理由 | ない場合の対処 |
|---|---|---|
| motionmaxxing エンジン(Apache-2.0) | render.mjs(フレーム→MP4)、look.py ゲート、lint.mjs デザインリント、runtime/vendor/gsap.min.js | このスキルの隣で git clone https://github.com/Tejashmakwana/motionmaxxing、または MOTIONMAXXING を設定 |
| ffmpeg + ffprobe、Node 18+、Chrome/Chromium/Edge | レンダリング、プローブ、ミックス | インストール;Chromeが自動検出されない場合は CHROME_PATH を設定 |
| Python 3.9+(numpy + Pillow) | ビート、シンセベッド、ミックス、シート | pip install numpy pillow |
| faster-whisper(オプション) | 単語ロックタイミングのための単語タイムスタンプ | pip install faster-whisper、または単語の開始/終了時間を取得できる任意のアライナー |
| シームゲート(オプション) | 各トランジションが速度マッチしていることを証明 | HyperFrames motion-doctrine + patches/seam-gate-camera-overlap.patch |
| ElevenLabs(オプション、推奨) | 表現力豊かなVO、作曲音楽、カスタムSFX | 次のセクションを参照 |
ElevenLabsはオプション:ユーザーに一度通知し、ブロックしない
プリフライトが NOTICE(APIキーがなく、ElevenLabsツールもない)を表示した場合、オーディオステップの前にユーザーの言語で1回だけ短いメッセージで伝え、以下の選択肢を提示します:
- 接続する:ユーザーが
ELEVENLABS_API_KEYを追加するか、ElevenLabs MCPサーバーに接続します。プリフライトを再実行します。 - 続行する:以下のキーなしパスでフル映像を作成します。納品ノートで一度だけ「ElevenLabsがあればVOと音楽の品質が向上する」と伝えます。同じプロジェクトで再度尋ねないでください。
対話不可能な実行(バッチや非インタラクティブ)の場合は、ElevenLabsなしで続行し、推奨事項を NOTE.md に記述します。
| レイヤー | ElevenLabsあり | ElevenLabsなし(それでも出荷可能) |
|---|---|---|
| ボイスオーバー | 感情タグ付きTTS、2テイク、1つ選択 | ユーザー自身の録音(最善)、またはローカル/OSのTTSガイドボイス;VOなしの音楽主導映像 |
| 音楽 | 映像の長さに合わせて生成、ペイオフでドロップ | scripts/synth_bed.py(手続き型、正確なビートグリッド)、またはユーザーが権利を持つトラック |
| SFX | 1~3個のヒーローサンプル(ウィップ、スーッ、タイピング) | scripts/mix_events.py がすべてのSFXをローカルで合成 |
| 単語タイミング | タイムスタンプ付き音声認識(またはTTSタイムスタンプ) | scripts/words.py(ローカルfaster-whisper) |
詳細、プロンプト、クレジットコスト、ライセンスルール:references/audio-providers.md。
パイプライン
-
ワークスペース。
python scripts/new_film.py <project>がワンテイクキット、GSAPランタイム、ローカルフォントをコピーします。未編集のデモを1スチルレンダリングしてツールチェーンを確認:node $MOTIONMAXXING/scripts/render.mjs <project>/film/index.html --still 1.2,16.4 <project>/stills。 -
ブランドキット。 ユーザーから公式ロゴファイルを入手し、それぞれをアルファバウンディングボックスでトリミングします。キャリアがロゴにドッキングする場合は、サブグリフ矩形を測定します。色はサイトCSSの
#hexをカウント、フォントはローカルwoff2として取得(scripts/fetch_fonts.py)。ブランドが実際に使用するCTAチャネルを使用します。ロゴを再描画したり近似したりしないでください:必ず依頼してください。 -
1つのアイデア+新しいスタイル。 このブランドだけが撮影できる1つのアイデアだけを書きます。ロゴカバーテスト:ロゴを隠しても映像がこのブランドを指している必要があります。3つの方向性を書き、2つを却下し、
references/runs.mdの最後の行と異なるスタイルを選びます。 -
フック。 12語未満のバリエーションを3つ書き(疑問、否定、具体性、ストーリー)、1つ選びます。フレーム0はすでに動きで埋まっており、フックはフレーム1までに画面に表示され、何も黒からフェードインしません。
-
ボイスオーバー。 約2.5語/秒で書きます(30秒≈70〜75語)。TTSが感情タグをサポートしている場合は、各行にマークします([curious] [confident] [energetic] [playfully] [warmly])。生成または録音し、長いポーズをトリミング、
atempo≤1.1で長さを調整し、単語時間を取得:python scripts/words.py audio audio/vo.wav --lang <code>。Whisperは時間のみを提供します。キャプションテキストは常に承認済みスクリプトから取得します。 -
音楽。 生成(長さ+BPM+「<ペイオフ秒>でドロップ」)、トラックのライセンス取得、または
python scripts/synth_bed.py --bpm 120 --dur 32 --drop 15.8 --out audio/bed.wavを実行します。python scripts/beats.py audio/music.mp3 audio/beats.jsonでグリッドを取得(synth_bedは正確な.beats.jsonを書き込みます)。音楽の先頭をトリミングしてドロップがペイオフのVO単語に合うようにします:フィルムビートk = first_beat - trim + k·period。 -
STORYBOARD.md + ledger.json(
templates/one-take/に記入済みサンプルあり)。以下を含める:- ページ仕様、アイデア、3つの方向性;
- リズムシート(ストレッチ / t / エネルギー0-10 / ルート / 音楽);
- タイミングマップ:すべてのイベントとそれがロックされている単語
w(i)またはビートbeat(k); - VOと実例データのリスト;
- 台帳:シームごとに1行(出口/入口軸+方向、カット時間)。
-
構築。 キットからパターンをコピー(
references/one-take-kit.md):- クロック
w(i)/we(i)/beat(k); - フレームごとの順序
tl.seek → PRE(カメラ、移動アンカー)→ カーソル(ライブ矩形を読み取り)→ UP(それに従うUI); - キーフレーム化された3Dカメラと、ライブDOM矩形をターゲットにするカーソルエンジン;
- タイピング/テキスト/クラスアップデータをtの純粋関数として;
sfx()イベントとカメラ由来のスウッシュ。
レンダラーが必要とするコントラクト:
#mainはdata-composition-id="main" data-width data-height data-durationを保持。window.__seek / __duration / __timelines / __events / __player / __ready / __playerReady / __renderReady。 モンタージュスタイルの映像(レイヤードシーン、フラットUI、ロゴキャリア):references/montage-kit.md。 - クロック
-
確認。 15〜20枚のスチルをレンダリング(
node $MOTIONMAXXING/scripts/render.mjs ... --still t1,t2,... stills)、タイル表示(python scripts/sheet.py stills sheet.jpg 6 220)、1回のビジョンパスを実行:フレームごとに1行、その後欠陥リスト。修正して2〜3パス繰り返します。- ジオメトリの真実(どこに何があり、可視性、透明度)は
node scripts/probe.mjs index.html "t1,t2" "#a,#b"から取得。 - テキストの真実はフル解像度クロップから取得:ビジョンは縮小されたアラビア語やCJKを「タイポ」と誤読することがあるため、実際にはタイポではありません。
- ジオメトリの真実(どこに何があり、可視性、透明度)は
-
シームゲート(推奨)。映像フォルダを localhost でサーブし、次に
node "$SEAM_GATE" verify --ledger ledger.json --url http://127.0.0.1:<port> --comp-url http://127.0.0.1:<port>/index.htmlを実行。目標は 0 FAIL。ワンテイクカメラホイップで両方のウィンドウが画面内に収まる行には"overlap": "camera"とpatches/のパッチが必要。その後サーバーを停止。references/qa-gates.mdを参照。 -
ミックス。 すべてのSFXは
window.__eventsに格納({t, type:'sfx', name, gain, dur?, speed?})。node $MOTIONMAXXING/scripts/render.mjs index.html --still <t> evでダンプするとev/events.jsonが書き込まれます。- ミックス:
python scripts/mix_events.py --events ev/events.json [--vo vo.wav --vo-at 0.10] [--music bed.wav --music-trim s] --dur <s> --out audio/mix.wav [--music-db -24] [--tp -2.5] [--whip/--whoosh/--typing samples] [--lift t0:t1:dB] [--fade t]。 - レベル:VO -18 dBFS RMS、音楽 -30(VO下でダッキング)、スウッシュはカメラの最速フレームにピーク合わせ、2パス loudnorm で -14 LUFS / TP ≤ -1。
-
レンダリング+ゲート+納品。
- レンダリング:
node $MOTIONMAXXING/scripts/render.mjs index.html <NEW-name>.mp4 --audio ../audio/mix.wav --crf 17 --grain 0.03。試行ごとに新しい出力名を使用:1ファイルに2回レンダリングすると破損します。 ffmpeg -v error -i x.mp4 -f null -は何も出力してはいけません。次にpython $MOTIONMAXXING/scripts/look.py x.mp4 --out look --expect <dur> --expect-audio(G0/G2/G3/G5 PASS)とnode $MOTIONMAXXING/scripts/lint.mjs index.htmlを実行。- 納品:9:16マスター、4:5クロップ(レイアウト確認後
crop=1080:1350:0:200)、2〜3枚のカバーPNG、NOTE.md(アイデア、タイミングマップ、実データと例示データの区別、オーディオソース+ライセンス、ゲート数、改善点)、project/フォルダ(映像+オーディオ+スクリプト)。 - クリーンアップ:サーバーと孤立したヘッドレスChromeを停止。
- レンダリング:
-
Retrospective(必須、最終回答の前)。 日付付きのルール+理由を
references/lessons.mdに追記。references/runs.mdに行を追加(日付、製品タイプ、スタイル、長さ、ゲート数、判明した評価)。このファイル、スクリプト、またはキットを、ステップが変更された場合はパッチ。ユーザーが後で反応した場合、評価を記録。教訓はメソッドのみを保持し、クライアント名やプライベートデータは保持しません。
品質基準
- フック: 実際の顧客の言い回し、または好奇心のギャップ。フレーム0は動き、フックはフレーム1までに読み取り可能、黒からのフェード無し。
- 連続性: 1つのキャリアが映像全体を貫く(カーソル、チップ、ロゴマーク)、クロスフェード無し、2〜3種類のトランジションタイプを繰り返し。カットは動きの途中で発生し、速度がマッチ。1つの現在の方向性を維持:「次へ」の場合、RTL映像はコンテンツを左→右、LTR映像は右→左に移動。予約ベクトルは意味に費やす。
- タイミングロック: すべてのクリック、ドロップ、着地は
w(i)またはbeat(k)上にあり、音楽ドロップはVO単語上にある。スウッシュはカメラ速度から派生。タイミングマップは各イベントとそれがロックされているものをリスト。 - 無駄な揺れ無し: すべてのホールドには意図を持ったカメラ移動、段階的なリビール、またはライブUIがある。静止はペイオフの直前のみ。
- セーフゾーン(1080×1920):
- 有料Meta配置:読み取り可能なテキストは y 270-1250、x 60-960(右端120ピクセルはボタン);
- オーガニックReels/TikTok:下部320-370ピクセルはクリアに保つ;
- キャプションレールはUIパネルの下に配置、コンポーザーの上には絶対に配置しない;
- ドロップレールは画像がすでに示している単語。
- 終了: ワードマークとブランドの実際のチャネルでの1つのCTA。終了を0.6〜1.4秒保持し、最終ショットは映像の25%以下に保つ。
- 正直さ: NOTE.mdで例示データを宣言。パフォーマンスの主張、価格、推薦文を捏造しない。
- ターゲット: look.py G0/G2/G3/G5 PASS、運動エネルギー ≥ 5/255 平均輝度変化(ダークUI映像は約2)、カット同期率 ≥ 35%(計測されたプロベンチマーク)、-14 LUFS ± 0.5、トゥルーピーク ≤ -1 dBTP、デコードエラー0。
プラットフォーム注意事項
- Windowsのgit-bashでのバックグラウンドジョブ:
node.exeを呼び出し、nodeのwinptyエイリアスは使用しない(「stdin is not a tty」)。 - ESMによる絶対Windowsパスのインポートには
file:///C:/...が必要。 - 中断された実行からヘッドレスChromeがリークする。最後に、
--headless=newと--remote-debugging-port=0で起動され、親プロセスが存在しないブラウザをリストし、ルートとそのツリーを強制終了。 - レンダリング速度:フラットUIは1080×1920で35秒あたり約4分。3Dワールドは約4〜5分(約4fps)だが、3Dレイヤー数が少ない場合のみ。
ファイル
scripts/:preflight.py:依存関係とElevenLabs通知;new_film.py:プロジェクトのスキャフォールディング;fetch_fonts.py:ローカルwoff2;words.py:単語時間;beats.py:ビートグリッドとドロップ;synth_bed.py:キーなし音楽;mix_events.py:イベント駆動ミックス;sheet.py:コンタクトシート;probe.mjs:ライブジオメトリ。
templates/one-take/:実行可能デモとしての完全なワンテイク3Dカメラ映像(架空の製品、アラビア語RTLコピー)、STORYBOARD.md と ledger.json 付き。references/:research.md:ランドスケープ調査、アップストリームスキル、セキュリティノート、プラットフォーム仕様;lessons.md、runs.md:自己学習メモリ;audio-providers.md、one-take-kit.md、montage-kit.md、qa-gates.md。
patches/seam-gate-camera-overlap.patch:ワンテイクカメラ映像のためのオプトインシームゲートルール。