Claude CodeでAfter Effectsを自動化するには、Claude CodeにExtendScript(.jsx)を書かせ、osascriptで起動中のAfter Effectsに送ってコンポジションを作り、付属のaerenderで書き出します。AEの画面には一度も触らずに、表のデータからタイトル(テロップ)動画を何本でも作れます。
ショート動画のタイトルやテロップは、文言と色だけを変えた同じ形の動画を何本も作ることが多い作業です。手作業だと、コンポジションの複製、文字の打ち替え、色の変更、レンダーキューへの追加を本数分くり返すことになり、1本の修正が全部に波及します。
この記事では、筆者がClaude Codeから実際にAfter Effectsを動かし、ツール紹介用のタイトル5本を一括で書き出した手順を紹介します。手元の環境はAfter Effects 26.5(2026年9月リリースの最新版・aerenderの表示は26.5×89)とmacOSで、掲載したスクリプトはこの環境で動かしたものです。Adobeの公式情報は2026年10月22日に確認しています。
全体の流れ|Claude Code → osascript → After Effects → aerender
仕組みは、スクリプトを書く、AEに送る、結果を確かめる、書き出す、の4段階です。Claude Codeはターミナルでコマンドを実行できるので、この4段階をすべて会話の中で進められます。
| 段階 | 使うもの | やること |
|---|---|---|
| 1. スクリプトを書く | ExtendScript(.jsx) | コンポジション・文字・動き・レンダーキューを組む |
| 2. AEに送る | osascript(AppleScript) | 起動中のAEに DoScriptFile でスクリプトを実行させる |
| 3. 結果を確かめる | プロジェクトの保存(.aepx) | XML形式で保存し、中身をgrepで確かめる |
| 4. 書き出す | aerender | レンダーキューの全項目を画面なしで書き出す |
After Effectsのスクリプトは、JavaScriptを拡張したExtendScriptで書きます(Adobe公式ヘルプ「スクリプト」)。書けるオブジェクトやメソッドは、Adobeのヘルプが案内しているコミュニティ運営のリファレンスAfter Effects Scripting Guideで調べられます。Claude Codeに書かせるときも、このリファレンスに沿っているかを確かめると安心です。
なお、Adobeは新しい拡張の仕組みであるUXPのAfter Effects版を開発者サイトでベータとして公開しています。2026年10月時点でExtendScriptの廃止の告知は見当たらず、この記事ではExtendScriptを使います。
準備|AE 26.5と書き出し先のフォルダ
必要なのは、After Effects本体と、書き出し先のフォルダを先に作っておくことの2つだけです。aerenderはAfter Effectsに付属しており、別にインストールする必要はありません。
- After Effectsを起動しておく(スクリプトは起動中のAEに送る)
- 疎通確認は新規プロジェクト([ファイル]→[新規]→[新規プロジェクト])で行う。作業中のプロジェクトで流すと、そこにテスト用のコンポジションが足され、保存先も変わってしまう
- 書き出し先のフォルダをターミナルで作っておく(理由は後述)
- 初めてosascriptからAEに命令を送るとき、macOSが自動操作の許可を求めてきたら許可する
mkdir -p ~/ae-titles/outAfter Effectsをまだ入れていない場合は、料金や動作環境をAfter Effectsの導入前チェックで先に確かめてください。
疎通確認|スクリプトでコンポジションを1つ作る
最初に、コンポジションを1つ作るだけの短いスクリプトで、AEに命令が届くかを確かめます。addCompの引数は、名前・幅・高さ・ピクセル縦横比・長さ(秒)・フレームレートの順です。掲載したのは、筆者が動かしたスクリプトから取り消し用の処理などを省いた最小の形です。
// ping.jsx:コンポジションを1つ作り、文字を1行置く
var comp = app.project.items.addComp("cq-ping", 1080, 1920, 1, 5, 30);
comp.layers.addText("Hello from Claude Code");このファイルを、osascriptで起動中のAEに送ります。アプリ名はインストールしたバージョンに合わせて書き替えてください。
osascript -e 'tell application "Adobe After Effects 2026" to DoScriptFile "/Users/あなたのユーザー名/ae-titles/ping.jsx"'AEのプロジェクトパネルに「cq-ping」が増えていれば成功です。ただし、画面を見なくても確かめられる方法が必要なので、次の節の手順を使います。
結果の確かめ方|返り値は「0」なので.aepxに保存して見る
osascriptからスクリプトを送ると、筆者の環境では返り値が常に「0」で、スクリプトの結果はターミナルに返ってきませんでした。コンポジションの情報を文字列にして返すスクリプトを送っても、表示されたのは「0」だけです。返り値の仕様は公式資料に書かれていないので、「0」を成功の合図として扱うことはできません。
そこで、プロジェクトをXML形式の.aepxで保存し、その中身を検索して確かめます。.aepxはAfter Effectsのプロジェクトを XML で書いた形式です(Adobe公式ヘルプ「プロジェクト」)。
osascript -e "tell application \"Adobe After Effects 2026\" to DoScript \"app.project.save(new File('$HOME/ae-titles/ping.aepx'));\""
grep -c "cq-ping" ~/ae-titles/ping.aepx件数が1以上なら、コンポジションはできています。Claude Codeに作業させるときも「保存してgrepで確かめる」までを1セットにしておくと、うまくいったかどうかを会話の中で判定できます。
タイトルを量産する|表のデータから5本を作る
量産のコツは、変わる部分(文言と色)だけを配列に切り出し、組み立てる処理を1つの関数にまとめることです。配列の行を増やせば、本数もそのまま増えます。作例では、CodeQuest.workのツール5つの名前と配色を並べました。
| ツール名(大きい文字) | 小さい文字 | 背景色 | 差し色 |
|---|---|---|---|
| Liquid Glass | CSSジェネレーター | #1e2a5a | #a78bfa |
| CSSアニメーション | ギャラリー | #0f4c4c | #5eead4 |
| clip-path | ジェネレーター | #5a1e3a | #f472b6 |
| GSAPアニメーション | ギャラリー | #3b1e6a | #c4b5fd |
| 手書き風文字 | ジェネレーター | #4a2a10 | #ff6a2b |
スクリプトの全体は次のとおりです。OUT_DIRは自分の環境のパスに書き替えます。
// titles.jsx:表のデータからタイトルを5本作り、レンダーキューに積んで保存する
// 書き出し先のフォルダ(OUT_DIR)は先にターミナルで作っておく
(function () {
var OUT_DIR = "/Users/あなたのユーザー名/ae-titles/out";
var W = 1080, H = 1920, FPS = 30, DURATION = 3;
var MAX_TEXT_W = 940; // 文字がこの幅を超えたら縮める(左右70pxずつ余白)
var ITEMS = [
{ slug: "liquid-glass", title: "Liquid Glass", sub: "CSSジェネレーター", bg: "#1e2a5a", accent: "#a78bfa" },
{ slug: "animation-gallery", title: "CSSアニメーション", sub: "ギャラリー", bg: "#0f4c4c", accent: "#5eead4" },
{ slug: "clip-path", title: "clip-path", sub: "ジェネレーター", bg: "#5a1e3a", accent: "#f472b6" },
{ slug: "gsap-animation-gallery", title: "GSAPアニメーション", sub: "ギャラリー", bg: "#3b1e6a", accent: "#c4b5fd" },
{ slug: "handwriting-text-generator", title: "手書き風文字", sub: "ジェネレーター", bg: "#4a2a10", accent: "#ff6a2b" }
];
var NOTE = "無料・登録不要";
function rgb(hex) {
var n = parseInt(hex.replace("#", ""), 16);
return [((n >> 16) & 255) / 255, ((n >> 8) & 255) / 255, (n & 255) / 255];
}
// 中央揃えのテキストを置き、幅が収まらなければ文字を小さくする
function addText(comp, text, font, size, color, y) {
var layer = comp.layers.addText(text);
var prop = layer.property("Source Text");
var doc = prop.value;
doc.font = font;
doc.fontSize = size;
doc.fillColor = rgb(color);
doc.applyFill = true;
doc.justification = ParagraphJustification.CENTER_JUSTIFY;
prop.setValue(doc);
var w = layer.sourceRectAtTime(0, false).width;
if (w > MAX_TEXT_W) {
doc.fontSize = Math.floor(size * MAX_TEXT_W / w);
prop.setValue(doc);
}
layer.property("Position").setValue([W / 2, y]);
return layer;
}
// start秒から0.6秒かけて、下から80px上がりながらフェードインし、ゆっくり止まる
function riseIn(layer, start) {
var pos = layer.property("Position");
var to = pos.value;
pos.setValueAtTime(start, [to[0], to[1] + 80]);
pos.setValueAtTime(start + 0.6, to);
var opacity = layer.property("Opacity");
opacity.setValueAtTime(start, 0);
opacity.setValueAtTime(start + 0.6, 100);
var linear = new KeyframeEase(0, 33);
var slowStop = new KeyframeEase(0, 85);
pos.setTemporalEaseAtKey(1, [linear], [linear]);
pos.setTemporalEaseAtKey(2, [slowStop], [slowStop]);
opacity.setTemporalEaseAtKey(2, [slowStop], [slowStop]);
}
function build(item) {
var comp = app.project.items.addComp("title-" + item.slug, W, H, 1, DURATION, FPS);
comp.layers.addSolid(rgb(item.bg), "bg", W, H, 1, DURATION);
riseIn(addText(comp, item.title, "HiraginoSans-W8", 120, "#ffffff", 900), 0);
riseIn(addText(comp, item.sub, "HiraginoSans-W6", 72, item.accent, 1020), 0.3);
riseIn(addText(comp, NOTE, "HiraginoSans-W4", 48, "#cbd5e1", 1120), 0.3);
var rq = app.project.renderQueue.items.add(comp);
rq.outputModule(1).file = new File(OUT_DIR + "/title-" + item.slug + ".mp4");
}
// 作業中のプロジェクトに未保存の変更があれば、何もせずに終わる(変更を失わないため)
if (app.project.dirty) return;
var prev = app.project.file;
app.project.close(CloseOptions.DO_NOT_SAVE_CHANGES);
app.newProject();
app.beginUndoGroup("cq-titles");
for (var i = 0; i < ITEMS.length; i++) build(ITEMS[i]);
app.endUndoGroup();
app.project.save(new File(OUT_DIR + "/titles.aepx"));
// 作業前に開いていたプロジェクトに戻す
app.project.close(CloseOptions.DO_NOT_SAVE_CHANGES);
if (prev) app.open(prev);
})();このスクリプトは、空のプロジェクトで5本を組み立てて保存したあと、作業前に開いていたプロジェクトに戻します。開いているプロジェクトに未保存の変更があるときは、変更を失わないよう何もせずに終わります。スクリプトを流しても何も起きないときは、AEで保存してからもう一度流してください。送り方は疎通確認と同じです。
osascript -e 'tell application "Adobe After Effects 2026" to DoScriptFile "/Users/あなたのユーザー名/ae-titles/titles.jsx"'動きをつける|キーフレームとイーズ
動きは、位置と不透明度に開始と終了の2つのキーフレームを打ち、到着側に強いイーズをかけて「ゆっくり止まる」動きにしています。ツール名は0秒から、下の2行は0.3秒遅れて、0.6秒かけて80px上がりながら現れます。
| 時間 | 動き |
|---|---|
| 0〜0.6秒 | ツール名が下から80px上がりながらフェードインし、ゆっくり止まる |
| 0.3〜0.9秒 | 小さい文字と「無料・登録不要」が同じ動きで少し遅れて出る |
| 0.9〜3秒 | 止まったまま表示する |
イーズはKeyframeEase(速度・影響)で指定します。影響(influence)は0.1〜100の値で、到着側を85にすると、終わり際に大きく減速します。setTemporalEaseAtKeyに渡す配列の要素数はプロパティの種類で決まります(Scripting Guide「Property」)。作例の位置と不透明度は、どちらも要素1つの配列で動きました。
日本語の文字|フォントを名前で指定し、長い文字は自動で縮める
日本語のテキストは、フォントをPostScript名で明示しておくと、環境によって書体が変わったり文字化けしたりするのを防げます。作例ではmacOSに入っているヒラギノ角ゴを、太さ違いで3種類使っています。
| 行 | フォント(PostScript名) | 大きさ |
|---|---|---|
| ツール名 | HiraginoSans-W8 | 120px(収まらなければ縮める) |
| 小さい文字 | HiraginoSans-W6 | 72px |
| 無料・登録不要 | HiraginoSans-W4 | 48px |
「GSAPアニメーション」のように長い名前は、120pxのままだと画面の幅からはみ出します。そこで、文字を置いたあとにsourceRectAtTimeで実際の幅を測り、940pxを超えていれば比率で文字を小さくしています。文言を差し替えるたびに大きさを手で調整する必要がなくなるので、量産では効く一手です。
aerenderで一括書き出し|5本を約15秒
レンダーキューに積んでプロジェクトを保存しておけば、aerenderにプロジェクトを渡すだけで、積んだ項目をまとめて書き出せます。Adobe公式ヘルプによると、aerenderで-compを指定しない場合は、レンダーキューの全項目をそのままレンダリングします(自動レンダリングとネットワークレンダリング)。
"/Applications/Adobe After Effects 2026/aerender" -project ~/ae-titles/out/titles.aepx筆者の環境では、AEの起動を含めて約15秒で、1080×1920・3秒のH.264(.mp4)が5本できました。書き出し先は、スクリプトで出力モジュールに指定したパスです。
できたタイトルは、ショート動画の冒頭に使う想定です。ナレーションを自動で付ける工程はVOICEVOXでナレーションを自動で入れる手順で、できた動画をYouTubeに上げる工程はYouTube Data APIで動画をアップロードする手順で解説しています。
After EffectsはレンダーキューからH.264の.mp4を直接書き出せ、新規インストール時の出力モジュールの既定テンプレートはH.264です(Adobe公式ヘルプ「H.264の書き出し」)。テンプレートの既定を変えている環境では形式が変わることがあるので、確実にしたい場合は-OMtemplateでテンプレート名を指定してください(このオプションは-compか-rqindexと組み合わせて使います)。
1本だけ書き出す場合
コンポジションを1つだけ書き出すときは、-compと-outputで名前と出力先を指定します。疎通確認で作ったcq-pingは、次のコマンドで5秒のmp4になりました。
"/Applications/Adobe After Effects 2026/aerender" -project ~/ae-titles/ping.aepx -comp "cq-ping" -output ~/ae-titles/ping.mp4-compを付けずにレンダーキュー全体を書き出す場合、-outputなどの指定は無視されます。複数本をまとめて書き出すときは、出力先をスクリプト側の出力モジュールで決めておくのが確実です。
つまずいた点と対処
実際に動かしてつまずいた点を、症状から引けるように表にしました。後半の3行は、同じ仕組みでショート動画用のロゴの部品を作ったときに起きたものです。
| 症状 | 原因 | 対処 |
|---|---|---|
| 「行 ○○ のスクリプトを実行できません。アクセスが拒否されました」というダイアログで止まる | スクリプトからフォルダを作ろうとした(new Folder().create()) | フォルダはターミナルで先に作る。または環境設定で書き込みを許可する |
| osascriptの結果が「0」しか出ない | DoScriptFile・DoScriptの返り値が結果を返さない(筆者の環境) | .aepxに保存してgrepで確かめる |
| 日本語の書体が意図と違う | フォントを指定していない | TextDocument.font にPostScript名を入れる |
| 長いツール名が画面からはみ出す | 文字の大きさが固定 | sourceRectAtTime で幅を測って縮める |
| -outputを付けたのに出力先が変わらない | -compなしではレンダーキュー全体が対象になり、-outputが無視される | 出力先はスクリプトで出力モジュールに指定する |
| 親子付けしたのに、親の拡大率が子に効かない | layer.parent で親を付けると、見た目を保つように子の拡大率が自動で補正される | setParentWithJump(親) で付ける。子の値をキーフレームで打っている場合は上書きされるので表に出ない |
| アルファ付きのTIFF連番をPNGにすると、ぼかした光のまわりが暗くにごる | 書き出したTIFFのアルファが乗算済み(premultiplied)になっている | ffmpegで -vf unpremultiply=inplace=1 を掛けて戻す。出力テンプレートの名前は outputModule(1).templates で一覧できる |
| 図形レイヤーにガウスぼかしを掛けると、光が四角く切れる | 図形の範囲のあたりでぼかしが切れる(「エッジピクセルを繰り返す」のオン・オフでは直らなかった) | 平面レイヤーに円形のマスクを付け、マスクのぼかしで光を作る |
ファイル書き込みの安全設定
After Effectsは、既定ではスクリプトからのファイル書き込みとネットワーク通信を許可していません(Adobe公式ヘルプ「スクリプト」)。許可するには、[After Effects]→[設定]→[スクリプトとエクスプレッション]の「スクリプトによるファイルへの書き込みとネットワークへのアクセスを許可」をオンにします(Adobe公式ヘルプ「環境設定」、2026年10月更新)。
筆者の環境では、この設定がオフのままでもエラーになったのはフォルダの作成だけで、プロジェクトの保存(app.project.save)と出力モジュールの出力先の指定は通りました。設定を広げずに済むよう、フォルダの作成のようなファイル操作はターミナル側に寄せています。
Photoshopで同じことをする場合との違い
PhotoshopもAfter Effectsも、osascriptからExtendScriptを送って動かす点は同じですが、命令の名前と返り値の扱いが違います。
| Photoshop | After Effects | |
|---|---|---|
| AppleScriptの命令 | do javascript | DoScript/DoScriptFile |
| スクリプトの結果 | 最後に評価した値がターミナルに返る | 筆者の環境では常に「0」 |
| 結果の確かめ方 | 返り値をそのまま読む | プロジェクトを.aepxで保存して検索する |
| 画面なしでの書き出し | スクリプト内で保存する | 付属のaerenderで書き出す |
Photoshop版の手順はClaudeでPhotoshopを操作する方法で解説しています。なお、AdobeがClaude向けに出している公式コネクタ(Adobe for creativity)は、2026年9月時点の発表で対象に挙がっているのがPhotoshop・Illustrator・Premiere・Acrobatなどで、After Effectsの名前はありません(Adobe公式ブログ)。After Effectsを動かすなら、現時点ではこの記事のようにスクリプトを送る方法になります。
よくある質問
Q. Claude CodeでAfter Effectsを操作できますか?
できます。Claude CodeにExtendScriptのスクリプトを書かせ、osascriptで起動中のAfter Effectsに DoScriptFile で送ると、コンポジションの作成から文字や動きの設定、レンダーキューへの追加まで実行できます。
Q. After Effectsのスクリプトは何の言語で書きますか?
JavaScriptを拡張したExtendScriptで書き、拡張子は.jsxです。After Effects向けのUXPはAdobeの開発者サイトでベータとして公開されていますが、2026年10月時点でExtendScriptの廃止の告知は見当たりません。
Q. aerenderとは何ですか?
After Effectsに付属している、画面を開かずにコンポジションを書き出すためのコマンドラインツールです。プロジェクトを渡すと、レンダーキューに積んだ項目をまとめて書き出せます。
Q. スクリプトで「アクセスが拒否されました」と出るのはなぜですか?
After Effectsは既定でスクリプトからのファイル書き込みを許可していないためです。環境設定の[スクリプトとエクスプレッション]で許可するか、フォルダの作成などのファイル操作をターミナル側で先に済ませておきます。
Q. Adobe公式のClaude用コネクタでAfter Effectsは使えますか?
2026年9月時点のAdobeの発表では、コネクタの対象にAfter Effectsの名前はありません。After Effectsを動かすには、ExtendScriptをosascriptで送る方法を使います。
Q. osascriptから送ったスクリプトの結果はどう確かめますか?
筆者の環境では返り値が常に「0」だったため、プロジェクトをXML形式の.aepxで保存し、コンポジション名などを検索して確かめました。
