PPro Scripting: Algorithm to get selected clips as QE items
I spent some time brainstorming how to combine useful (but experimental) QE functions with the well documented ExtendScript library for Premiere Pro. Most importantly, I wanted to port over the getSelection() return values from regular trackItems into QEitems, that way I can do things such as addVideoEffect onto a user's selected clips.
I made a QEgetSelection() function to accomplish this. It gets the user's selection as an array of trackItems and loops through each one to find its associated QEitem. These are returned in an array.
In practice, QEgetSelection() should have similar functionality to getSelection(), plus a short buffering period. On my i7 RTX laptop, this function can collect roughly 500 track items in 0.65 seconds.
Before implementing this, please note that the QE API is undocumented and unsupported. There's no guarantee this algorithm will work in future Premiere versions.
I'm happy to hear any ideas on how this algorithm can be faster or more efficient:
// Function: QEgetSelection
// Purpose: Gets user's selected timeline clips as QEitems
// Input: None
// Output: Array of QEitems selected
// Note: This Algorithm is optimized for VIDEO CLIPS ONLY
//
function QEgetSelection() {
// DEBUG: get start time
/*
var startTime = new Date().getTime();
*/
// get selected clips
var QEsequence = qe.project.getActiveSequence();
var sequence = app.project.activeSequence;
var sel = sequence.getSelection();
var QEsel = [];
// Store loop iterations with respect to track index, initialize to 0
var loopIter = new Array(sequence.videoTracks.length);
for (var i = 0; i < loopIter.length; i++)
{
loopIter[i] = 0;
}
// For each selected clip
for (var i = 0; i < sel.length; i++)
{
// Ignore if it's an audio clip
if (sel[i].mediaType == "Audio")
{
continue;
}
// Store start time
var clipTicks = sel[i].start.ticks;
var clipName = sel[i].name;
// Store track
var trackIdx = sel[i].parentTrackIndex;
// Loop through every QE item on that track
var QEtrack = QEsequence.getVideoTrackAt(trackIdx);
for (loopIter[trackIdx]; loopIter[trackIdx] < QEtrack.numItems; loopIter[trackIdx]++)
{
var QEitem = QEtrack.getItemAt(loopIter[trackIdx]);
// Disregard QEitem if it's empty space
if (QEitem.type == "Empty")
{
continue;
}
var QEticks = QEitem.start.ticks;
var QEname = QEitem.name;
// If QEitem and Clip are identical
if (QEticks == clipTicks &&
QEname == clipName)
{
// Push QEitem to array
QEsel.push(QEitem);
// Move onto next selected clip
break;
}
}
}
// DEBUG: get end time, display time elapsed
/*
var endTime = new Date().getTime();
var elapsedMs = endTime - startTime;
var elapsedSec = elapsedMs / 1000
alert("Done\nItems Selected: " + QEsel.length + "\nTime: " + elapsedSec + " sec");
*/
return QEsel;
}
