Hi everyone,
I’m building a UXP plugin for Premiere Pro that auto-arranges clips on the timeline (multi-camera auto-switcher). The entry point is an async function that iterates over potentially hundreds of camera segments and places each one on the timeline.
The UXP docs say the API is asynchronous and should not block the host UI. But in practice, Premiere freezes completely for several seconds (sometimes crashes), and all clip placements appear on the timeline all at once only after the freeze ends — the UI never updates incrementally during the loop.
What the code does (simplified):
// Called once per camera segment — may run hundreds of times
async function placeClipOnTimeline({
project, editor, projectItem,
inPointSeconds, outPointSeconds,
startSeconds, videoTrackIndex, audioTrackIndex
}) {
const startTick = TickTime.createWithSeconds(startSeconds);
const inTick = TickTime.createWithSeconds(inPointSeconds);
const outTick = TickTime.createWithSeconds(outPointSeconds);
// Step 1: set in/out on the source clip
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
projectItem.createSetInOutPointsAction(inTick, outTick)
);
}, “Set Source InOut”);
});
// Step 2: overwrite (insert) at the timeline position
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
editor.createOverwriteItemAction(
projectItem, startTick, videoTrackIndex, audioTrackIndex
)
);
}, “Overwrite Clip”);
});
// Step 3: clear in/out after insertion
project.lockedAccess(() => {
project.executeTransaction((compoundAction) => {
compoundAction.addAction(
projectItem.createClearInOutPointsAction()
);
}, “Clear Source InOut”);
});
// Step 4: re-fetch track to find the inserted clip, then trim it
const track = await sequence.getVideoTrack(videoTrackIndex);
const items = await track.getItems();
const insertedClip = items[items.length - 1];
// … further trim actions via another executeTransaction
}
// Main loop
export async function autoSwitchCamera(cameraSegments) {
for (let i = 0; i < cameraSegments.length; i++) {
await placeClipOnTimeline({ /* params for segment i */ });
}
}
What I observe:
Premiere’s UI becomes completely unresponsive while the loop runs.
The timeline does not update incrementally — no clips appear during the freeze.
Once Premiere unfreezes, all clips appear on the timeline at once.
With 500+ segments, Premiere sometimes crashes entirely.
My questions:
Is project.lockedAccess + project.executeTransaction synchronous/blocking on the host side?
Should all three steps (set in/out → overwrite → clear in/out) be combined into a single executeTransaction so the compound action handles the sequencing internally? Already tried this but it seems like there is a race condition(?)
Is there a recommended way to yield between iterations to keep the UI responsive, or does the host lock prevent repainting regardless?
Are there a way to prevent the crash?
Any insight? would be hugely appreciated. Thanks!