CEP 插件开发基础
CEP 插件开发基础
Section titled “CEP 插件开发基础”CEP (通用扩展平台) 是 Adobe 的插件开发框架,它允许开发者使用 HTML、CSS 和 JavaScript 来创建现代化的插件界面。
什么是 CEP?
Section titled “什么是 CEP?”CEP 是 Adobe Creative Suite 应用程序的可扩展性平台,提供:
- 现代 Web 技术 - 使用 HTML5, CSS3, JavaScript
- 跨应用支持 - 适用于 Photoshop, After Effects, Premiere Pro 等
- 丰富的 API - 访问应用程序核心功能
- 灵活的界面 - 创建自定义用户界面
开发环境设置
Section titled “开发环境设置”-
代码编辑器
- Visual Studio Code (推荐)
- Adobe Brackets
- Sublime Text
-
调试工具
- Chrome DevTools
- CEP 调试模式
-
Adobe 应用程序
- After Effects CC 2015 或更高版本
启用调试模式
Section titled “启用调试模式”在 Windows 上添加以下注册表项:
[HKEY_CURRENT_USER\Software\Adobe\CSXS.9]"PlayerDebugMode"="1"或在 macOS 终端中执行:
defaults write com.adobe.CSXS.9 PlayerDebugMode 1一个典型的 CEP 插件项目结构:
MyPlugin/├── CSXS/│ └── manifest.xml # 插件清单文件├── js/│ ├── main.js # 主要逻辑│ └── extendscript.jsx # ExtendScript 代码├── css/│ └── style.css # 样式文件├── index.html # 主界面└── icons/ ├── icon-normal.png └── icon-hover.png清单文件 (manifest.xml)
Section titled “清单文件 (manifest.xml)”<?xml version="1.0" encoding="UTF-8"?><ExtensionManifest Version="7.0" ExtensionBundleId="com.example.myplugin"> <ExtensionList> <Extension Id="com.example.myplugin" Version="1.0.0" /> </ExtensionList>
<ExecutionEnvironment> <HostList> <Host Name="AEFT" Version="[13.0,99.9]" /> </HostList> <LocaleList> <Locale Code="All" /> </LocaleList> <RequiredRuntimeList> <RequiredRuntime Name="CSXS" Version="9.0" /> </RequiredRuntimeList> </ExecutionEnvironment>
<DispatchInfoList> <Extension Id="com.example.myplugin"> <DispatchInfo> <Resources> <MainPath>./index.html</MainPath> <ScriptPath>./js/extendscript.jsx</ScriptPath> </Resources> <Lifecycle> <AutoVisible>true</AutoVisible> </Lifecycle> <UI> <Type>Panel</Type> <Menu>My Plugin</Menu> <Geometry> <Size> <Width>300</Width> <Height>400</Height> </Size> </Geometry> </UI> </DispatchInfo> </Extension> </DispatchInfoList></ExtensionManifest>基本 HTML 结构
Section titled “基本 HTML 结构”<!DOCTYPE html><html><head> <meta charset="utf-8"> <title>My Plugin</title> <link rel="stylesheet" href="css/style.css"></head><body> <div id="content"> <h1>我的 AE 插件</h1> <button id="createLayer">创建图层</button> <button id="addKeyframes">添加关键帧</button> </div>
<script src="js/CSInterface.js"></script> <script src="js/main.js"></script></body></html>JavaScript 主要逻辑
Section titled “JavaScript 主要逻辑”(function() { 'use strict';
var csInterface = new CSInterface();
function init() { // 绑定事件 document.getElementById('createLayer').addEventListener('click', createLayer); document.getElementById('addKeyframes').addEventListener('click', addKeyframes); }
function createLayer() { // 调用 ExtendScript 函数 csInterface.evalScript('createSolidLayer()', function(result) { console.log('图层创建结果:', result); }); }
function addKeyframes() { csInterface.evalScript('addPositionKeyframes()', function(result) { console.log('关键帧添加结果:', result); }); }
// 初始化 init();})();ExtendScript 代码
Section titled “ExtendScript 代码”function createSolidLayer() { try { var comp = app.project.activeItem; if (!comp || !(comp instanceof CompItem)) { return "请先选择一个合成"; }
var solidLayer = comp.layers.addSolid( [Math.random(), Math.random(), Math.random()], // 随机颜色 "CEP Solid", comp.width, comp.height, comp.duration );
return "图层创建成功: " + solidLayer.name; } catch (e) { return "错误: " + e.toString(); }}
function addPositionKeyframes() { try { var comp = app.project.activeItem; if (!comp || !(comp instanceof CompItem)) { return "请先选择一个合成"; }
var selectedLayers = comp.selectedLayers; if (selectedLayers.length === 0) { return "请先选择一个图层"; }
var layer = selectedLayers[0]; var position = layer.property("Transform").property("Position");
// 在当前时间和2秒后添加关键帧 var currentTime = comp.time; position.setValueAtTime(currentTime, [100, 100]); position.setValueAtTime(currentTime + 2, [500, 300]);
return "位置关键帧添加成功"; } catch (e) { return "错误: " + e.toString(); }}
function getCompInfo() { try { var comp = app.project.activeItem; if (!comp || !(comp instanceof CompItem)) { return "没有活动的合成"; }
var info = { name: comp.name, width: comp.width, height: comp.height, duration: comp.duration, frameRate: comp.frameRate, layerCount: comp.numLayers };
return JSON.stringify(info); } catch (e) { return "错误: " + e.toString(); }}CSS 样式
Section titled “CSS 样式”body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; margin: 0; padding: 20px; background-color: #2e2e2e; color: #ffffff;}
#content { max-width: 100%;}
h1 { color: #00a8ff; margin-bottom: 20px; font-size: 18px;}
button { background-color: #0066cc; color: white; border: none; padding: 10px 15px; margin: 5px 0; border-radius: 4px; cursor: pointer; width: 100%; font-size: 14px;}
button:hover { background-color: #0052a3;}
button:active { background-color: #003d7a;}
.input-group { margin: 10px 0;}
label { display: block; margin-bottom: 5px; font-size: 12px;}
input[type="text"],input[type="number"],select { width: 100%; padding: 8px; border: 1px solid #555; border-radius: 4px; background-color: #404040; color: white; box-sizing: border-box;}
input[type="text"]:focus,input[type="number"]:focus,select:focus { outline: none; border-color: #00a8ff;}UI 与 ExtendScript 之间的通信
Section titled “UI 与 ExtendScript 之间的通信”从 UI 到 ExtendScript
Section titled “从 UI 到 ExtendScript”// 执行 ExtendScript 函数csInterface.evalScript('functionName()', function(result) { console.log('结果:', result);});
// 传递参数var param1 = "hello";var param2 = 42;csInterface.evalScript(`functionName('${param1}', ${param2})`, function(result) { console.log('结果:', result);});从 ExtendScript 到 UI
Section titled “从 ExtendScript 到 UI”// 在 ExtendScript 中function notifyUI(message) { var event = new CSEvent("com.example.myplugin.message", "APPLICATION"); event.data = message; csInterface.dispatchEvent(event);}
// 在 UI JavaScript 中csInterface.addEventListener("com.example.myplugin.message", function(event) { console.log('来自 ExtendScript 的消息:', event.data);});启用远程调试
Section titled “启用远程调试”- 启用 CEP 调试模式 (如上所示)
- 打开 Chrome 并导航到
http://localhost:8092 - 在列表中找到您的插件并点击 “inspect”
- 使用 Chrome DevTools 进行调试
常用调试技巧
Section titled “常用调试技巧”// 控制台日志console.log('调试信息:', variable);
// 错误处理try { // 您的代码} catch (error) { console.error('发生错误:', error);}
// ExtendScript 调试$.writeln('ExtendScript 中的调试信息');-
将插件文件夹复制到 CEP 扩展目录:
- Windows:
C:\Users\[username]\AppData\Roaming\Adobe\CEP\extensions\ - macOS:
~/Library/Application Support/Adobe/CEP/extensions/
- Windows:
-
重启 After Effects
-
在 窗口 > 扩展 菜单中找到插件
- 使用 Adobe 工具打包为 ZXP 文件
- 通过 Adobe Exchange 分发
- 提供安装说明
- 最小化 DOM 操作
- 使用高效的 ExtendScript 代码
- 实现正确的错误处理
- 缓存常用数据
- 为操作提供视觉反馈
- 处理加载状态
- 实现正确的验证
- 遵循 Adobe UI 指南
- 验证所有用户输入
- 清理传递给 ExtendScript 的数据
- 妥善处理敏感信息
常见问题与解决方案
Section titled “常见问题与解决方案”- 检查 manifest.xml 语法
- 验证文件路径
- 确保调试模式已启用
- 检查控制台错误
ExtendScript 错误
Section titled “ExtendScript 错误”- 使用 try-catch 块
- 验证对象是否存在
- 检查 After Effects 版本兼容性
UI 响应性
Section titled “UI 响应性”- 使用异步操作
- 实现进度指示器
- 避免阻塞操作
🔗 相关资源
Section titled “🔗 相关资源”- 插件架构 - 高级插件结构
- ExtendScript 集成 - 深入了解 ExtendScript
- VS Code 设置 - 开发环境
- Adobe CEP 示例 - 官方示例