Writing a Position (or any PointF-typed) keyframe value through the UXP scripting API silently corrupts the value to 32767, 32767 (INT16_MAX — a classic uninitialized-memory sentinel) instead of storing what was requested. No error is thrown. The API’s own immediate readback even reports a plausible-looking {value: [x, y]} shape — the corruption only becomes visible when you look at Effect Controls. This blocks any workflow that needs to programmatically write animated 2D-point parameters (Position, Anchor Point, and likely Scale).
Minimal repro
js
const project = await require('premierepro').Project.getActiveProject();
const sequence = await project.getActiveSequence();
const clip = (await (await sequence.getSelection()).getTrackItems())[0];
const chain = await clip.getComponentChain();
// find the intrinsic Motion component (matchName "AE.ADBE Motion")
const posParam = await motionComponent.getParam(0); // "Position"
await project.lockedAccess(() => {
project.executeTransaction((ca) => {
ca.addAction(posParam.createSetTimeVaryingAction(true));
}, "enable time-varying");
});
await project.lockedAccess(() => {
project.executeTransaction((ca) => {
const pt = new ppro.PointF(200, 200); // also tried: new PointF() + pt.x=200; pt.y=200 — identical result
const kf = posParam.createKeyframe(pt); // documented signature: createKeyframe(inValue: PointF)
kf.position = ppro.TickTime.createWithTicks(someTicksString);
ca.addAction(posParam.createAddKeyframeAction(kf));
}, "write test keyframe");
});
// getValueAtTime() afterward reports {value: [x, y]} — looks fine via API.
// Effect Controls shows 32767, 32767 — not 200, 200.
Environment: Premiere Pro 26.5.1, manifest v5, tested via UDT debug session.
- Where does the corruption happen — the JS↔native marshaling layer, or inside the parameter engine after receiving a correctly-formed
PointF? (We tested two different construction patterns — constructor args vs. property assignment — both produced the identical 32767 sentinel, which points away from a JS-side construction mistake.)
- Is there a different, currently-undocumented correct pattern for writing point-type keyframe values? We followed the documented
createKeyframe(inValue: PointF) signature exactly.
- Does this affect all
PointF-typed params, or specifically Position?
Hey @MoisesNavarroSolera,
Thanks for the detailed report! This is less a “corruption” issue and more a documentation (or lack thereof) one. PointF-based keyframes work based on normalized values rather than pixel-based values: if you get the initial value for the Position param, you’ll get something like:
const project = await require('premierepro').Project.getActiveProject();
const sequence = await project.getActiveSequence();
const clip = (await (await sequence.getSelection()).getTrackItems())[0];
const chain = await clip.getComponentChain();
// find the intrinsic Motion component (matchName "AE.ADBE Motion")
const posParam = await motionComponent.getParam(0); // "Position"
const value = await posParam.getStartValue();
console.log(value.value); // [0.5, 0.5]
That [0.5, 0.5] refers to frame center. If you wanted to adjust the “Motion > Position” param specifically you can do so by normalizing against the sequence’s frame rect first, e.g.:
const sequence = await project.getActiveSequence();
const sequenceSettings = await sequence.getSettings();
const videoFrameRect = await sequenceSettings.getVideoFrameRect();
project.lockedAccess(() => {
// Normalize the x, y values by dividing the
// pixel value by frame width/height
const pt = new ppro.PointF(
200 / videoFrameRect.width,
200 / videoFrameRect.height
);
const kf = posParam.createKeyframe(pt);
kf.position = ppro.TickTime.createWithTicks(someTicksString);
project.executeTransaction((ca) => {
ca.addAction(posParam.createAddKeyframeAction(kf));
}, "write test keyframe");
});
Can you see if doing that gets you closer to what you’re expecting?
2 Likes
Thank you Cameron! Yes, this solve my issue.
can temporal bezier handles be read or written?
We’re building a panel that copies keyframed animations between clips. With Keyframe.temporalInterpolationMode and createSetInterpolationAtKeyframeAction we can read and set Linear, Hold and Bezier, but a Bezier keyframe always comes back with default handles.
- Is there any API to read or write the temporal handles (influence and speed, or in/out tangents) of a keyframe?
- The same question for spatial handles on Position.
- If not, is there a planned API? And is
getValueAtTime intended to be accurate enough to reconstruct the curve by sampling?
- Are there limits on how many keyframes one transaction can add?
Right now there isn’t any support for temporal ease or spatial handles yet, but we can certainly look to adding these sorts of features in the future. I’ve created DVAPR-4268138 on our side to track this more.
To answer your questions:
- Not yet
- Not yet
getValueAtTime should be accurate enough.
- None as far as I’m aware, but I’d love to know if you find one!
1 Like