Having troubles writing position in Premiere

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.

  1. 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.)
  2. Is there a different, currently-undocumented correct pattern for writing point-type keyframe values? We followed the documented createKeyframe(inValue: PointF) signature exactly.
  3. 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.

  1. Is there any API to read or write the temporal handles (influence and speed, or in/out tangents) of a keyframe?
  2. The same question for spatial handles on Position.
  3. If not, is there a planned API? And is getValueAtTime intended to be accurate enough to reconstruct the curve by sampling?
  4. 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:

  1. Not yet
  2. Not yet
  3. getValueAtTime should be accurate enough.
  4. None as far as I’m aware, but I’d love to know if you find one!
1 Like