Copy link to clipboard
Copied
Hi everyone, I’m trying to automate the creation of keyframes for the “Scale” property of a clip using ExtendScript in Premiere Pro. I want to set two keyframes (start and end), assign them values, and set their interpolation to Bezier (or Hold, depending on the case). Here’s the relevant part of my code:
var scaleProperty = /* ... get the Scale property from the Transform effect ... */;
var startFrame = 0;
var endFrame = 100;
var zoomStart = 100;
var zoomEnd = 120;
var interp = 5; // 5 = Bezier, 4 = Hold
scaleProperty.setTimeVarying(true);
// Remove existing keyframes
if (scaleProperty.numKeys && scaleProperty.numKeys > 0) {
while (scaleProperty.numKeys > 0) {
scaleProperty.removeKey(0);
}
}
// Add start keyframe
scaleProperty.addKey(startFrame);
scaleProperty.setValueAtKey(startFrame, zoomStart);
scaleProperty.setInterpolationTypeAtKey(startFrame, interp, 1);
// Add end keyframe
scaleProperty.addKey(endFrame);
scaleProperty.setValueAtKey(endFrame, zoomEnd);
scaleProperty.setInterpolationTypeAtKey(endFrame, interp, 1);
My problem:
The stopwatch icon turns blue (so time-varying is enabled), but I don’t see any keyframe points on the curve.
The Scale curve stays flat at the zoomEnd value (e.g., 120 here in the example), instead of animating between the two values.
No error is thrown, but the keyframes just don’t appear or animate as expected.
Thank you for your help ! Have a nice day 🙂
This snippet seems to work:
var seq = app.project.activeSequence;
if (seq) {
var firstVideoTrack = seq.videoTracks[0];
if (firstVideoTrack) {
var firstClip = firstVideoTrack.clips[0];
if (firstClip) {
var clipComponents = firstClip.components;
if (clipComponents) {
var motionComp = clipComponents[1];
if (motionComp){
var motionProps = motionComp.properties;
if (motionProps){
var scaleProp = motionProps[1];
if (scaleProp){
var startingKeys = sca
...
Copy link to clipboard
Copied
We'll have a look...
When you say "get the Scale property from the Transform effect", do you mean the Scale property that's part of every trackItem's intrinsic Motion, or do you mean an application of the Transform effect, independent of the intrinsic Scale property?
Copy link to clipboard
Copied
To be honest, I’ve tried both — the intrinsic Motion > Scale property and the Scale from the applied Transform effect. Neither throws an error, but in both cases, the keyframes just don’t appear. The curve stays flat at the zoomEnd value instead of animating.
Thank you for taking the time to look into this, sir. Much appreciated.
Copy link to clipboard
Copied
This snippet seems to work:
var seq = app.project.activeSequence;
if (seq) {
var firstVideoTrack = seq.videoTracks[0];
if (firstVideoTrack) {
var firstClip = firstVideoTrack.clips[0];
if (firstClip) {
var clipComponents = firstClip.components;
if (clipComponents) {
var motionComp = clipComponents[1];
if (motionComp){
var motionProps = motionComp.properties;
if (motionProps){
var scaleProp = motionProps[1];
if (scaleProp){
var startingKeys = scaleProp.getKeys();
var startFrame = 0;
var endFrame = 100;
var zoomStart = 100;
var zoomEnd = 120;
var interp = 5; // 5 = Bezier, 4 = Hold
var isVarying = scaleProp.isTimeVarying();
scaleProp.addKey(startFrame);
scaleProp.setValueAtKey(startFrame, zoomStart);
scaleProp.setInterpolationTypeAtKey(startFrame, interp, 1);
// Add end keyframe
scaleProp.addKey(endFrame);
scaleProp.setValueAtKey(endFrame, zoomEnd);
scaleProp.setInterpolationTypeAtKey(endFrame, interp, 1);
var newKeys = scaleProp.getKeys();
}
}
}
}
}
}
}
Copy link to clipboard
Copied
Indeed, the keys do seem to be set, since scaleProp.numKeys = 2 at the end of the script run, but in the software, the value is not a curve—it’s a constant equal to zoomEnd (the last applied value), and we don’t see the keyframes (the diamonds on the curve).
I used this code very similar to yours :
applyZoomToClip: function(clip, params) {
try {
if (!clip) return false;
var clipComponents = clip.components;
if (!clipComponents) {
alert("No components found on this clip.");
return false;
}
var motionComp = null;
if (!motionComp && clipComponents.numItems > 1) {
motionComp = clipComponents[1];
}
if (!motionComp) {
alert("Motion component not found on this clip.\n\nThe Motion component is usually automatically present on all video clips in Premiere Pro.");
return false;
}
var motionProps = motionComp.properties;
if (!motionProps) {
alert("No properties found on Motion component.");
return false;
}
var scaleProp = null;
for (var j = 0; j < motionProps.numItems; j++) {
if (motionProps[j].displayName === "Scale" || motionProps[j].displayName === "Echelle") {
scaleProp = motionProps[j];
break;
}
}
if (!scaleProp && motionProps.numItems > 1) {
scaleProp = motionProps[1];
}
if (!scaleProp) {
alert("Scale property not found on Motion component.");
return false;
}
var clipStart = 0;
var clipEnd = 0;
try {
if (clip.duration) {
clipStart = 0;
clipEnd = Math.floor(clip.duration.seconds * 30);
} else {
clipStart = 0;
clipEnd = 150;
}
} catch (e) {
clipStart = 0;
clipEnd = 150;
}
this.applyScaleKeyframes(scaleProp, clipStart, clipEnd, params);
return true;
} catch (error) {
alert("Error in applyZoomToClip: " + error.toString() + (error.stack ? "\nStack: " + error.stack : ""));
return false;
}
},
applyScaleKeyframes: function(scaleProp, startFrame, endFrame, params) {
try {
if (!scaleProp) return false;
var zoomStart = (params && params.zoomStart) || 100.0;
var zoomEnd = (params && params.zoomEnd) || 110.0;
var interp = 5; // 5 = Bezier, 4 = Hold
// ALERT 1: Show input parameters
alert("DEBUG - Input Parameters:\n" +
"Start Frame: " + startFrame + "\n" +
"End Frame: " + endFrame + "\n" +
"Zoom Start: " + zoomStart + "%\n" +
"Zoom End: " + zoomEnd + "%\n" +
"Interpolation: " + interp + " (Bezier)");
var isVarying = scaleProp.isTimeVarying();
// ALERT 2: Show property state before modification
alert("DEBUG - Property State:\n" +
"Is Time Varying: " + isVarying + "\n" +
"Current Value: " + scaleProp.getValue() + "\n" +
"Number of existing keys: " + (scaleProp.numKeys || 0));
if (scaleProp.numKeys && scaleProp.numKeys > 0) {
while (scaleProp.numKeys > 0) {
scaleProp.removeKey(0);
}
}
scaleProp.setTimeVarying(true);
scaleProp.addKey(startFrame);
scaleProp.setValueAtKey(startFrame, zoomStart);
scaleProp.setInterpolationTypeAtKey(startFrame, interp, 1);
scaleProp.addKey(endFrame);
scaleProp.setValueAtKey(endFrame, zoomEnd);
scaleProp.setInterpolationTypeAtKey(endFrame, interp, 1);
var newKeys = scaleProp.getKeys();
// ALERT 3: Final result
alert("DEBUG - Final Result:\n" +
"Total keys created: " + newKeys.length + "\n" +
"Key 1: Frame " + startFrame + " = " + zoomStart + "%\n" +
"Key 2: Frame " + endFrame + " = " + zoomEnd + "%\n" +
"Current property value: " + scaleProp.getValue() + "\n" +
"Is Time Varying: " + scaleProp.isTimeVarying());
return true;
} catch (e) {
alert("ERROR in applyScaleKeyframes: " + e.toString() + (e.stack ? "\nStack: " + e.stack : ""));
return false;
}
},
Find more inspiration, events, and resources on the new Adobe Community
Explore Now