So I just got it to work and the timeline is building nicely. I run the file in Visual Studio Code. VERY CLUNKY. Wish there was an easier way to run it. It uses the ExtendScript Debugger from Adobe that I installed inside VSC as one of its extensions.
Here is the descriptor I have at the beginning of my code.
/*
Adobe Premiere ExtendScript
Auto-populate timeline from scratch
- Deletes existing sequence and bins
- Imports media into fresh bins
- Sets durations in bins (10s and 5s)
- Timeline length: 3:00 minutes (180s)
- Custom preset: “304x176”
- V1: 10s clips at 20s intervals
- V2: 2x 5s clips in gaps, cycling as needed
*/
It is an interesting timeline that draws clips from 2 bins. One is 10 second clips, the other is 5 second. The files all are named with dates on the beginning of the name so they are all sorted and placed on the 3:00 timeline in order. with the 10 second clips leaving space for two 5 second clips to fill in, all the way till it hits 3:00.
It took me 1 or 2 hours to recreate this timeline inside the ViPlex system, now with this Adobe script, it takes me 10 seconds and then I upload a single video file to ViPlex. WOW! I was so amazed at how quickly this turned out to be, I had to come here and post it, just incase someone else could cut it up and use it for their own projects.
Here’s the code.
And if anybody has any easier way to execute jsx code in Premiere, let me know.
Adobe seems to have made it nearly impossible to do with any ease. So painful… But not 2 hours painful…
/*
Adobe Premiere ExtendScript
Auto-populate timeline from scratch
-
Deletes existing sequence and bins
-
Imports media into fresh bins
-
Sets durations in bins (10s and 5s)
-
Timeline length: 3:00 minutes (180s)
-
Custom preset: “304x176”
-
V1: 10s clips at 20s intervals
-
V2: 2x 5s clips in gaps, cycling as needed
*/
var folderAPath = “C:/Adobe Projects/Marquee/Active Slides/Marquee Live Slides/10Sec”;
var folderBPath = “C:/Adobe Projects/Marquee/Active Slides/Marquee Live Slides/5sec”;
var SEQUENCE_LENGTH = 180; // seconds
function buildSequence() {
**var proj = app.project;
**// Sequence name
**var today = new Date();
**var seqName = today.getFullYear() + “-” +
**(“0” + (today.getMonth()+1)).slice(-2) + “-” +
**(“0” + today.getDate()).slice(-2) + “_AutoSequence”;
**// Delete existing sequence and bins
**deleteSequenceByName(seqName);
**deleteBinByName(“10 Sec Clips”);
**deleteBinByName(“5 Sec Clips”);
**// Create fresh bins
**var bin10 = proj.rootItem.createBin(“10 Sec Clips”);
**var bin5 = proj.rootItem.createBin(“5 Sec Clips”);
**// Import files into bins
**importFilesToBin(folderAPath, bin10);
**importFilesToBin(folderBPath, bin5);
**// Wait until bins populate
**waitForBinPopulation(bin10, new Folder(folderAPath).getFiles(/\.(jpg|jpeg|png|mp4|mov)$/i).length);
**waitForBinPopulation(bin5, new Folder(folderBPath).getFiles(/\.(jpg|jpeg|png|mp4|mov)$/i).length);
**// Force durations for all clips in bins
**setClipDurations(bin10, 10); // 10s for Folder A
**setClipDurations(bin5, 5); // 5s for Folder B
**// Get clips from bins
**var clips10 = getClipsFromBin(bin10);
**var clips5 = getClipsFromBin(bin5);
**if (clips10.length === 0 && clips5.length === 0) {
**alert(“No clips found in bins!”);
**return;
**}
**// Create new sequence
**var seq;
**try {
**seq = proj.createNewSequence(seqName, “304x176”);
**} catch(e) {
**alert(“Could not find preset ‘304x176’. Make sure it’s saved.\n” + e);
**return;
**}
**var timeCursor = 0;
**var trackV1 = 0;
**var trackV2 = 1;
**var bIndex = 0;
**// Place 10s clips on V1 every 20s, fill gaps with 2 5s clips
**for (var i = 0; i < clips10.length && timeCursor < SEQUENCE_LENGTH; i++) {
**placeClip(seq.videoTracks[trackV1], clips10[i], timeCursor);
**for (var j = 0; j < 2; j++) {
**if (clips5.length === 0) break;
**var clipB = clips5[bIndex % clips5.length];
**placeClip(seq.videoTracks[trackV2], clipB, timeCursor + 10 + j*5);
**bIndex++;
**}
**timeCursor += 20;
**}
**// Fill remaining time with 5s clips
**while (timeCursor < SEQUENCE_LENGTH && clips5.length > 0) {
**var clipB = clips5[bIndex % clips5.length];
**placeClip(seq.videoTracks[trackV2], clipB, timeCursor);
**timeCursor += 5;
**bIndex++;
**}
**alert(“Sequence '” + seqName + “’ rebuilt from scratch with preset 304x176! Folder A clips = 10s, Folder B clips = 5s. Isn’t Barrett Awesome! BE SURE TO MODIFY THE OPTION FOR FIT TO FRAME BEFORE EXPORTING!”);
}
// ------------------------ Helper Functions ------------------------
function deleteBinByName(binName) {
**var rootItems = app.project.rootItem.children;
**for (var i = rootItems.numItems-1; i >= 0; i–) {
**var item = rootItems[i];
**if (item && item.name === binName && item.type === ProjectItemType.BIN) {
**item.deleteBin();
**return;
**}
**}
}
function deleteSequenceByName(seqName) {
**var proj = app.project;
**for (var i = proj.sequences.numSequences-1; i >= 0; i–) {
**var seq = proj.sequences[i];
**if (seq && seq.name === seqName) {
**app.project.deleteSequence(seq);
**}
**}
}
function importFilesToBin(folderPath, bin) {
**var f = new Folder(folderPath);
**if (!f.exists) return;
**var files = f.getFiles(/\.(jpg|jpeg|png|mp4|mov)$/i).sort(sortByName);
**for (var i = 0; i < files.length; i++) {
**app.project.importFiles([files[i].fsName], 1, bin, 0);
**}
}
function waitForBinPopulation(bin, expectedCount, maxRetries, delayMs) {
**maxRetries = maxRetries || 40;
**delayMs = delayMs || 250;
**var retry = 0;
**while (retry < maxRetries) {
**if (bin.children.numItems >= expectedCount) return true;
**$.sleep(delayMs);
**retry++;
**}
**return false;
}
function setClipDurations(bin, durationSeconds) {
**for (var i = 0; i < bin.children.numItems; i++) {
**var item = bin.children[i];
**if (item && item.type === ProjectItemType.CLIP) {
**try {
**if (item.setOutPoint) {
**item.setOutPoint(durationSeconds, 1); // 1 = seconds
**}
**} catch(e) {}
**}
**}
}
function getClipsFromBin(bin) {
**var clips = ;
**for (var i = 0; i < bin.children.numItems; i++) {
**var item = bin.children[i];
**if (item && item.type === ProjectItemType.CLIP) {
**clips.push(item);
**}
**}
**return clips;
}
// Place clip using its baked-in duration
function placeClip(track, clip, startSeconds) {
**var t = new Time();
**t.seconds = startSeconds;
**track.insertClip(clip, t);
**$.sleep(50); // pause 50ms after placing each clip
}
// Sorting helper
function sortByName(a,b) {
**var an = a.name.toLowerCase();
**var bn = b.name.toLowerCase();
**return (an < bn) ? -1 : (an > bn) ? 1 : 0;
}
// ------------------------ Run Script ------------------------
buildSequence();