Skip to main content
Inspiring
March 10, 2023
Answered

Is there an extendscript API to check if there's a track item at a given time?

  • March 10, 2023
  • 1 reply
  • 936 views

Hi All,

 

I'm trying to write a script to automate effect posting at a given time, However there's no check to see if tehre's already a sound track item at a given time.

 

The only way I could think of is to check all objects in and outpoints against the in and out points of the object I'm trying to post into the track, but that is not very efficient. I'm basically trying to check if it intersects with its neighbors.

 

I'm using 2023 PPro

Windows 10

 

Thanks

 

This topic has been closed for replies.
Correct answer MrPingPong

So I wrote some code that would paste the clips at the given track or paste it lower if it intersects. The prerequisite is that the length of the clips (if multiple) should go from highest to lowest. I'm sure I can code something that checks if the clip at a given time is length "x" but this is enough for my purposes. Here's the piece of code:

// Kamran Maharramli April 2nd, 2023

//Necessary prerequisites
//Premiere File with all the sequences properly named (i.e "Zoom", "Glitch", "Pop" etc), most likely grabbed by exporting After Effects file to premiere with the proper compositions
//Clips themselves need to be present in the project file
//Clip length is the last object (index=3)
//Offset value (i.e. paste 10 frames previous to current point) is index=2
//Clip name for the loop to check (index=1)


var list = [
    ["Zoom", "Trans1", 24, 55],
    ["Glitch", "GlitchSFX", 24, 39],
    ["Pop", "popEffect", 11, 24],
    ["Arm", "Whoosh_1_Basic", 8, 17],
    ["popHead", "Whoosh_1_Basic", 8, 17],
    ["InfoBox","Whoosh_1_Basic",17,17]
]

//Function to transform ticks to frames (hardcoded to "30")
function toTicks(frames) {
    newval = frames * 254016000000 / 30
    return newval;

}

//"Function checks if there's a clip at the given time. PreRequisite is that the order of clips to be imported is sorted from high to low depending on their clip length."
//This one is only for Audio Imports/tracks
function checkIfOccupied(curTime, durat, track) {
    var val = false;
    //if there are clips on track
    if (track.clips.length != 0) {
        //go through every clip on the track
        for (var clp = 0; clp < track.clips.length; clp++) {

            $.writeln("curTime: " + curTime + ", Op: " + track.clips[clp].end.ticks + ", IP: " + track.clips[clp].start.ticks + " , curTime + durat: " + (curTime + durat))
            //if start point of the "to-be-inserted" clip is in between start and end points of the existing clip->return false
            if (curTime <= track.clips[clp].end.ticks && curTime >= track.clips[clp].start.ticks) {

                val = false;
                break;
                //if end point of the "to-be-inserted" clip is in between start and end points of the existing clip->return false
            } else if ((curTime + durat) >= track.clips[clp].start.ticks && (curTime + durat) <= track.clips[clp].end.ticks) {
                val = false;
                break;
                //otherwise it does not intersect
            } else {
                val = true;
            }

        }
        //if track has 0 clips
    } else {
        val = true;
    }

    return val

}

app.enableQE();

//For Loop that goes through the "list" object and assigns the marker name value ("obj") and clip that is present in the project ("myClip") and assigns those values back to undefined at the beginning
for (var idx = 0; idx < list.length; idx++) {
    var obj = undefined;
    var myClip = undefined;
    for (var i = 0; i < app.projects[0].rootItem.children.length; i++) {
        clip = app.projects[0].rootItem.children[i]
        if (clip.name == list[idx][0]) {
            $.writeln(clip.name)
            obj = clip
        }
        if (clip.name == list[idx][1]) {
            myClip = clip;

        }
    }

    //if obj and myClip have proper values
    if (obj != undefined && myClip != undefined) {

        //get all markers from the nested sequence
        allMarkers = obj.getMarkers()
        seq = app.project.activeSequence
        //go through each marker on the sequence
        for (var j = 0; j < allMarkers.numMarkers; j++) {
            //convert duration to ticks
            var durat = toTicks(list[idx][3]);
            //skip the first 2 tracks and go through each track
            for (var g = 2; g < seq.audioTracks.length; g++) {
                //if not occupied 
                if (checkIfOccupied(allMarkers[j].start.ticks - toTicks(list[idx][2]), durat, seq.audioTracks[g]) == true) {
                    //paste the clip and then break
                    seq.audioTracks[g].insertClip(myClip, (String(allMarkers[j].start.ticks - toTicks(list[idx][2]))))
                    break;
                }

            }
        }

    }
}

 

