Activity › Forums › Adobe After Effects Expressions › Creating comps from folders
-
Creating comps from folders
Posted by Danyl Bernard on July 1, 2020 at 11:17 pmHi all.
I have a project where I have about 60 folders in the project panel, containing comps of generated videos.
Each folders comps needs to be placed one after another in a final composition per folder to create 60 full videos.

How can I create a script that goes through all of the folders in the project window starting from item 2, and adds each folders compositions (not the subfolders) to a new comp named the folder name?
Danyl Bernard replied 5 years, 10 months ago 2 Members · 10 Replies -
10 Replies
-
Filip Vandueren
July 4, 2020 at 2:26 pmI haven’t tested this rigourously yet, but think it will work;
app.beginUndoGroup("Create Comps from Folders");
items = app.project.items;comps_2b_created=[];
for (i=1; i<=items.length; i++) {
item=items[i];// If the item is a folder in the root, whose name begins with "Video "
if (item.parentFolder.id==0 && item.typeName=="Folder" && item.name.indexOf("Video ")==0) {
comp={};
comp.name = item.name;
comp.duration=0;
comp.layers=[];folderItems = item.items;
for (j=1; j<=folderItems.length; j++) {
subFolderItem=folderItems[j];// if the subFolderItem is a direct Child, and is a comp, add it.
if(subFolderItem.parentFolder==item && subFolderItem.typeName=="Composition") {
comp.layers.push(subFolderItem);
comp.duration+=subFolderItem.duration;
}
}
if (comp.layers.length>0) {
comps_2b_created.push(comp);
}
}}
for (c=0; c<comps_2b_created.length; c++) {
comp=comps_2b_created[c];newComp = app.project.items.addComp(
comp.name,
comp.layers[0].width,
comp.layers[0].height,
comp.layers[0].pixelAspect,
comp.duration,
comp.layers[0].frameRate
);
startTimeCounter=0;for (l =0; l<comp.layers.length; l++) {
newLayer = newComp.layers.add(comp.layers[l]);
newLayer.startTime = startTimeCounter;
startTimeCounter+=comp.layers[l].duration;
}
}app.endUndoGroup();
-
Danyl Bernard
July 5, 2020 at 7:20 pmWow, it works fantastic. Thank you!
I’m trying to work through the code here, It seems like the last two lines are where the layers get sequenced.
Earlier, I was working with an expression that would sequence the layers minus thirty frames from the last one, kind of like this
is there a way to do that via scripting as well?Also, how can I make the sequencing start from the second layer? The first layer is an audio track that I don’t want sequenced. I tried creating a new loop and changing the index number, but then it only imports one layer
Thank you!
-
Filip Vandueren
July 5, 2020 at 8:12 pmTo only start sequencing from the second layer, and overal by 30 frames, change one of the last lines of the script:
This:
startTimeCounter+=comp.layers[l].duration;
Should become:
If (l>0) {
startTimeCounter+=comp.layers[l].duration – (30/comp.layers[0].frameRate)
} -
Danyl Bernard
July 5, 2020 at 8:54 pmIt works great, one small issue. Now the comp is the length of the originally imported layers, not the newly moved ones.

