Copy link to clipboard
Copied
Greetings. I've come across a HUGE issue with scripting. Being that Premiere Pro is an editing application, it would make sense that you should be able to perform basic editing using scripting. I know you can script a lot of things, but why can't I script making a cut on the timeline? The shortcut is Control+K on windows to add an edit. Can you do this with scripting? I'm not able to find any information on this. Why?
I am versed in programming, but there is no documentation on this.
How can I perform an edit using scripting, please what am I missing? I have the clip saved as a variable called
clip
Also my play head is at 1 second. Why can't I do something like
clip.makeEdit();
Can you please direct me to the correct answer?
Thank you!
>why can't I script making a cut on the timeline?
Because ExtendScript can already add, remove, and change any trackItem.
I'm struggling to see how this is a "HUGE issue"; perhaps walk us through the entire workflow you'd like to support, from the user's perspective, and we can provide better guidance.
After a long time of searching, I found out it was about calling the RAZOR method, which I never new existed. Here is some sample working code:
// Enable Quality Enginering library
app.enableQE();
// Get the active QE sequence
var sqe = qe.project.getActiveSequence();
// We need the playertime, but not in the normal Time() format, but rather in the format "00:00:03:38"
var playerTime = sqe.CTI.timecode;
// QE has a razor method that can be called on a sequence object
// Cut only on track
sqe.getV
...
Copy link to clipboard
Copied
>why can't I script making a cut on the timeline?
Because ExtendScript can already add, remove, and change any trackItem.
I'm struggling to see how this is a "HUGE issue"; perhaps walk us through the entire workflow you'd like to support, from the user's perspective, and we can provide better guidance.
Copy link to clipboard
Copied
I can walk you through the workflow:
Here I can do this currently with scripting:
// This line of code will put the player head at 1 second in my active sequence
app.project.activeSequence.setPlayerPosition("254016000000");
// This line of code will add a marker at 1 second in my active sequence.
app.project.activeSequence.markers.createMarker(1);
// I am struggling to find a solution to ADD A CUT in my active sequence.
??? ??? ???
Maybe the functionality or terminology I am using is incorrect? I don't want to add, remove, or change the trackItem, I just want to split it in 2. The basic functionality I am looking to do is: I would like to split a single clip on my timeline into 2 clips based on where the playhead is. This functionality using ExtendScript at present seems unsupported. I've read a few threads where nobody seems to know, and nobody is willing to provide an accurate answer. I've also been through all the documentation, and looked at the sample panel, but somehow there is nothing. So, any help, or secret, or direction would be appreciated from Adobe.
Thanks again!
Copy link to clipboard
Copied
>I don't want to add, remove, or change the trackItem, I just want to split it in 2
Splitting a trackItem into two, sounds a lot like changing that trackItem. 🙂
>I would like to split a single clip on my timeline into 2 clips based on where the playhead is.
What will that do, for the user?
[There is no single ExtendScript call to accomplish what you're requesting, but given better understanding of the desired effect, perhaps we can provide better / more useful guidance...]
Copy link to clipboard
Copied
That's OK I'll figure it out and post it later.
Copy link to clipboard
Copied
I was able to make something work. Basically you're right, there is no "Cut" or "Add Edit" function available in ExtendScript. Why? I have no idea, since Premiere is an editing program, you think Adobe would make this available, since the "Add Edit" function is under Sequence > Add Edit (Control + K).
So, here is a very basic and heavily commented small piece of code. It just performs a cut at the playhead time, or performs multiple cuts based on a collection of time objects.
Please feel free to read out to me if you have any questions.
// PSUDO-PROGRAMMING CODE STEPS I TOOK JUST TO MAKE A CUT USING EXTENTSCRIPT IN PREMIERE PRO
// 0. get the project item reference from selected clip, clip.projectItem
// 1. get video track that the clip is on
// 2. get the play head position, just incase you want to visualize the cuts being made
// 3. calculate the time of the clip the playhead is over, that will be the in point, and get the out point
// 4. set the project item in point and out point, for video, audio, or all
// 5. insert the clip onto the track at the playhead position track.overwriteClip();
// 6. deselect the track to avoid any issues
function main(cutPositions)
{
var activeSequence = app.project.activeSequence;
if(activeSequence)
{
// get selection of track items
var trackItems = activeSequence.getSelection();
if(trackItems.length > 0)
{
// CAVEAT: linked video and audio track items on the same track,
// example: track item on Video 1 and Audio 1, video track item will appear first in the array.
// however, if video track is on Video 2 and audio track is on Audio 1, audio track item will appear first element in array.
// ARE YOU LOOKING AT ONLY CUTTING VIDEO TRACKS OR AUDIO TRACKS?
// get track item type you want to reference in your selection of track items.
var mediaType = 'Video'; // or 'Audio'
var tracks = (mediaType == 'Video') ? activeSequence.videoTracks : activeSequence.audioTracks;
// remove the track items from the selection you don't want to process
for(var i = 0; i < trackItems.length; i++)
{
var trackItem = trackItems[i];
// we will use the "mediaType" STRING, instead of the "type" INT
// trackItem.mediaType == "Video" or trackItem.mediaType == "Audio"
// INSEAD OF
// trackItem.type == 1 or trackItem.type == 2
// if track item is not the media type you initialized above, then remove it from the array
if(trackItem.mediaType != mediaType)
{
trackItems.splice(trackItems.indexOf(trackItem), 1);
}
}
// loop over all the track items in the new array and do cuts
for(var i = 0; i < trackItems.length; i++)
{
// USE THIS VARIABLE TO PASS INTO OTHER FUNCTIONS TO REFERENCE THE CURRENT TRACK ITEM BEING WORKED ON
var trackItem = trackItems[i];
for(var j = 0; j < tracks.length; j++)
{
var track = tracks[j];
var clips = track.clips;
for(var k = 0; k < clips.length; k++)
{
if(clips[k].name == trackItem.name)
{
trackItem.track = track; // used to store the track that our track item is on
}
}
}
// just check if the track item is on a track, which it should be, if not do nothing
if(trackItem.track == null) return;
// THIS PART IS SUPER IMPORTANT, ADDING 2 TIME OBJECTS TO THE TRACK ITEM FOR REFERENCE LATER
// get the sequence time of the playhead
trackItem.sequencePlayheadPosition = activeSequence.getPlayerPosition();
// get the track item time of the playhead
trackItem.playheadPosition = new Time();
trackItem.playheadPosition.seconds = trackItem.sequencePlayheadPosition.seconds - trackItem.start.seconds + trackItem.inPoint.seconds;
if(cutPositions)
{
// THIS IS PROBABLY WHAT MOST PEOPLE WANT TO DO
cutFromTimeArray(trackItem, cutPositions)
}
else
{
// JUST A BASIC CUT AT THE CURRENT PLAYHEAD POSITION
cutFromPlayhead(trackItem);
}
// deselect the everything and update the UI
var itemsToDeselect = activeSequence.getSelection();
for(var i = 0; i < itemsToDeselect.length; i++)
{
itemsToDeselect[i].setSelected(0, 1);
}
}
}
else
{
alert("Please select a track item (clip) on the timeline");
}
}
}
function cutFromPlayhead(trackItem)
{
// get project item of the selected clip
var projectItem = trackItem.projectItem;
// perform cut at playhead position
projectItem.setInPoint(trackItem.inPoint.ticks, 4);
projectItem.setOutPoint(trackItem.playheadPosition.ticks, 4);
trackItem.track.overwriteClip(projectItem, trackItem.start.ticks);
}
function cutFromTimeArray(trackItem, cutPositions)
{
// get project item of the selected clip
var projectItem = trackItem.projectItem;
for(var cut = 0; cut < cutPositions.length; cut++)
{
// get the sequence time of the cut
var cutPosition = cutPositions[cut];
// move playhead to the cut position
app.project.activeSequence.setPlayerPosition(cutPosition.ticks);
if(cutPosition.seconds <= trackItem.start.seconds || cutPosition.seconds >= trackItem.end.seconds)
{
continue;
}
else
{
// get track item time of the cut position in the sequence
var playheadPosition = new Time();
playheadPosition.seconds = cutPosition.seconds - trackItem.start.seconds + trackItem.inPoint.seconds;
projectItem.setInPoint(trackItem.inPoint.ticks, 4); // 1 for video, 2 for audio, 4 for all
projectItem.setOutPoint(playheadPosition.ticks, 4); // 1 for video, 2 for audio, 4 for all
trackItem.track.overwriteClip(projectItem, trackItem.start.ticks);
}
}
}
// PLEASE COMMENT/UNCOMMENT THE MAIN FUNCTION.
// USE ONE AT A TIME, SINCE EVERYTIME IT IS RUN, IT DESELECTS EVERYTHING
// DO SINGLE CUT AT PLAYHEAD POSITION
var cutPositions = []
cutPositions.push(app.project.activeSequence.getPlayerPosition());
main(cutPositions);
// OR
// MULTI-CUT, MAKE AN ARRAY OF TIME OBJECTS
// in my example, I made 3 cuts, one at the playhead time, the others 1 and 2 seconds after playhead time
var cutPositions = [];
var cut1 = app.project.activeSequence.getPlayerPosition();
cut1.seconds = cut1.seconds + 1; // first cut 1 second after playhead
var cut2 = new Time();
cut2.seconds = cut1.seconds + 1; // 1 second ahead of the first cut
var cut3 = new Time();
cut3.seconds = cut2.seconds + 1; // 1 second ahead of the second cut
cutPositions.push(cut1, cut2, cut3); // put all the cut times (based on sequence/playhead time) into an array
//main(cutPositions);
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Glad you were able to create something, that works for your purposes!
>there is no "Cut" or "Add Edit" function available in ExtendScript. Why?
Because no developer/partner has ever requested such functionality. Of course, that doesn't mean it's not desireable...
That was my motivation for asking what the entire workflow was: your explanation of what you'd like to do was thorough and completely made sense, but I still don't understand why a user would want (or need) ExtendScript to insert an edit, into an existing trackItem.
So, now that your script can programmatically 'cut' an existing trackItem...what does that do, for the user?
Copy link to clipboard
Copied
As one who just added to my plugin a tool that can add more then 300 cut-edits at one run i got by this thread when i searched how can i make it more efficient as it takes about 2 min to do so.
I do get the frustration of creating cuts manually, scanning the whole timeling aggresivly and the general inefficient of the whole thing as its get slower the more cuts you adds (at start adding a single cut takes about 0.18 secounds to do, at the end the most i got is 0.8 to single cut)
The real thing that I think that is slowing me back is the visual updates premiere need to show for all the action needed to create a single cut.
The way i did it is to select the current clip, create a subclip of it with the new in point, moving it to specific bin in the projects(preventimg mass clips in main bin) , then overwriting it on the track right next to the last clip (essentialy deleteing the part between the new in point) , wich cases a leftover clip to generate at the end (as i override with shorter clip) then deleting that leftover clip and all of its audio tracks (as i support for multiple audio per clip), then selecting the new clip i just inserted and going back to top, doint this 300 times seperatly in eval scripts case if not premiere will hang, freeze, and might crash, not the best user exp..
And for you question,
As part of my plugin I added an option to analyze the selected clips outside of premiere then detect "dead areas" in the clip and smartly remove them.. (mostly aimed for youtubers), this is done in premiere and not outside of it to allow "restore" of deleted part by just extanding the current cut at a clip.
It took a 20 min vid and converted it to 6 min long after 1.5min of processing (on wich only 15 sec is the time it took to analyze and 75 sec to premiere cuts)
Copy link to clipboard
Copied
I would love to see the code for this, can you share some parts for us?
Copy link to clipboard
Copied
After a long time of searching, I found out it was about calling the RAZOR method, which I never new existed. Here is some sample working code:
// Enable Quality Enginering library
app.enableQE();
// Get the active QE sequence
var sqe = qe.project.getActiveSequence();
// We need the playertime, but not in the normal Time() format, but rather in the format "00:00:03:38"
var playerTime = sqe.CTI.timecode;
// QE has a razor method that can be called on a sequence object
// Cut only on track
sqe.getVideoTrackAt(0).razor(playerTime);
// Cut on all tracks
sqe.razor(playerTime);
Copy link to clipboard
Copied
QE DOM methods are not supported, and not at all recommended. Glad it works!