1 reply

Bruce Bullis
Legend
March 10, 2023

While it'd be handy, PPro's API doesn't provide any "tell me whether there's already a trackItem on [track] during [time range]" function. 

The approach you mention could work; I'd be tempted to walk the trackItems on [target track], until I got to the time range I cared about...

MrPingPongAuthorCorrect answer
Inspiring
April 3, 2023

So I wrote some code that would paste the clips at the given track or paste it lower if it intersects. The prerequisite is that the length of the clips (if multiple) should go from highest to lowest. I'm sure I can code something that checks if the clip at a given time is length "x" but this is enough for my purposes. Here's the piece of code:

// Kamran Maharramli April 2nd, 2023

//Necessary prerequisites
//Premiere File with all the sequences properly named (i.e "Zoom", "Glitch", "Pop" etc), most likely grabbed by exporting After Effects file to premiere with the proper compositions
//Clips themselves need to be present in the project file
//Clip length is the last object (index=3)
//Offset value (i.e. paste 10 frames previous to current point) is index=2
//Clip name for the loop to check (index=1)


var list = [
    ["Zoom", "Trans1", 24, 55],
    ["Glitch", "GlitchSFX", 24, 39],
    ["Pop", "popEffect", 11, 24],
    ["Arm", "Whoosh_1_Basic", 8, 17],
    ["popHead", "Whoosh_1_Basic", 8, 17],
    ["InfoBox","Whoosh_1_Basic",17,17]
]

//Function to transform ticks to frames (hardcoded to "30")
function toTicks(frames) {
    newval = frames * 254016000000 / 30
    return newval;

}

//"Function checks if there's a clip at the given time. PreRequisite is that the order of clips to be imported is sorted from high to low depending on their clip length."
//This one is only for Audio Imports/tracks
function checkIfOccupied(curTime, durat, track) {
    var val = false;
    //if there are clips on track
    if (track.clips.length != 0) {
        //go through every clip on the track
        for (var clp = 0; clp < track.clips.length; clp++) {

            $.writeln("curTime: " + curTime + ", Op: " + track.clips[clp].end.ticks + ", IP: " + track.clips[clp].start.ticks + " , curTime + durat: " + (curTime + durat))
            //if start point of the "to-be-inserted" clip is in between start and end points of the existing clip->return false
            if (curTime <= track.clips[clp].end.ticks && curTime >= track.clips[clp].start.ticks) {

                val = false;
                break;
                //if end point of the "to-be-inserted" clip is in between start and end points of the existing clip->return false
            } else if ((curTime + durat) >= track.clips[clp].start.ticks && (curTime + durat) <= track.clips[clp].end.ticks) {
                val = false;
                break;
                //otherwise it does not intersect
            } else {
                val = true;
            }

        }
        //if track has 0 clips
    } else {
        val = true;
    }

    return val

}

app.enableQE();

//For Loop that goes through the "list" object and assigns the marker name value ("obj") and clip that is present in the project ("myClip") and assigns those values back to undefined at the beginning
for (var idx = 0; idx < list.length; idx++) {
    var obj = undefined;
    var myClip = undefined;
    for (var i = 0; i < app.projects[0].rootItem.children.length; i++) {
        clip = app.projects[0].rootItem.children[i]
        if (clip.name == list[idx][0]) {
            $.writeln(clip.name)
            obj = clip
        }
        if (clip.name == list[idx][1]) {
            myClip = clip;

        }
    }

    //if obj and myClip have proper values
    if (obj != undefined && myClip != undefined) {

        //get all markers from the nested sequence
        allMarkers = obj.getMarkers()
        seq = app.project.activeSequence
        //go through each marker on the sequence
        for (var j = 0; j < allMarkers.numMarkers; j++) {
            //convert duration to ticks
            var durat = toTicks(list[idx][3]);
            //skip the first 2 tracks and go through each track
            for (var g = 2; g < seq.audioTracks.length; g++) {
                //if not occupied 
                if (checkIfOccupied(allMarkers[j].start.ticks - toTicks(list[idx][2]), durat, seq.audioTracks[g]) == true) {
                    //paste the clip and then break
                    seq.audioTracks[g].insertClip(myClip, (String(allMarkers[j].start.ticks - toTicks(list[idx][2]))))
                    break;
                }

            }
        }

    }
}