内容
<div align="center">
<img src="docs/hero.png" alt="aftr" width="880" />
# aftr
### After Effects 的 Puppeteer
使用 Claude Code 和 After Effects 生成可用于生产的视频。
[](LICENSE)

[](https://www.npmjs.com/package/aftr-studio)
[](https://pypi.org/project/aftr-studio/)
[](https://github.com/Arman-Luthra/aftr/pkgs/container/aftr)
</div>
节点控制器通过 WebSocket 向 AE 中的 CEP 面板发送 JSON 命令,面板运行这些命令为 ExtendScript 并返回 JSON。在此基础上,构建了一个自主的、基于规范的管道,用于构建剪辑并自我纠正,通过渲染、审查和修订。所有操作都通过套接字以编程方式驱动,无需手动进行 After Effects 操作。
<div align="center">
<img src="docs/pals-title-demo.gif" alt="aftr demo: a title sequence built and rendered entirely through the bridge" width="880" />
*一个标题序列完全通过 aftr 构建和渲染。无需手动 After Effects 操作。<br>为 [tilion / fortress](https://github.com/tiliondev/fortress) 制作的视频。<br>[观看完整演示](https://www.youtube.com/watch?v=QkjTwlqPhNc)*
</div>
---
## 启动 MCP 服务器
使用两个命令将 aftr 集成到 Claude Code 中。启动控制器(它提供 MCP 端点),然后将 Claude Code 指向它。
```bash
npx aftr-studio controller # 无需安装,需要 Node 18+
pip install aftr-studio && aftr controller # pip
docker run -p 8787:8787 ghcr.io/arman-luthra/aftr # docker
```
```bash
claude mcp add --transport http aftr http://127.0.0.1:8787/mcp
```
打开 After Effects 和面板(窗口 > 扩展 > aftr;从克隆仓库中部署它,运行 `npm run deploy:panel`)。然后用自然语言问 Claude Code:
> 创建一个 1080p 5 秒的合成,添加一个标题 "LAUNCH",后面有火,动画模糊渐变,然后渲染成 mp4。
Claude Code 将每个命令视为一个工具:它首先调用 `ae_status`,列出集合使用 `ae_list_commands`,并通过 `ae_command` 运行任何命令。更喜欢 stdio 服务器?使用 `claude mcp add aftr -- npx -y aftr-studio mcp`(同时保持控制器运行)。
---
## 安装
| 方法 | 命令 |
|---|---|
| npm(全局 CLI) | `npm install -g aftr-studio`,然后 `aftr controller` |
| npx(无需安装) | `npx aftr-studio controller` |
| pip(Python 启动器) | `pip install aftr-studio`,然后 `aftr controller`(需要 Node 18+) |
| Docker | `docker run --rm -p 8787:8787 ghcr.io/arman-luthra/aftr` |
| 从源代码 | 克隆此仓库(以下) |
npm、npx 和 Docker 路径运行控制器、MCP 服务器(`aftr mcp`)和模拟器(`aftr sim`)。在克隆仓库中,将 CEP 面板部署到 After Effects 中(`npm run deploy:panel`),因为它自我签名并安装扩展程序。pip 包是一个薄的启动器,通过 `npx` 转发到 npm CLI。
---
## 60 秒快速入门
```bash
git clone https://github.com/Arman-Luthra/aftr.git
cd aftr
npm install
# 1) 验证它是否健康,无需 After Effects(无头模拟器 + 测试)
npm run build:jsx && npm test
# 2) 将面板安装到 AE 中(自我签名 + 部署在 Windows 和 macOS 上)
npm run deploy:panel # 然后退出并重启 AE,窗口 > 扩展 > aftr
# 3) 启动桥梁 + 打开 UI
npm run controller # http://127.0.0.1:8787
```
然后通过 UI、REST、WebSocket 或作为库驱动它:
```bash
node examples/flaming-title.mjs "ON FIRE"
```
需要 After Effects 2024 至 2026、Node 18+ 和 `ffmpeg` 在您的 `PATH` 上。完整的 Windows 和 macOS 设置在 [第 4 节](#4-完整设置与真实的After Effects)。
---
## 功能
| 能力 | 它做什么 |
|---|---|
| ~100 命令 | 合成、图层、关键帧和缓动、表达式、效果(按 matchName 或显示名称,包括深层嵌套参数和第三方插件)、蒙版、图层样式、文本动画器、渲染。 |
| 发现 | `listFonts`、`listInstalledEffects`(返回 matchNames)、`findEffectMatchName`、`listPlugins`、`getEnvironment`。查找已安装的内容,而不是猜测。 |
| 一键 VFX | `fireEffect`、`smokeEffect`、`glitchEffect`、`neonGlow`、`cinematicGrade` 和友好的 `applyLumetri` 分级。 |
| 文本动画 | 四个 Animate 面板预设(`wordReveal`、`charScale`、`bunchRotate`、`blurFade`)以及一个完整的范围选择器构建器。 |
| 自主管道 | 声明性片段规格实现、渲染、获取视觉审查、采取结构化增量、重新渲染,直到通过,然后使用 FFmpeg 连接。 |
| MCP 服务器 | 从 Claude Desktop、Claude Code 或任何 MCP 客户端驱动 AE。每个命令都是一个工具(`npm run mcp`)。 |
| 快速和批处理 | `batch` 在一次往返中运行 N 个编辑,并在一次撤销中(小于 200 毫秒完成 20 个操作)。非阻塞 `aerender` 流式传输进度事件,具有并行渲染引擎。 |
| 无需 AE 可测试 | 无头模拟器在模拟 DOM 上运行真实的 JSX。96 个测试 + e2e,CI 在 Node 18、20 和 22 上。 |
| 跨平台 | Windows 和 macOS,一键签名和部署。 |
---
## 工作原理
```
┌──────────────────────────────────────────────┐
│ 控制器(Node + ws + Express + web UI) │ <- 您 / UI / 代理驱动此
│ • 主持 WebSocket 服务器(面板 + 代理) │
│ • REST 接口 + 交互式 UI │
│ • HLD 协调器(代理循环) │
└───────────────┬────────────────────────────────┘
│ WebSocket(JSON 请求/响应/事件信封)
┌───────────────▼────────────────────────────────┐
│ CEP 面板(在 After Effects 中) │ ┐
│ • WebSocket 客户端,拨打控制器 │ │ 构建一次,
│ • 将命令路由到 JSX 调度层 │ │ 适用于 Win & Mac
│ • 启动 aerender 进行非阻塞渲染 │ │
└───────────────┬────────────────────────────────┘ │
│ evalScript(字符串 in / JSON 字符串 out)
┌───────────────▼────────────────────────────────┐ │
│ JSX 命令层(host.jsx + commands/*.jsx) │ │
│ • dispatch(command, paramsJson) -> JSON │ │
│ • ~90 命令:图层、关键帧、效果、 │ │
│ 文本动画器、蒙版、VFX 预设、渲染 │ │
└───────────────┬────────────────────────────────┘ ┘
│ AE 脚本 DOM(app.project, comps, layers)
┌───────────────▼────────────────────────────────┐
│ After Effects │
└──────────────────────────────────────────────────┘
```
---
## 目录
1. [您可以做的事情](#1-您可以做的事情)
2. [先决条件](#2-先决条件)
3. [快速开始,无需 AE(模拟器)](#3-快速开始,无需AE(模拟器))
4. [使用真实的 After Effects 完成设置](#4-使用真实的After Effects完成设置)
- [Windows](#41-windows)
- [macOS](#42-macos)
5. [运行顺序](#5-运行顺序)
6. [驱动桥梁](#6-驱动桥梁)
7. [命令词汇](#7-命令词汇)
8. [VFX 和文本预设](#8-VFX-和文本预设)
9. [协调器(自主管道)](#9-协调器(自主管道))
10. [配置](#10-配置)
11. [开发工作流(热重载 + 签名)](#11-开发工作流(热重载+签名))
12. [架构](#12-架构)
13. [项目结构](#13-项目结构)
14. [测试](#14-测试)
15. [故障排除](#15-故障排除)
16. [跨平台说明](#16-跨平台说明)
---
## 1. 您可以做的事情
通过代码控制 AE:创建合成和图层(固体、文本、形状、空对象、摄像机、灯光、调整、素材),设置任何变换或效果属性,添加关键帧和缓动,编写表达式,并父级、修剪、移动或复制图层,所有操作均通过套接字。
通过 matchName 添加任意效果并驱动其参数,甚至是深层嵌套的参数,通过关键帧或表达式进行动画处理。
使用四种现成的 Animate 面板样式(`wordReveal`、`charScale`、`bunchRotate`、`blurFade`)以及完整的文本动画器构建器(基于、形状、缓和高到低、关键帧偏移和启动)来动画文本。
使用一键式 VFX 预设:`fireEffect`(逼真的火)、`smokeEffect`、`glitchEffect`、`neonGlow`、`cinematicGrade` 和友好的 `applyLumetri` 分级。
批处理和内省:以一次往返运行多个编辑并撤销一次(`batch`),然后读回图层或合成状态(`getLayerDetails`、`getProperty`)。
无阻塞渲染:`render` 启动 `aerender` 并流式传输 `progress` 和 `renderComplete` 事件,使 AE 保持响应。
运行自主管道:用 JSON 片段描述视频,协调器实现每个片段(`applySpec`),渲染其范围,视觉审查,应用结构化规范增量,如果不正确则重新渲染,直到通过,然后使用 FFmpeg 连接。
---
## 2. 先决条件
| 要求 | 说明 |
|---|---|
| Adobe After Effects | 2024(24.x)、2025(25.x)或 2026(26.x)。已许可并激活。请记录您的确切版本。 |
| Node.js 18+ | 控制器、模拟器和构建脚本都是 Node(ESM)。 |
| FFmpeg | 需要由协调器的视觉审查者和最终连接。`ffmpeg` 必须在您的 `PATH` 上。 |
| Git | 用于克隆和推送。 |
检查它们:
```bash
node --version # v18+ (推荐 v22)
ffmpeg -version # 任意近期版本
```
CEP 版本映射到 AE 版本:AE 2024 使用 CEP 11(`CSXS.11`);AE 2025 和 2026 使用 CEP 12(`CSXS.12`)。面板清单针对 `[24.0,99.9]` 和低要求的运行时,因此它们都加载。
---
## 3. 快速开始,无需 AE(模拟器)
您可以在没有 After Effects 的情况下,使用无头模拟器验证整个架构(控制器到桥梁协议、命令调度、渲染管道)。它是 Node 进程,与真实面板使用相同的 WebSocket 协议,并运行真实的捆绑 JSX 以对抗模拟 AE DOM。
```bash
git clone https://github.com/Arman-Luthra/aftr.git
cd aftr
npm install
# 构建 JSX 包一次
npm run build:jsx
# 运行完整的无头测试套件(单元 + 模拟器 + JSX 调度)
npm test
# 端到端:控制器 + 模拟器往返,包括渲染事件
npm run e2e
```
或交互式运行:
```bash
# 终端 1:控制器(WS 服务器 + REST + UI,位于 http://127.0.0.1:8787)
npm run controller
# 终端 2:模拟器(假装成 AE 面板)
npm run sim
# 现在打开 http://127.0.0.1:8787 并点击命令,或:
curl -X POST http://127.0.0.1:8787/command \
-H "Content-Type: application/json" \
-d '{"command":"createComp","params":{"name":"Main","width":1920,"height":1080}}'
```
这是如何验证 `M0`、`M3` 和 `M4`(架构、往返、词汇表)并使用零 AE 验证。真实面板为 `M1`、`M2` 和 `M5` 保留不变。
---
## 4. 使用真实的 After Effects 完成设置
面板是 CEP 扩展程序。在现代 AE(2025+),旧的启用未签名面板的技巧 `PlayerDebugMode` 不可靠:AE 忽略它并拒绝未签名的扩展程序,提示“签名验证失败”。可靠且受支持的路径是自我签名并安装面板,该仓库通过一个命令自动执行此操作:
```bash
npm run deploy:panel
```
`deploy:panel` 构建 JSX 包,创建自签名开发证书(缓存在 `dist/`),将 `panel/` 签名到 `.zxp`,并将签名扩展程序解压到您的每个用户 CEP 扩展程序文件夹中。
它适用于 Windows 和 macOS([`zxp-sign-cmd`](https://www.npmjs.com/package/zxp-sign-cmd)工具提供适用于两者的签名者)。运行后,请完全退出并重新启动 After Effects,然后打开窗口 > 扩展 > aftr。
签名扩展程序是一个快照。编辑面板源代码后,请再次运行 `npm run deploy:panel`(并重新打开 AE)使其永久生效,或者使用热重载开发循环(参见 [第 11 节](#11-开发工作流(热重载+签名))进行迭代。
### 4.1 Windows
```powershell
# 从仓库根目录
npm install
npm run deploy:panel
# 然后退出 AE,重新启动,窗口 > 扩展 > aftr
```
已签名的面板安装到:
```
%APPDATA%\Adobe\CEP\extensions\com.ae-bridge.panel
```
您也可以设置远程 DevTools,但不一定需要:
`reg add HKCU\Software\Adobe\CSXS.12 /v PlayerDebugMode /t REG_SZ /d 1 /f`(使用 `CSXS.11` 进行 AE 2024)
### 4.2 macOS
```bash
# 从仓库根目录
npm install
npm run deploy:panel
# 然后退出 AE,重新启动,窗口 > 扩展 > aftr
```
已签名的面板安装到:
```
~/Library/Application Support/Adobe/CEP/extensions/com.ae-bridge.panel
```
macOS 特定:
- 如果 Gatekeeper 隔离了签名二进制文件,请一次性清除它: `xattr -dr com.apple.quarantine node_modules/zxp-sign-cmd`(路径可能不同)。
- `aerender` 位于应用程序根目录:`/Applications/Adobe After Effects <year>/aerender`. 控制器和面板自动检测它。如果您的安装到 `aerender`. 控制器和面板自动检测它。 如果您的安装位置非常规,请设置 `AE_BRIDGE_AERENDER`(参见 [第 10 节](#10-配置))。
- 可选的调试模式:`defaults write com.adobe.CSXS.12 PlayerDebugMode 1`(使用 `CSXS.11` 进行 AE 2024)。签名后不需要。
---
## 5. 运行顺序
1. 启动控制器(在固定端口上托管 WS 服务器、REST 和 UI):
```bash
npm run controller # http://127.0.0.1:8787
```
2. 启动 After Effects。
3. 打开面板:窗口 > 扩展 > aftr。它会拨号控制器,状态点变为绿色(`AE v26.x`)。
4. 打开位于 <http://127.0.0.1:8787> 的 UI:按钮对应每个命令,实时事件日志和 JSON 响应查看器。
要运行自主演示(参见 [第 9 节](#9-协调器(自主管道))):`npm run orchestrate`,`npm run orchestrate:fire` 或 `npm run showreel`.
---
## 6. 驱动桥梁
有几种等效的方法发送命令,都使用相同的 JSON 信封。
REST(一次性):
```bash
curl -X POST http://127.0.0.1:8787/command \
-H "Content-Type: application/json" \
-d '{"command":"createComp","params":{"name":"Hello","width":1920,"height":1080,"duration":6,"frameRate":30}}'
```
WebSocket(编程,适用于代理):连接到 `ws://127.0.0.1:8787/agent`,发送
`{"id":"1","type":"command","command":"ping","params":{}}`,并接收
`{"type":"result","id":"1","ok":true,"result":{...}}`。面板事件(就绪、日志、进度、渲染完成)广播给每个连接的代理。
Web UI 在 `/` 处渲染一个命令控件(带有 JSON 参数框的富文本参数),实时日志和最后一个响应。
作为库,捆绑的代理客户端使脚本编写变得简单。参见 `examples/` 目录:
```bash
node examples/flaming-title.mjs "ON FIRE" # 使用编程方式构建一个火焰标题
node examples/animated-text.mjs # 四个文本动画预设合集
```
```js
import { AgentClient } from './controller/src/orchestrator/agentClient.js';
const ae = new AgentClient();
await ae.connect();
const { compId } = await ae.must('createComp', { name: 'Hi', width: 1080, height: 1080, duration: 5, frameRate: 30 });
await ae.must('fireEffect', { compId });
await ae.must('addTextLayer', { compId, text: 'ON FIRE', fontSize: 150, justification: 2, position: [540, 300], name: 't' });
await ae.must('applyTextPreset', { compId, layer: 't', preset: 'blurFade' });
```
### 作为 MCP 服务器
通过任何 MCP 客户端(Claude Desktop、Claude Code 等)驱动 After Effects。MCP 服务器(`controller/src/mcp.js`)是一个薄的 stdio 适配器,它将每个工具调用转发到正在运行的控制器,因此 AE 面板、控制器和您的项目表现完全相同;客户端只是获取工具。
```bash
# 1)启动桥梁并打开 AE 面板(窗口 > 扩展 > aftr)
npm run controller
# 2a) Claude Code:注册 MCP 服务器
claude mcp add aftr -- node /ABSOLUTE/PATH/aftr/controller/src/mcp.js
```
```jsonc
// 2b) Claude Desktop:claude_desktop_config.json
{
"mcpServers": {
"aftr": {
"command": "node",
"args": ["/ABSOLUTE/PATH/aftr/controller/src/mcp.js"],
"env": { "AE_BRIDGE_URL": "http://127.0.0.1:8787", "AE_MCP_TOOLS": "core" }
}
}
}
```
客户端看到:
- `ae_status`: AE 是否已连接?(如果任何操作返回 `NO_PANEL`,请调用此操作)
- `ae_list_commands`: 每个命令及其描述
- `ae_command`: 运行任何命令(`{ command, params }`),通用逃生舱
- `ae_createComp`、`ae_addTextLayer`、`ae_deepGlow`、`ae_shadowStudio`、`ae_applySpec`、`ae_render` 等精选的每个命令工具
| 环境变量 | 默认值 | 含义 |
|---|---|---|
| `AE_BRIDGE_URL` | `http://127.0.0.1:8787` | 转发到的控制器 |
| `AE_MCP_TOOLS` | `core` | `core` 是精选工具集加上元工具;`all` 公开每个注册的命令作为独立工具 |
| `AE_BRIDGE_ALLOW_DEV` | (未设置) | `1` 以显示仅限开发的命令 |
MCP 服务器是控制器的客户端,因此运行 `npm run controller`(而不是第二个)以避免端口冲突;MCP 进程只需要访问它。
### 主机用于他人:视频输入,渲染,视频输出
在您的机器上运行桥梁,让其他人发送视频,让您的 AE 渲染它,并通过 HTTP 或 MCP 下载结果。
```bash
# 1)启动桥梁并打开 AE 面板(窗口 > 扩展 > aftr)
npm run controller
# 2a) Claude Code:注册 MCP 服务器
claude mcp add aftr -- node /ABSOLUTE/PATH/aftr/controller/src/mcp.js
```
# 绑定到您的网络并需要一个共享密钥(在公开之前请同时执行这两个操作)
AE_BRIDGE_HOST=0.0.0.0 AE_BRIDGE_TOKEN=your-secret npm run controller
| 路由 | 用途 |
|---|---|
| `GET /studio` | 一个小型浏览器页面:选择文件,上传,查看和下载输出 |
| `POST /media/upload?name=clip.mp4` | 发送视频(原始正文),返回 `{ id, file, path, url }`(在主机上落地) |
| `POST /media/fetch` `{ url \| dataBase64, name? }` | 主机通过URL拉取视频(最适合远程调用者) |
| `GET /media/list` | 列出传入和渲染的文件,每个文件都有一个下载URL |
| `GET /media/file/<name>` | 下载视频 |
| `POST /media/render` `{ compId, name? }` | 渲染,转码为H.264 .mp4,返回 `{ downloadUrl }`。等待最多 `AE_BRIDGE_RENDER_WAIT_MS`(默认为150秒);较长的渲染返回 `{ pending, jobId }` |
| `GET /media/render/<jobId>` | 轮询长渲染,完成后返回 `{ status, downloadUrl }` |
渲染被跟踪为作业,因此长渲染永远不会超出MCP客户端的~180秒调用超时,并且每个输出都转码为通用可播放的H.264 `.mp4`(通过ffmpeg,自动检测或使用 `AE_BRIDGE_FFMPEG`设置)。
```bash
# 发送剪辑,然后(在从剪辑构建合成后)渲染并获取结果:
curl -X POST --data-binary @in.mp4 -H "Content-Type: application/octet-stream" \
"http://HOST:8787/media/upload?name=in.mp4&token=your-secret"
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer your-secret" \
-d '{"compId":3,"name":"out.mp4"}' http://HOST:8787/media/render
# 返回 { "downloadUrl": "/media/file/out.mp4" }
```
使用隧道公开它到互联网(无需路由器配置):
```bash
cloudflared tunnel --url http://localhost:8787 # 或: ngrok http 8787
```
远程MCP有两种工作方式。控制器还通过HTTP在 `POST /mcp`(Streamable HTTP)上提供MCP,因此隧道URL是一个可插拔的MCP链接:
```bash
# (a)直接HTTP MCP:将URL粘贴到任何MCP客户端
claude mcp add --transport http aftr https://your-tunnel.example/mcp \
--header "Authorization: Bearer your-secret"
```
```jsonc
// (b)stdio适配器指向隧道
{ "mcpServers": { "aftr": {
"command": "node", "args": ["/path/aftr/controller/src/mcp.js"],
"env": { "AE_BRIDGE_URL": "https://your-tunnel.example", "AE_BRIDGE_TOKEN": "your-secret" }
}}}
```
远程调用者也可以使用视频工具:`ae_upload_video`(`{ url }`,主机获取它),`ae_media_info`,`ae_media_list`,`ae_render_and_download`(`{ compId }`,返回下载URL或 `{ pending, jobId }`表示长时间渲染),以及 `ae_render_result`(`{ jobId }`用于轮询)。
这公开了对After Effects的编程控制。始终在绑定到 `0.0.0.0` 或隧道之前设置 `AE_BRIDGE_TOKEN`。设置令牌后, `/command`,`/media/*`,`/mcp`,以及 `/bridge` 和 `/agent` WebSocket都需要它(本地AE面板除外,作为直接环路连接豁免)。仅与您信任的人共享令牌。
onboarding团队成员?将[docs/TEAM-GUIDE.md](docs/TEAM-GUIDE.md)交给他们,这是一份无需仓库连接指南,包含工具目录和复制粘贴配方(包括通过两次调用渲染视频的URL)。
### 消息合约
```jsonc
// 请求(控制器到面板)
{ "id": "uuid", "type": "command", "command": "createComp", "params": { ... } }
// 结果(面板到控制器)
{ "id": "uuid", "type": "result", "ok": true, "result": { ... } }
{ "id": "uuid", "type": "result", "ok": false, "error": "width must be a positive integer" }
// 事件(面板到控制器,非请求)
{ "type": "event", "event": "ready", "data": { "ae": "26.3", "project": "Untitled" } }
{ "type": "event", "event": "progress", "data": { "jobId": "r1", "percent": 42 } }
```
---
## 7. 命令词汇表
~90个命令,按组分类。 在 `GET /api/commands` 上实时列出它们。 亮点:
项目和合成:
`ping`,`getProjectInfo`,`getAppInfo`,`listComps`,`createComp`,`setCompSettings`,`addCompMarker`,`duplicateComp`,`setActiveComp`,`setCompTime`,`getCompTime`,`setWorkArea`,`clearComp`,`createFolder`,`moveToFolder`,`renameItem`,`deleteItem`,`setProxy`,`getProjectItems`,`saveProject`。
图层:
`addSolid`,`addTextLayer`,`addNull`,`addAdjustmentLayer`,`addCamera`,`addLight`,`addShape`,`addPathShape`(自定义贝塞尔曲线路径),`addFootageLayer`,`setLayerProperty`,`setParent`,`trimLayer`,`moveLayer`,`duplicateLayer`,`deleteLayer`,`getLayers`,`setBlendMode`,`setTrackMatte`,`setLayerFlag`,`addLayerMarker`,`setTimeStretch`,`enableTimeRemap`,`replaceSource`,`alignLayer`,`sequenceLayers`。
动画:
`setKeyframe`,`setKeyframes`(批量+缓动),`setEase`,`setInterpolation`,`removeKeyframes`,`setExpression`,`removeExpression`,`enableExpression`。
特效:
`addEffect`(按matchName),`setEffectParam`,`listEffects`,`addExpressionControl`。 任何嵌套的特效参数都可以通过 `setLayerProperty` 或 `setExpression` 可达,例如 `["ADBE Effect Parade","FN","ADBE Fractal Noise-0012"]`。
文本:
`setTextDocument`,`addTextAnimator`(完整的Animate面板范围选择器),`applyTextPreset`。
遮罩和样式:
`addMask`,`addRectMask`,`setMaskProperty`,`addLayerStyle`,`setLayerStyleEnabled`。
素材和渲染:
`importFootage`,`compFromFootage`,`render`(非阻塞aerender,作用域 `startFrame` 和 `endFrame`),`addToRenderQueue`,`listRenderQueue`,`setOutputModule`,`clearRenderQueue`。
分级和VFX预设:
`applyLumetri`,`lumetriParams`,`cinematicGrade`,`fireEffect`,`smokeEffect`,`glitchEffect`,`neonGlow`。
发现(只读):
`listFonts`(postScriptName权威,派生字体和样式),`listInstalledEffects`(尽力而为,探测已知集,返回 `{name, matchName}`),`findEffectMatchName`(解析显示名称为matchName),`listPlugins`(尽力而为,扫描 `.aex` 和 `.plugin` 安装目录),`getEnvironment`(AE版本,操作系统,ExtendScript,字体数,内存,GPU)。 使用这些来发现 `addEffect` 所需的matchNames。
应用和编排:
`executeMenuCommand`(按名称或ID运行任何AE菜单项),`findMenuCommand`,`undo`,`redo`,`purge`,`getSelection`,`keystroke`(尽力而为的操作系统键),`batch`,`applySpec`,`removeLayersByPrefix`。
`runJSX`(原始ExtendScript)作为开发人员专属的逃生通道, gated behind `AE_BRIDGE_ALLOW_DEV=1`.
---
## 8. VFX和文本预设
逼真的火焰,一次调用:
```json
{ "command": "fireEffect", "params": { "compId": 1, "center": [960,660], "size": 1.0, "embers": true } }
```
构建动画分形噪声火焰加湍流位移,CC Toner色彩,上升的余烬,环境光辉和发光调整,遮罩成火焰形状。
其他预设:
```json
{ "command": "smokeEffect", "params": { "compId": 1, "size": 1.1, "color": [0.7,0.7,0.8] } }
{ "command": "glitchEffect", "params": { "compId": 1, "layer": "title", "amount": 50, "shake": 18 } }
{ "command": "neonGlow", "params": { "compId": 1, "layer": "title", "radius": 28 } }
{ "command": "cinematicGrade", "params": { "compId": 1, "layer": "footage", "warm": true } }
{ "command": "applyLumetri", "params": { "compId": 1, "layer": "footage",
"settings": { "saturation": 140, "contrast": 20, "temperature": 12, "vibrance": 25 } } }
```
专业文本样式,一次调用:
```json
{ "command": "applyTextPreset", "params": { "compId": 1, "layer": "title", "preset": "blurFade" } }
```
`preset` 是 `wordReveal`,`charScale`,`bunchRotate`,`blurFade` 之一。 对于完全控制,使用 `addTextAnimator`(属性 + 高级范围选择器 + 关键帧偏移和起始时间,易用模式)。
---
## 9. 编排器(自主流水线)
用清单描述视频(片段的时间或帧范围)+每个片段的规格(声明性处理)。 编排器,即桥的 `/agent` 客户端,运行循环:
```
spec -> applySpec(实现)-> scoped aerender(渲染)-> visual review(FFmpeg)->
structured delta(修订)-> re-render -> pass -> FFmpeg concat(组装)
```
规格是一份处理列表:
```jsonc
{
"segment_id": 0,
"intent": "A flaming title",
"treatments": [
{ "type": "fire", "center": [960,660], "size": 1.0 },
{ "type": "title", "text": "ON FIRE", "fontSize": 150, "fillColor": [1,0.95,0.8],
"justification": 2, "position": [960,300], "animator": "blurFade",
"grade": { "warm": true }, "glitch": { "amount": 40 }, "neon": { "radius": 25 },
"effects": [ { "effect": "Glow", "params": { "Glow Radius": 40 } }, { "effect": "Tint" } ] }
]
}
```
支持的处理类型:`fire`,`smoke`,`title`(带有 `animator`,`grade`,`glitch` 和 `neon` 修饰符),`color_grade`,`procedural_motion`,`responsive_box`,`transition`。 每个片段都是幂等的:重新运行会擦除并重建其 `seg{id}_*` 图层,因此状态永远不会漂移。
特效按显示名称:任何处理都可以带有 `effects: [{ effect, params }]` 数组(`color_grade` 采用单个 `effect`)。 编写您从Effect菜单中选择的显示名称,如 `"Glow"` 或 `"Lumetri Color"`,执行者会为您解析为matchName(`ADBE Glo2`,`ADBE Lumetri`),并在验证其已安装后为您验证。
第三方插件:两个已安装的特效包装器提供友好的参数(在幕后解析为插件的稳定matchNames,因为这些插件重用内部参数名称):
| 命令 / 规格修饰符 | 插件 | 友好参数 |
|---|---|---|
| `deepGlow` | Deep Glow 2(Plugin Everything,`PEDG2`) | `radius, exposure, threshold, glowMode, color, colorOuter, tintStrength` |
| `shadowStudio` | Shadow Studio 3(Plugin Everything,`PESS3`) | `lightDirection, shadowLength, lightRadius, softness, color, opacityStart, opacityEnd, samples` |
```jsonc
{ "type": "title", "text": "NEON",
"deepGlow": { "radius": 200, "exposure": 1.2, "color": [1, 0.4, 0.1] },
"shadowStudio": { "lightDirection": 120, "shadowLength": 300 } }
```
编写其他插件是一次调用:`introspectEffect { name: "Your Plugin" }` 将其添加到一个临时图层并导出完整的参数树(每个参数的 `name`,`matchName`,值类型和默认值)。 复制matchNames到映射并完成。 上述两个包装器都是这样构建的;传递原始 `params: { "PEDG2-0017": 250 }` 以访问任何不在友好映射中的内容。 重新运行 `introspectEffect` 插件版本更新时,以防matchNames发生偏移。
审查者是可插拔的(`controller/src/orchestrator/reviewers.js`):
- `brightnessReviewer`(默认):一个FFmpeg `signalstats`检查段实际渲染了可见内容;如果它是空白的,它会发出结构化delta。
- `claudeReviewer`: 一个判断意图的视觉模型;设置 `ANTHROPIC_API_KEY` 启用。
演示:
```bash
npm run orchestate # 2个段;一个故意损坏并自我纠正
npm run orchestate:fire = "a fiery title" plus a self-correcting segment
npm run showreel # 4-VFX parallel showreel(fire / smoke / glitch / neon)
```
并行渲染:`runPipelineParallel` 构建所有段快速(顺序编辑 + 一次保存),然后并发渲染待段,修订失败的段。 默认值为 `concurrency: 2`;仅在段内渲染)然后在轮次中并发渲染挂起的段。`aerender`已经跨核心多帧渲染,因此高并发性会使单个机器超载。默认值为 `concurrency: 2`;仅在多个机器上或针对短时间、启动绑定的渲染时才提高它。
---
## 10. 配置
根目录 `config.json` 是终点的单一真实来源(只有面板的 `wsUrl` 在移动到云端时更改):
```jsonc
{ "host": "127.0.0.1", "port": 8787, "wsPath": "/bridge", "agentPath": "/agent",
"commandTimeoutMs": 30000, "reconnect": { "initialDelayMs": 500, "maxDelayMs": 10000, "factor": 1.8 } }
```
环境变量覆盖:
| 环境变量 | 默认值 | 用途 |
|---|---|---|
| `AE_BRIDGE_HOST` | `127.0.0.1` | 绑定地址 |
| `AE_BRIDGE_PORT` | `8787` | 端口 |
| `AE_BRIDGE_TIMEOUT_MS` | `30000` | 命令超时 |
| `AE_BRIDGE_ALLOW_DEV` | `0` | 启用 `runJSX`(允许时为 `1`) |
| `AE_BRIDGE_LOG_LEVEL` | `info` | `debug`,`info`,`warn` 或 `error` |
| `AE_BRIDGE_AERENDER` | 自动检测 | 如果自动检测失败,则为 `aerender` 提供完整路径 |
| `ANTHROPIC_API_KEY` | (未设置) | 在编排器中启用视觉模型审查 |
面板读取 `panel/config.json` 以获取其 `wsUrl`(如果移动到云端,则回退到 `ws://127.0.0.1:8787/bridge`)。
---
## 11. 开发工作流(热重载 + 签名)
编辑JSX并热重载,无需重新打开AE:`node tools/hot.mjs` 将包重新生成并通过CEF DevTools协议将其评估到正在运行的面板中(它永远不会触及签名文件,因此签名保持有效)。它需要面板打开和 `.debug` 远程调试端口可用。
使其永久生效:`npm run deploy:panel` 重新签名并部署(然后退出并重新打开AE)。
实时检查面板:存在 `.debug` 文件时,使用CEF DevTools在指定的端口打开它。
捆绑的JSX必须是ASCII字符,因为 `$.evalFile` 错误地解码了没有BOM的UTF-8。打包器清理了非ASCII字符,面板加载器读取文件为显式UTF-8并求值。
---
## 2. 架构
控制器(`controller/`):Express + `ws`。`aeClient.js` 跟踪单个面板套接字并提供 `sendCommand()`(一个Promise,与ID相关联,有超时,断开连接时拒绝,并且始终解析为统一的 `{ok,...}` 形状)。`agentHub.js` 将来自代理和UI的命令中继,并广播面板事件。`server.js` 将 `/bridge`(面板)路由到 `/agent`(客户端)。`orchestrator/` 包含代理管道。
面板(`panel/`):一个手工制作的CEP扩展程序。`index.html` 加载Adobe的真实 `CSInterface.js`,`bridge.js`(evalScript到Promise + 包加载器)和 `main.js`(带有重连和回退的WS客户端)。JSX位于 `panel/jsx/`,并捆绑到 `bundle.jsx`。
JSX层(`panel/jsx/`):`host.jsx`(调度 + `AEB.*` 帮助程序 + JSON polyfill)和 `commands/*.jsx`(每个组一个文件)。仅支持ES3。
共享(`shared/`):线协议 + 命令注册表,由控制器和模拟器使用(单一真实来源)。
模拟器(`simulator/`):在Node `vm`中运行实际捆绑的JSX以模拟AE DOM,因此无需AE即可测试架构。
面板是承载且构建一次的部分,本地和(稍后)云端都相同。控制器是一个可互换的前端。
---
## 13. 项目结构
```
aftr/
├── README.md
├── package.json # 工作区 + 脚本
├── config.json # 端点配置
├── controller/
│ ├── src/
│ │ ├── server.js # WS服务器 + Express + 静态UI
│ │ ├── aeClient.js # 面板套接字 + sendCommand(ID相关,超时)
│ │ ├── agentHub.js # 代理/UI中继 + 事件广播
│ │ ├── protocol.js, commands.js, log.js
│ │ └── orchestrator/ # 代理客户端,审查器,引擎,演示
│ ├── ui/ # 交互式控制面板(index.html,ui.js,styles.css)
│ └── test/ # aeClient,agentHub,e2e
├── panel/ # CEP扩展程序(桥)
│ ├── CSXS/manifest.xml
│ ├── index.html, .debug, config.json
│ ├── src/ # csInterface.js(Adobe真实库),bridge.js,render.js,keystroke.js,main.js
│ ├── jsx/ # json2.js, host.jsx, commands/*.jsx (bundle.jsx 生成)
│ ├── build/ # bundle-jsx.js, sign-and-deploy.mjs
│ └── tools/sendkeys.ps1
├── shared/src/ # 协议,命令,验证,配置
└── simulator/src/ # index.js, mockAeDom.js, jsxRunner.js, render.js
```
---
## 14. 测试
```bash
npm test # 单元测试(协议/命令)+ 模拟器(JSX调度在模拟DOM上)+ 控制器
npm run e2e # 控制器 + 模拟器完整往返,包括渲染进度/完成事件 + 输出文件
```
里程碑 | 验证者
|---|---|
| M0 面板加载 | 面板出现在窗口 > 扩展(签名);模拟器验证连接 |
| M1 读取路径 | `getProjectInfo` 返回实际项目 |
| M2 写入路径 | `createComp` 创建一个合成,确认通过 `listComps` |
| M3 往返 | 控制器到WS到桥到JSX到结果到REST(e2e) |
| M4 词汇表 | 所有命令在两侧进行验证;错误作为 `{ok:false,error}` 出现 |
| M5 渲染 | 非阻塞 `aerender`;`progress` 和 `renderComplete` 事件;实际输出文件 |
---
## 15. 故障排除
"签名验证失败" 或面板在窗口 > 扩展中不显示。
现代 AE 忽略 `PlayerDebugMode`。运行 `npm run deploy:panel`(签名并安装),然后完全退出并重新启动 AE。CEP 在启动时读取签名,因此在(重新)部署后需要重启。
面板连接成功,但每个命令都返回 "EvalScript 错误"。
面板必须使用真正的 Adobe `CSInterface.js`(已在 `panel/src/csInterface.js` 中提供)。存根或缺少的库会导致 `evalScript` 始终失败。同时确保 `npm run build:jsx` 已运行,以便 `panel/jsx/bundle.jsx` 存在。
JSX 包无法加载。
`$.evalFile` 错误地解码无 BOM 的 UTF-8。捆绑器发出 ASCII,加载器读取 UTF-8 然后 `eval()`,因此请保持源代码为 ASCII(捆绑器会进行清理)。ExtendScript 是 ES3:不允许使用 `let`、`const` 或箭头函数,也不允许使用链式三元运算符 `a?b:c?d:e`,因此请使用 `if/else`。
`render` 表示找不到 aerender。
设置 `AE_BRIDGE_AERENDER` 为完整路径。Windows:`…\Support Files\aerender.exe`。macOS:`/Applications/Adobe After Effects <year>/aerender`。
`render` 错误:"未找到合成。"
`aerender` 读取已保存的 `.aep` 文件。首先保存(使用 `saveProject` 并提供路径),因为新建的"未标题"项目在磁盘上没有任何内容。
协调器或代理命令超时。
确保控制器正在运行并且面板已连接(`GET /api/status`)。代理回复与您发送的 `id` 相关。
按键操作无反应。
操作系统按键注入是尽力而为的(Windows 前台锁定阻止后台 `SendKeys`)。对于任何菜单或快捷键操作,请使用 `executeMenuCommand`;这是直接的脚本调用,始终有效。
模态对话框冻结桥梁。
避免使用打开对话框的 JSX(或 `alert()`);它会阻塞 `evalScript`。
---
## 16. 跨平台说明
| | Windows | macOS |
|---|---|---|
| CEP 扩展文件夹 | `%APPDATA%\Adobe\CEP\extensions` | `~/Library/Application Support/Adobe/CEP/extensions` |
| `aerender` 位置 | `…\Support Files\aerender.exe` | `/Applications/Adobe After Effects <year>/aerender` |
| 签名工具 | 由 `zxp-sign-cmd` 提供 | 由 `zxp-sign-cmd` 提供(需要时清除隔离) |
| 按键层 | .NET `SendKeys` (`panel/tools/sendkeys.ps1`) | `osascript` 系统事件 |
| 可选调试模式 | `HKCU\Software\Adobe\CSXS.12` `PlayerDebugMode=1` | `defaults write com.adobe.CSXS.12 PlayerDebugMode 1` |
`deploy:panel`、控制器、模拟器、捆绑器和协调器都是跨平台的 Node。CEP 面板本身在两个平台上是相同的,因此只需构建一次并在 AE 运行的任何地方运行。
---
## 许可证
MIT。随意使用、分叉和发布。
---
观看完整演示:<a href="https://www.youtube.com/watch?v=QkjTwlqPhNc">https://www.youtube.com/watch?v=QkjTwlqPhNc</a>
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器