- after-effects-mcp
- src
- scripts
// applyEffect.jsx
// Applies an effect to a specified layer in a composition
function applyEffect(args) {
try {
// Extract parameters
var compIndex = args.compIndex || 1; // Default to first comp
var layerIndex = args.layerIndex || 1; // Default to first layer
var effectName = args.effectName; // Name of the effect to apply
var effectMatchName = args.effectMatchName; // After Effects internal name (more reliable)
var effectCategory = args.effectCategory || ""; // Optional category for filtering
var presetPath = args.presetPath; // Optional path to an effect preset
var effectSettings = args.effectSettings || {}; // Optional effect parameters
if (!effectName && !effectMatchName && !presetPath) {
throw new Error("You must specify either effectName, effectMatchName, or presetPath");
}
// Find the composition by index
var comp = app.project.item(compIndex);
if (!comp || !(comp instanceof CompItem)) {
throw new Error("Composition not found at index " + compIndex);
}
// Find the layer by index
var layer = comp.layer(layerIndex);
if (!layer) {
throw new Error("Layer not found at index " + layerIndex + " in composition '" + comp.name + "'");
}
var effectResult;
// Apply preset if a path is provided
if (presetPath) {
var presetFile = new File(presetPath);
if (!presetFile.exists) {
throw new Error("Effect preset file not found: " + presetPath);
}
// Apply the preset to the layer
layer.applyPreset(presetFile);
effectResult = {
type: "preset",
name: presetPath.split('/').pop().split('\\').pop(),
applied: true
};
}
// Apply effect by match name (more reliable method)
else if (effectMatchName) {
var effect = layer.Effects.addProperty(effectMatchName);
effectResult = {
type: "effect",
name: effect.name,
matchName: effect.matchName,
index: effect.propertyIndex
};
// Apply settings if provided
applyEffectSettings(effect, effectSettings);
}
// Apply effect by display name
else {
// Get the effect from the Effect menu
var effect = layer.Effects.addProperty(effectName);
effectResult = {
type: "effect",
name: effect.name,
matchName: effect.matchName,
index: effect.propertyIndex
};
// Apply settings if provided
applyEffectSettings(effect, effectSettings);
}
return JSON.stringify({
status: "success",
message: "Effect applied successfully",
effect: effectResult,
layer: {
name: layer.name,
index: layerIndex
},
composition: {
name: comp.name,
index: compIndex
}
}, null, 2);
} catch (error) {
return JSON.stringify({
status: "error",
message: error.toString()
}, null, 2);
}
}
// Helper function to apply effect settings
function applyEffectSettings(effect, settings) {
// Skip if no settings are provided
if (!settings || Object.keys(settings).length === 0) {
return;
}
// Iterate through all provided settings
for (var propName in settings) {
if (settings.hasOwnProperty(propName)) {
try {
// Find the property in the effect
var property = null;
// Try direct property access first
try {
property = effect.property(propName);
} catch (e) {
// If direct access fails, search through all properties
for (var i = 1; i <= effect.numProperties; i++) {
var prop = effect.property(i);
if (prop.name === propName) {
property = prop;
break;
}
}
}
// Set the property value if found
if (property && property.setValue) {
property.setValue(settings[propName]);
}
} catch (e) {
// Log error but continue with other properties
$.writeln("Error setting effect property '" + propName + "': " + e.toString());
}
}
}
}
// Get arguments passed from Node.js process
var args;
try {
args = JSON.parse($.getenv("args"));
} catch (e) {
args = {};
}
// Run the function and write the result
var result = applyEffect(args);
// Write the result so it can be captured by the Node.js process
$.write(result);