コード製動画から編集可能なAfter Effectsプロジェクトを作成する
目標は、モーションデザイナーが手作業で構築したかのように開いて作業できるプロジェクトを生成することです。テキストは生テキスト、パスはシェイプレイヤー、各オブジェクトは名前付きプリコンポーズ、カメラは再キーフレーム可能なヌルになります。逆に、レンダリング済みフレームシーケンスをコンポにドロップしただけのものは編集不可能なので、メインアニメーションとして決して提供しないでください。
アプローチは3ステップです:
- レンダラーが描画する同じデータからシーンをエクスポート。
scene.jsonとして書き出し。- After Effectsが、生成されたExtendScriptを実行して、プロジェクトを自動構築。
バイナリの.aepを手動で書くことはありません。
renderer data ──export──▶ scene.json + assets/ ──make_jsx.js──▶ build.jsx ──After Effects──▶ project.aep (+ check stills)
バンドルスクリプト(scripts/ 内):
aelib.jsx:After Effects内で実行されるビルダー。シーンを読み取り、コンポ、レイヤー、キーフレーム、マスク、エフェクト、マット、マーカー、オーディオを作成し、.aepとビルドログを保存します。make_jsx.js:node make_jsx.js [--portable] scene.json build.jsxで実行。シーンをチェック(アセット欠落、不正な親、プリコンポーズ順序)し、単一の自己完結型build.jsxを書き出します。--portableを付けると、パスはbuild.jsxからの相対パスになり、フォルダをZIP圧縮して別のコンピュータ(Windows含む)で実行可能になります。納品物として使用します。run_in_ae.sh:run_in_ae.sh build.jsx /abs/path/Project.aep [timeout]。macOSで、インストール済みのAfter Effectsでビルドを実行し、完了を待ってログを表示します。
エクスポーターを書く前に、references/scene-spec.md を読んでください。すべてのフィールド、イージング、チェック済みエフェクトマッチ名と値の範囲、時間を浪費する落とし穴が定義されています。
ワークフロー
1. 動画が描画するものを棚卸し
レンダラーを読み、画面に表示されるすべてのものとその動きをリストアップします:
- ワールドまたは背景。
- 各オブジェクトまたはドキュメント。
- 各テキスト。
- カメラの動き。
- 言葉やビートに合わせた瞬間。
- ルック:グレイン、グロー、ビネット、モーションブラー、フェード。
- オーディオ。
各項目について、その数値の出どころ(定数、ジオメトリ関数、タイミングファイル)をメモします。
2. 各要素をAEネイティブ形式にマッピング
モーションデザイナーが手作業で構築するであろう形式を選びます:
| コード内 | After Effects内 |
|---|---|
| ワールド上のカメラ移動(移動、拡大縮小、回転) | 1つのCAMERA null。アンカーポイント = カメラが見ている点(ワールド座標)。スケール = ズーム。回転 = ロール。位置 = コンポの中心。すべてのワールドレイヤーをこれにペアレント化。すると screen = position + R·scale·(p − anchor) となり、キャンバスカメラ変換と正確に一致するため、ワールドレイヤーはコードが使用する座標を維持します。 |
| 手持ちブレ、衝撃ジョルト | nullの位置と回転に適用するエクスプレッション。それぞれの動作を表す名前(「Handheld amount」「Impact strength」)のスライダーコントロールで駆動。 |
| オブジェクトやドキュメント(印刷物、紙、カード、本) | 独自のプリコンポーズ。境界線、写真、テキスト、コンタクトシャドウ、「Dim」ソリッドを含む。2倍サイズでオーサリングし、レイヤースケールを50%に設定。Collapseをオンに。プリコンポーズレイヤー上でドロップインをアニメート。 |
| ベクターパス(海岸線、ルーラー線、円、線) | シェイプレイヤー。論理的な部分ごとに1グループ、名前付き。 |
| テキスト | テキストレイヤー。実際の文字列とPostScriptフォント名を使用。プリレンダリングされたテキスト画像は絶対に使用しない。 |
| コードが生成するビットマップ(プレースホルダー写真、紙テクスチャ) | PNG/JPGアセットとしてエクスポート。交換しやすいように名前を付ける(「PHOTO — replace me」など)。 |
| ナレーションに合わせて単語ごとに表示される文字 | reveal: { times: [...] } を持つテキストレイヤー。ビルダーが単語ごとにWrite-onマスクのキーを打つ(AEで計測)。テキストは編集可能のまま。 |
| 線が自分自身を描画する動作 | Trim Paths end キーを0→100 |
| スタンプ / スラム | スケール/不透明度キーと、カメラインパクトリストへのエントリ |
| ヒーローフォーカス / 他を暗くする | 各プリコンポーズ内の透明度保持付き黒「Dim」ソリッド、および背景上の画面スペースDimソリッド(不透明度キー付き) |
| フィルムルック | 名前付き調整レイヤー(「LOOK — Soft glow」「LOOK — Film grain」)、フェザー付き反転マスクを持つビネットソリッド、フェードソリッド、ワールドレイヤーに対するコンポモーションブラー。すべてオフにしやすいよう名前を付ける。 |
| オーディオ | 別々のステム(音声、音楽/効果音)をオーディオレイヤーとして、さらにナレーション行をコンポマーカーとして |
3. 信頼できる情報源からエクスポート
数値を再入力する代わりに、既存のレンダラーにエクスポートパスを追加します。例えば、その内部を公開(module.exports、--export フラグ、またはモジュールのインポート)し、export_ae.js / export_ae.py を書きます。これにより scene.json と assets/ フォルダが生成されます。こうすることでAEプロジェクトとMP4が乖離せず、ストーリー変更後の再エクスポートも1コマンドで済みます。
モーションを一致させるために:
- カメラおよび他のカーブ。 意味のある瞬間(ホールドの開始と終了、着地)にのみキーを打ち、すべてのフレームには打たない。各キーに 33.333% の影響力 でその時点のカーブの真の速度を与える:これで三次エルミートが正確に再現される。途中で追加の動作(引きズーム、対数空間ズーム)がある場合は、その移動の1/4、1/2、3/4の点にも自身の微分値とともにキーを追加する。微分値はレンダラーのカメラ関数から数値的に取得する。
- 符号付き速度。 回転、スケール、不透明度の速度は符号付き。空間プロパティ(位置、アンカーポイント)は絶対値のみ。
- フレームごとのキー は、本当に不規則なもの(例:フリッカー)にのみ許容される。それ以外は簡単に掴んで移動できるようにする。
- 再タイミング。 レンダラーが使用するのと同じファイル(例:
timings.json)からタイミングを読み取る。これにより、ナレーションの再タイミングがプロジェクトにも反映される。
開く人のために書く:
- すべてのレイヤーにそれが何であるかの名前を付ける(「Ink circle (draws on 'Kestrel Point')」、「Map dim (hero focus)」)。
- 明白でないものには1行の
commentを付ける。 - ラベルを使用してグループ化し、カメラヌルには明確なラベルを付ける。
- ナレーション行はコンポマーカーとして配置する。
4. ビルドと確認
node <skill>/scripts/make_jsx.js --portable --quiet scene.json build.jsx # build.jsx は assets/ の隣に配置
<skill>/scripts/run_in_ae.sh build.jsx "/abs/path/My Project.aep" 1500
- 前提条件(AEで一度だけ): 環境設定 → スクリプティングとエクスプレッション → 「スクリプトによるファイルへの書き込みとネットワークアクセスを許可」を有効にする。これがないと、保存とビルドログが失敗する。ランナーがタイムアウトした場合、この設定(またはAEの開いたダイアログ)が原因であることが多いので、ユーザーに確認を依頼する。
- 既存の作業を破棄しない。 開いているAEプロジェクトに未保存の変更がある場合、ビルドは停止し、その旨をログに出力する。ユーザーのプロジェクトを破棄することでこれを回避しないでください;ユーザーに保存または閉じるよう依頼すること。自動ビルドでは
--quietを使用して、メッセージをダイアログではなくログに送る。納品するbuild.jsxでは--quietを付けずに再生成し、手動で実行する人がメッセージを見られるようにする。 - ビルドログ(
<Project>.build-log.txt)には、失敗したレイヤー、エフェクト、プロパティがすべてリストされる。問題はシーンのバグとして扱い、AEではなくエクスポーターで修正する。 - チェックスチル。
project.stillsに5~8枚の適切なタイミング(単語同期瞬間、ドロップ途中、ヒーローホールド、タイトルなど)を設定する。ビルダーはメインコンポからそれらをレンダリングする。保存後に非同期でレンダリングされ、ランナーはそれらを待つ。16ビットPNGで、ffmpegが常に読めるとは限らないので、sips -s format jpeg -Z 1920 in.png --out out.jpgで表示する。 - 同じタイミングの元レンダリングのフレームと並べて比較する。 フレーミング、どのオブジェクトがヒーローか、テキストリビールが単語に合っているか、色と明るさを確認する。その後エクスポーターを修正して再ビルドする。AEのグローはキャンバスの「ぼかしたコピーのスクリーン合成」よりもはるかに強いので、高いスレッショルド(約200/255)と低い強度(約0.2)から始めること。
もしこのマシンにAfter Effectsがインストールされていない場合、または編集者が別のコンピュータで作業する場合は、起動しようとしないでください。ポータブルフォルダ(build.jsx、assets/、scene.json、README)を納品します。編集者は ファイル → スクリプト → スクリプトファイルを実行… でそれを実行し、.aepは build.jsx の隣に保存されます。READMEには、最初にスクリプトのファイル書き込み設定を有効にするよう伝え、またフォントがインストールされている必要があることを記載する必要があります。
5. 納品
1つのフォルダを納品します。含めるもの:
<Name>.aepassets/- プロジェクトを再ビルドできるよう、
build.jsxとscene.json - エクスポータースクリプト
- 短い
README.md。以下の方法を説明する:- カメラを動かす:CAMERA nullのアンカーポイント(見ている場所)とスケール(ズーム)をキーフレーム
- 写真を差し替える:プロジェクトパネルでアセットを選択し、ファイル → フッテージの置き換え
- 単語を再タイミング:そのレイヤーのWrite-onキーをドラッグ、またはタイミングを変更して再エクスポート
- ルックレイヤーをトグル
- テキストを変更:ダブルクリック
- インストールが必要なフォント
ユーザーに明示的に伝える:
- 正確に一致するもの(レイアウト、タイミング、キー)
- 近似されているもの(AEのグロー、グレイン、色はキャンバスコンポジットと多少異なる)
- スチルで確認したものと確認していないもの(例:全長再生)
これまでに問題になったこと
上記の規約の背後にある理由:
- シェイプやテキストレイヤーへのシャドウやブラーはカメラと連動して拡大縮小しない。 それらのエフェクトはトランスフォーム後に適用されるため。ワールドスペースのグローやシャドウには、マスク付きソリッドを使用する。
- プリコンポーズはカメラがズームインするとソフトになる。 Collapse Transformationsで修正し、2倍サイズでオーサリングする。
- フェザーマスクはソリッドの端で切れる。 グロー用ソリッドはグローよりはるかに大きくする。
- フォントはPostScript名でなければならない。 未知のフォントはAEで簡単なプローブ(
textDocument.fontを設定して読み返す)で確認する。 - ExtendScriptはES3であり、連鎖三項演算子(
a ? b : c ? d : e)を誤読する。 代わりにルックアップテーブルまたはif/elseを使用する。aelib.jsxを変更した場合は、フルビルドの前に小さなシーン(テキストレイヤー1つ、シェイプ1つ、プリコンポーズ1つ)でテストする。