Copy link to clipboard
Copied
I have this script which I wrote to reduce a little tedium from my everyday workflow. It takes the selected SWF file in my project window, makes a comp from it, the comp then automatically becomes the active item, the comp is set to 1920x1080, the SWF is resized to fit, and it enables continuous rasterization. It works fine if I run it from the script menu.
// File > New Comp from Selection
app.executeCommand(2796);
// Change active comp size
var activeComp = app.project.activeItem;
activeComp.width = 1920;
activeComp.height = 1080;
// Layer > Transform > Fit To Comp
app.executeCommand(2156);
// Set layer to Continous Rasterization
app.project.activeItem.selectedLayers[0].collapseTransformation = true;
However, I would like to run it from an existing ScriptUI toolbar. I've pasted the script in like so, but it doesn't work…
/////////////////// SWF Setup
myPanel.grp.group12.swfSetup.onClick = function() {
// File > New Comp from Selection
app.executeCommand(2796);
// Change active comp size
var activeComp = app.project.activeItem;
activeComp.width = 1920;
activeComp.height = 1080;
// Layer > Transform > Fit To Comp
app.executeCommand(2156);
// Set layer to Continous Rasterization
app.project.activeItem.selectedLayers[0].collapseTransformation = true;
}
It's worth noting that if I replace the above with something else from another portion of my ScriptUI script, the button works fine. So I know at least that the button is set up correctly. The problem is that it just does nothing when it's written as above.
Also, if I strip this Script UI down to just the first line, app.executeCommand(2796); it does nothing, so I think that is the problem.
1 Correct answer
var myName = myItem.name.substring(0, myItem.name.lastIndexOf("."));
var myComp = app.project.items.addComp(myName, etc
you could just stick myItem.name in your addComp but the above should strip off the extension
substring is a method for taking a range from a string (start char, end char). lastIndexOf returns the last position of the character you specify. This is general javascript so you can just google "javascript string methods" for that stuff, and you'll find a ton of other resources by doi
...Copy link to clipboard
Copied
Took me a while to package this into a script panel (better if you can post it that way for ease of testing) but yes I found the same thing. No new comp is created by the executeCommand. You can easily check this if you set up some debugging, like a $.writeln(app.project.activeItem.name) or even an alert(). You won't get far if you can't track down issues by testing variables and having debugger enabled to get error messages, as scripting is just one coding issue after another.
Relying on executeCommand when there are other options isn't a great idea. It's a hack. You can just use addComp instead then add the footage to it. Same for the Fit To Comp really. Divide comp dimension by footage dimension to get the correct scale.
Why doesn't it work? It could simply be that the focus has moved from the project panel to the script button so that menu command which requires project panel focus no longer works. executeCommand is often pretty fussy about things being set up exactly right.
Copy link to clipboard
Copied
Yeah I figured as much, thanks for the explanation.
So I have now started rebuilding my script, starting with…
Copy link to clipboard
Copied
I would use a variable to grab the item first before creating the comp (gotta be careful about doing things that might change the selection).
Something like:
var myItem = app.project.activeItem;
or taking it from app.project.selection[0];
or you can loop (for var x = 1; x < app.project.numItems; x++) through app.project.items looking for app.project.item(x).selected = true
and if so var myItem = app.project.item(x)
No shortage of options there. Then just:
var myComp = app.project.items.addComp...etc
var myLayer = myComp.layers.add(myItem);
That's all off top of my head so forgive any syntax errors!
There's a pretty big learning curve when first starting scripting. Nothing really makes sense. You don't know enough about enough things to do anything you want to do. Just keep plugging away and eventually it starts to click. If you're not already you should be using something like these as a resource:
https://ae-scripting.docsforadobe.dev
http://www.redefinery.com/ae/fundamentals/
Copy link to clipboard
Copied
Oops my bad:
app.project.item(x).selected = true
will make that item selected, should be:
if (app.project.item(x).selected == true) myItem = app.project.item(x);
= is make equal, == is compare if equal (which returns either true or false)
Anyway you don't really need to loop through to grab your footage. But there's one typical coding error for you!
Copy link to clipboard
Copied
Thanks! For now I've opted to keep it simple. I have a proof of concept version working…
var myItem = app.project.activeItem;
var myComp = app.project.items.addComp('Comp',1920,1080,1,60,24);
var myLayer = myComp.layers.add(myItem);
app.project.item(125).layer(1).transform.scale.setValue([200,200]);
app.project.item(125).layer(1).collapseTransformation = true;
However, I need to make it work for any new comp it creates, rather than for a single ITEM(125) comp. Ideally, the new comp would take the name of the SWF as its name, and then the script would look for a comp named that. I think. I quickly getting out of my depth here.
Copy link to clipboard
Copied
A couple more minutes and I figured out what mistakes I made above.
So this is a more robust working version…
var myItem = app.project.activeItem;
var myComp = app.project.items.addComp('Comp',1920,1080,1,60,24);
myComp.layers.add(myItem);
myComp.layer(1).transform.scale.setValue([200,200]);
myComp.layer(1).collapseTransformation = true;
However, as mentioned above, I would still like the SWF name to be given to the comp name, and for the comp to be added to the current SWF folder rather than the root folder. However, those are minor things. Thanks for getting me this far!
Copy link to clipboard
Copied
var myName = myItem.name.substring(0, myItem.name.lastIndexOf("."));
var myComp = app.project.items.addComp(myName, etc
you could just stick myItem.name in your addComp but the above should strip off the extension
substring is a method for taking a range from a string (start char, end char). lastIndexOf returns the last position of the character you specify. This is general javascript so you can just google "javascript string methods" for that stuff, and you'll find a ton of other resources by doing so.
myComp.parentFolder = myItem.parentFolder;
Copy link to clipboard
Copied
That's great, thank you so so much!
I didn't realize that's how you would capture the name. I'm starting to think a very nice addition might be possible.
Do you know how I could extract only a section of the SWF file name and add that to the name of the comp? The SWF are named following a strict convention, and the characters I need are always 11 through 16. So if the name was "SH_207_ST-01-020_v05_NS.swf" I would only require "01-020" from the name.
I then want to take "01-020" and add it to the comp name like this "COMP_01-020_v01". Note the suffix version number at the end, which will always be "_v01".
And help would be greatly appreciated. No big deal if not, you've helped me plenty already! This would only be the icing on the cake.
Copy link to clipboard
Copied
To prove I'm not completely useless, I did just figure out how to at least add the "COMP_" prefix and "_v01" suffix to the name haha.
var myItem = app.project.activeItem;
var myName = myItem.name.substring(0, myItem.name.lastIndexOf("."));
var myComp = app.project.items.addComp("COMP_"+myName+"_v01",1920,1080,1,60,24);
myComp.layers.add(myItem);
myComp.layer(1).transform.scale.setValue([200,200]);
myComp.layer(1).collapseTransformation = true;
myComp.duration = myComp.layer(1).source.duration;
myComp.parentFolder = myItem.parentFolder;
myComp.openInViewer();
I just need to figure out how to only extract a section of the string instead of the whole name.
Copy link to clipboard
Copied
I'm kinda surprised you didn't figure it out.
myItem.name.substring(10, 16);
Copy link to clipboard
Copied
wow. yeah. thanks again man. this will eventually add up to a big timesaver for me. Anything to sooth the daily grind is worth pursuing!
Copy link to clipboard
Copied
Hey @Paul Tuersley , I wonder if you have a moment to help me refine my script further. I've adapted the script to work for multiple selections by adding a for loop. Now I can select all the SWFs in the scene and hit the button to add them all to a single comp.
However, in order to make this work I've had to disable the rename and parent folder lines at the top, otherwise I get errors. The rename error is "Undefined is not an object", and the parent folder error is "Unable to set parentFolder, undefined is not of the correct type". I assume that when I changed it to app.project.selection it broke those lines because it's no longer referencing a single selection?
The other problem is my 'for loop' for adding SWFs to the comp. My SWF names have a prefix number so that I can easily re-assemble the Flash scene in AE. For example 00_Dog.Swf, 01_Cat.swf, 02_Bird.swf, etc. But the current script places the layer order in reverse order starting with the highest number. It doesn't seem to matter what order I select them in the project window either. How can I reverse this so it runs the correct way around, lowest to highest?
Any help would be appreciated here. Thank you!
var items = app.project.selection;
// Extract characters 11 through 16
// var myName = items.name.substring(10, 16);
// Create comp
var myComp = app.project.items.addComp("COMP_"+myName+"_v01",1920,1080,1,60,24);
// Put comp in the same folder as the selected footage
// myComp.parentFolder = items.parentFolder;
for(var i = 0; i < items.length; i++) {
var myItem = items[i];
// Add selected footage, scale footage, and collapse tranformation
myComp.layers.add(myItem);
myComp.layer(1).transform.scale.setValue([200,200]);
myComp.layer(1).collapseTransformation = true;
}
// Trim comp to duration of footage
myComp.duration = myComp.layer(1).source.duration;
// Deselects all items in the Project window
var selectedItems = app.project.selection;
for (var i = 0; i < selectedItems.length; i++)
selectedItems[i].selected = false;
// Selects the new comp
myComp.selected = true;
// Open comp
myComp.openInViewer();
For reference, this is the previous script which works fine for single selections…
var myItem = app.project.activeItem;
// Extract characters 11 through 16
var myName = myItem.name.substring(10, 16);
// var myName = myItem.name.substring(0, myItem.name.lastIndexOf(".")); // Copies the name, minus the extension
var myComp = app.project.items.addComp("COMP_"+myName+"_v01",1920,1080,1,60,24);
// Add selected footage, scale footage, and collapse tranformation
myComp.layers.add(myItem);
myComp.layer(1).transform.scale.setValue([200,200]);
myComp.layer(1).collapseTransformation = true;
// Trim comp to duration of footage
myComp.duration = myComp.layer(1).source.duration;
// Ensure comp is created in the same folder as the selected footage
myComp.parentFolder = myItem.parentFolder;
// Deselects all items in the Project window
var selectedItems = app.project.selection;
for (var i = 0; i < selectedItems.length; i++) // Note: selection array starts at 0
selectedItems[i].selected = false;
// Selects the new comp
myComp.selected = true;
// Open comp
myComp.openInViewer();
Copy link to clipboard
Copied
myComp.parentFolder = items.parentFolder;
This isn't working because you can't say 'put it in the same folder as all the items' folder'. You can say to put it in one of the item's folder. I assume as you did this they're all in thesame folder?
myComp.parentFolder = items[0].parentFolder;
Same thing for the name. You want the name to be the name of all the selected items? It doesn't make sense. I'm not even sure what you want the comp named after when you're putting multiple items into it. Kinda strange that you realised app.project.selection / myItem was an array of items and figured out how to access the individual items inside it and yet couldn't make this extra leap.
I haven't tested it but from your description app.project.selection is always in the alphabetical sort order of items in the project panel. So one simple way would be to just add the items in reverse order by doing a reverse for loop:
for (var i = items.length-1; i >= 0; i--) {
Alternatively, after you're done tweaking the layer, move it to the bottom of the stack. So at the end of but still inside the for loop:
if (myComp.numLayers > 1) myComp.layer(1).moveToEnd();
Copy link to clipboard
Copied
That reverse for loop worked, thank you.
Re: the renaming, the first part of the footage name is always the same, per episode. Example:
EP_207_ST-09-002_v05 Man.swf
EP_207_ST-09-002_v05 Woman.swf
EP_207_ST-09-002_v05 Dog.swf
I was just hoping that it could access any one of those names to get the section that is always the same.
Re: the parent folder, yes the SWFs are all in the same folder.
Copy link to clipboard
Copied
Ok this works…
var items = app.project.selection;
// Extract characters 11 through 16
var myName = items[0].name.substring(10, 16);
// Create comp
var myComp = app.project.items.addComp("COMP_"+myName+"_v01",1920,1080,1,60,24);
// Put comp in the same folder as the selected footage
myComp.parentFolder = items[0].parentFolder;
// Reverse for loop, so that the numerical layer names are listed correctly 00-99
for (var i = items.length-1; i >= 0; i--) {
var myItem = items[i];
// Remove the first 23 characters from the layer name
var remove23 = myItem.name.substring(23);
// Add selected footage, scale footage, and collapse tranformation
myComp.layers.add(myItem);
myComp.layer(1).transform.scale.setValue([200,200]);
myComp.layer(1).collapseTransformation = true;
myComp.layer(1).name = remove23;
}
// Trim comp to duration of footage
myComp.duration = myComp.layer(1).source.duration;
// Deselects all items in the Project window
var selectedItems = app.project.selection;
for (var i = 0; i < selectedItems.length; i++)
selectedItems[i].selected = false;
// Selects the new comp
myComp.selected = true;
// Open comp
myComp.openInViewer();