Is there a way to trim the comp to the length of the last (top) layer?
Thank you
-
Danyl Bernard
July 5, 2020 at 11:57 pmI’m essentially trying to add something like this to all of the comps which will trim them all to the “longest” layer
var myComp = app.project.activeItem;
var myLayer = myComp.selectedLayers[0];
myComp.duration = myLayer.outPoint; -
Filip Vandueren
July 6, 2020 at 7:21 amYes, I calculated the length in the first loop, so that didn’t take into account that the first one isn’t sequenced, nor the overlap.
Your code would work, but since the last created comp and layer are already in a variable, it can be even simpler in this script: newComp.duration = newLayer.outPoint;
I’ve put it in the right place below:
app.beginUndoGroup("Create Comps from Folders");
items = app.project.items;comps_2b_created=[];
for (i=1; i<=items.length; i++) {
item=items[i];// If the item is a folder in the root, whose name begins with "Video "
if (item.parentFolder.id==0 && item.typeName=="Folder" && item.name.indexOf("Video ")==0) {
comp={};
comp.name = item.name;
comp.duration=0;
comp.layers=[];folderItems = item.items;
for (j=1; j<=folderItems.length; j++) {
subFolderItem=folderItems[j];// if the subFolderItem is a direct Child, and is a comp, add it.
if(subFolderItem.parentFolder==item && subFolderItem.typeName=="Composition") {
comp.layers.push(subFolderItem);
comp.duration+=subFolderItem.duration;
}
}
if (comp.layers.length>0) {
comps_2b_created.push(comp);
}
}}
for (c=0; c<comps_2b_created.length; c++) {
comp=comps_2b_created[c];newComp = app.project.items.addComp(
comp.name,
comp.layers[0].width,
comp.layers[0].height,
comp.layers[0].pixelAspect,
comp.duration,
comp.layers[0].frameRate
);
startTimeCounter=0;for (l =0; l<comp.layers.length; l++) {
newLayer = newComp.layers.add(comp.layers[l]);
newLayer.startTime = startTimeCounter;
if (l>0) {
startTimeCounter+=comp.layers[l].duration - (30/comp.layers[0].frameRate);
}
}
newComp.duration = newLayer.outPoint;
}app.endUndoGroup();
-
Danyl Bernard
July 6, 2020 at 2:33 pmYep, works perfectly now. Thank you so much!
If I could pick your brain one last time, I have a music track in the project bin, that I’d like to add to all of the comps.

Previously, I was using an expression that looped through the bin and added the track to the bottom of the open compMy question is twofold. One, is it possible to loop through the array and add it to all of the comps?
Two, and more difficult. Can the music track have a simple fade expression based on the comp duration, that fades the sound 3 seconds before each comp ends?
Thank you once again
var footageName = "myMusicTrack.wav";
var myProject = app.project;// find the footage item
var myFootage = null;
for (var i = 1; i <= myProject.numItems; i++){
myFootage = myProject.item(i);
if (myFootage.name == footageName && myFootage instanceof FootageItem){
break;
}
}if (myFootage == null){
alert ("Can't find " + footageName);
}else{
myComp.layers.add(myFootage);
}// this moves the newly added layer to the bottom of the panel
var activeItem = app.project.activeItem;
var activeLayers=activeItem.layers;
for(i=1;i<=activeLayers.length;i++){
if(app.project.activeItem.layer(i).selected){
app.project.activeItem.layer(i).moveToEnd();
};};
-
Filip Vandueren
July 6, 2020 at 3:58 pmDo this at the beginning of the script:
var footageName = "myMusicTrack.wav";
var myProject = app.project;// find the footage item
var myFootage = null;
for (var i = 1; i <= myProject.numItems; i++){
myFootage = myProject.item(i);
if (myFootage.name == footageName && myFootage instanceof FootageItem){
break;
}
}if (myFootage == null){
alert ("Can't find " + footageName);
}
Now the myFootage Variable contains the music.
Now after the loop and right after where the duration of the comp gets set (newComp.duration = newLayer.outPoint;)
Add this:
newComp.layers.add(myFootage);
newComp.layers[1].startTime=0;
newComp.layers[1]("Audio")("Audio Levels").setValuesAtTimes([newComp.duration-3, newComp.duration], [[0,0], [-96,-96]]);
// add an ease to the fade
fadeEase = new KeyframeEase(0,100);
newComp.layers[1]("Audio")("Audio Levels").setTemporalEaseAtKey(1,[fadeEase,fadeEase]);
Something like that
-
Danyl Bernard
July 6, 2020 at 11:41 pmInteresting. It seems like it’s still going through the original array, and it ends up adding the music track under every original layer

Any suggestions?
Thanks again
-
Danyl Bernard
July 7, 2020 at 12:06 amNever mind, I was adding it in the wrong place
Thank you so much!
Reply to this Discussion! Login or Sign Up