Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Macro? Automating repetitive tasks??

  • Macro? Automating repetitive tasks??

    Posted by Joseph M. morgan on April 17, 2005 at 3:32 pm

    I do quite a bit work turning still photos into movies. I use After-Effects to do some small things like create a little movement, and use the adjust->auto color effect. I need some help automating most of the repetitive work.

    For example, for every photo I:

    1) Create a comp with a similar name to the photo, such as: Mary.JPG (photo name) = MaryJPG (comp name)
    2) Put the photo into the comp
    3) Add the Adjust->Auto Color effect
    4) Resize the photo to near the comp size
    5) Turn on keyframes for Position and Scale

    The composition length is always 6 seconds. After that, the scaling and position will vary according to the picture.

    Can I use expressions to do it??? Is there a better way??? How can I speed up this kind of thing???

    Joe

    Joseph M. morgan replied 20 years ago 3 Members · 7 Replies
  • 7 Replies
  • Nicholas White

    April 17, 2005 at 5:30 pm

    Hey,

    Scripting!

    Check this stuff out, once you get your head around it you’ll be up and running in no time…

    https://www.motionscript.com/ae-scripting/table-of-contents.html
    https://www.aenhancers.com/index.php?c=3&sid=cb1ffafdd5df5108cbabfdf4bdbb63d9

    Take care,

    Nick

  • Joseph M. morgan

    April 17, 2005 at 5:43 pm

    Oh my god… it’s JavaScript! I’ll be right at home (20yr programming veteran)…. thanks a million!

    And… I looked at the AEEnhancers site… and there is a script there I can probably just modify to do what I need…

    Hopefully there will be a relatively good object model reference out there..

    Thanks again…

    Joe

  • Mike Clasby

    April 17, 2005 at 8:23 pm

    If you wanted to share any new scripts, here or at aenchancers, that would be great.

  • Nicholas White

    April 17, 2005 at 8:38 pm

    Hey,

    That’s AWESOME; you’ll probably pick it up in no time. Here’s a link to Adobe’s scripting reference, it’s not easy for a beginner but for someone with some programming experience it probably won’t be too much hassle.

    https://pages.emerson.edu/departments/infotech/web/helpdesk/documentation/2004/aftereffects65/ScriptingGuide.pdf

    There’s a couple of members at the forum here who know an awful lot about scripting, virtually all my questions have been answered : )

    Take care,

    Nick

  • Joseph M. morgan

    April 17, 2005 at 10:05 pm

    Will do… call me lazy… but I became a programmer 20 years ago because I didn’t want to keep doing the same thing over and over again….

    I’ll dig into this right away… and keep everyone up to date.

    Joe

  • Joseph M. morgan

    April 17, 2005 at 10:05 pm

    OK… You’re my hero! Thanks again….

    Joe

  • Joseph M. morgan

    April 20, 2005 at 9:35 pm

    OK…. I finally got to the point I could write this thing… it is a modification of “COMPIFY” from the AE Enhancers web site. However, I made quite a few modifications… most notably:

    1) Added much more white space to make the code easier for ME to read
    2) Changed variable names for more meaningful names for ME.
    3) Added a list of existing folders from which to choose to place the new comps
    4) Added a comp size option
    5) Scaled the still images to as close to the comp scale as possible.
    6) Added some utility functions to simplify making the UI containers so they
    made more sense to ME… that is, ( x, y, width, height ) rather than by using
    the bounds ( left, top, right, bottom ). It also eases the understanding that
    the controls are set relative to the container.

    After I post here, I am going to do some refactoring so the script isn’t so long….

    /* =====================================================================
    * Compify
    * Byron Nash, Edited and Improved by Paul Tuersley
    * October 2004
    *
    * Comp Scaling, Folder destination, Auto Color effect
    * added by Joseph M. Morgan – April 2005
    *
    * Select footage items to be comped or select none to comp all
    * enter a suffix at prompt to be appended to the end of the comp name
    ===================================================================== */
    { // opening brace

    function createWindow(title, x, y, width, height) {
    var window = new Window(‘dialog’, title, [x, y, x + width, y + height]);

    return window;
    }

    function createPanel(container, x, y, width, height, label) {
    var panel = createControl(container, ‘panel’, x, y, width, height, label);

    return panel;
    }

    function createControl(container, type, x, y, width, height, value) {
    var control = container.add(type, [x, y, x + width, y + height], value);

    return control;
    }

    function createDialog() { //function to create the dialog
    var destinationFolderName;

    function onTimeCodeClick() { //enables timecode fields
    rb_TimeCode.value = true;
    rb_Frames.value = false;
    et_Frames.enabled = false;
    et_TimeCodeHours.enabled = true;
    et_TimeCodeMinutes.enabled = true;
    et_TimeCodeSeconds.enabled = true;
    et_TimeCodeFrames.enabled = true;

    et_Rate.enabled = false;
    et_TimeCodeSeconds.active = true;
    }

    function onFrameClick() { //enables frames field
    rb_TimeCode.value = false;
    rb_Frames.value = true;
    et_Frames.enabled = true;
    et_TimeCodeHours.enabled = false;
    et_TimeCodeMinutes.enabled = false;
    et_TimeCodeSeconds.enabled = false;
    et_TimeCodeFrames.enabled = false;

    et_TimeCodeSeconds.active = false;
    et_Frames.enabled = true;
    }

    // ==================================================================
    // added a custom click function so the edittxt box gets highlighted.
    // ==================================================================
    function onCustomClick() {
    et_TimeCodeSeconds.active = false;
    et_Rate.enabled = true;
    }

    // ================================================================
    // Added this code to disable the et_Rate field if
    // any of the frame rate radio buttons are selected except the
    // custom one.
    // ================================================================
    function onRateRBClick() {
    et_Rate.enabled = false;
    }

    // ====================
    // Create dialog window
    // ====================
    var dlg = createWindow(‘Automatic Composition Creation’, 100, 100, 385, 240);

    // =============================================================================
    // Composition Settings Panel – Wraps the Frame Rate, Duration, and Scale Panels
    // =============================================================================
    var compositionSettingsPanel = createPanel(dlg, 5, 5, 375, 155, ‘Composition Settings’);

    // ================
    // Frame Rate Panel
    // ================
    var frameRatePanel = createPanel(compositionSettingsPanel, 5, 15, 150, 135, ‘Frame Rate’);

    // =============================================================
    // add radio buttons for the different frame rates
    // increment the button placement in between creation of buttons
    // =============================================================
    var rb_NTSC = createControl(frameRatePanel, ‘radiobutton’, 5, 15, 90, 15, ‘29.97 [NTSC]’);
    rb_NTSC.value = true;

    var rb_PAL = createControl(frameRatePanel, ‘radiobutton’, 5, 35, 90, 15,’25 [PAL]’);
    var rb_Film = createControl(frameRatePanel, ‘radiobutton’, 5, 55, 50, 15, ’24’);
    var rb_Custom = createControl(frameRatePanel, ‘radiobutton’, 5, 75, 60, 15, ‘Custom’);
    var et_Rate = createControl(frameRatePanel, ‘edittext’, 70, 75, 60, 15, ’30’);
    et_Rate.enabled = false;

    // =======================
    // Duration Settings Panel
    // =======================
    var durationPanel = createPanel(compositionSettingsPanel, 160, 15, 210, 65, ‘Duration’);

    // =========================
    // frames radio and text box
    // =========================
    var rb_Frames = createControl(durationPanel, ‘radiobutton’, 5, 15, 90, 15, ‘Frames’);
    var et_Frames = createControl(durationPanel, ‘edittext’, 100, 15, 90, 15, ‘150’, ”);

    // ==================================================
    // timecode radio and fields for entering in timecode
    // ==================================================
    var rb_TimeCode = createControl(durationPanel, ‘radiobutton’, 5, 35, 90, 15, ‘Timecode’);
    var et_TimeCodeHours = createControl(durationPanel, ‘edittext’, 100, 35, 20, 15, ’00’);
    var et_TimeCodeMinutes = createControl(durationPanel, ‘edittext’, 122, 35, 20, 15, ’00’);
    var et_TimeCodeSeconds = createControl(durationPanel, ‘edittext’, 144, 35, 20, 15, ’06’);
    var et_TimeCodeFrames = createControl(durationPanel, ‘edittext’, 166, 35, 20, 15, ’00’);

    // =====================
    // initialize the values
    // =====================
    rb_TimeCode.value = true;
    rb_Frames.value = false;
    et_Frames.enabled = false;
    et_TimeCodeHours.enabled = true;
    et_TimeCodeMinutes.enabled = true;
    et_TimeCodeSeconds.enabled = true;
    et_TimeCodeFrames.enabled = true;

    // ============
    // Scale Panel
    // ============
    var scalePanel = createPanel(compositionSettingsPanel, 160, 85, 210, 65, ‘Scale’);
    var st_Width = createControl(scalePanel, ‘statictext’, 10, 15, 40, 15, ‘Width’);
    var et_Width = createControl(scalePanel, ‘edittext’, 100, 15, 40, 15, ‘720’);

    var st_Height = createControl(scalePanel, ‘statictext’, 10, 35, 40, 15, ‘Height’);
    var et_Height = createControl(scalePanel, ‘edittext’, 100, 35, 40, 15, ‘480’);

    // ========================================================================================
    // Folder Settings – Locate all the folders first, then build the dialog with radio buttons
    // for the user.
    // ========================================================================================
    var rootFolderItems = currentProject.rootFolder.numItems;
    var folders = new Array();
    var folderCount = 0;

    for (i = 1; i <= rootFolderItems; i++) { var item = currentProject.rootFolder.items[i]; if (item.typeName == "Folder") { folders[folderCount++] = item.name; } } var destFolderPanelHeight = (20 * folderCount) + 20; var folderPanel = createPanel(dlg, 5, 165, 375, destFolderPanelHeight, 'Destination Folder:'); for (i = 0, y = 15; i < folderCount; i++, y += 20) { var radioButton = createControl(folderPanel, 'radiobutton', 10, y, 365, 15, folders[i]); radioButton.onClick = function() { destinationFolderName = this.text; }; // ========================================================== // Enable the first RB and get its name in the event the user // doesn't change the name // ========================================================== if (i == 0) { radioButton.value = true; destinationFolderName = folders[i]; } } // ========================= // buttons for ok and cancel // ========================= buttonPanel = createPanel(dlg, 5, 165 + destFolderPanelHeight + 15, 375, 30, ''); var cb_OK = createControl(buttonPanel, 'button', 110, 5, 75, 20, 'OK'); var cb_Cancel = createControl(buttonPanel, 'button', 190, 5, 75, 20, 'Cancel'); // ========================================================================= // Reset the window size due to dynamic creation of destination folder panel // ========================================================================= dlg.bounds = [5, 5, 385, 220 + destFolderPanelHeight]; // ======================================================= // send clicks to functions for enabling/disabling buttons // ======================================================= rb_TimeCode.onClick = onTimeCodeClick; rb_Frames.onClick = onFrameClick; rb_Custom.onClick = onCustomClick; rb_NTSC.onClick = onRateRBClick; rb_PAL.onClick = onRateRBClick; rb_Film.onClick = onRateRBClick; // ======================================================== // Activate the dialog by showing it... respond to OK click // ======================================================== if (dlg.show() == 1) { var frameRate = 10; var duration = 1; var folder = ""; var scaleWidth; var scaleHeight; // ===================================== // Figure out what frame rate is checked // ===================================== if (rb_NTSC.value == true) { frameRate = 29.97; // NTSC } else if (rb_PAL.value == true) { frameRate = 25; // PAL } else if (rb_Film.value == true) { frameRate = 24; // Film } else if (rb_Custom.value == true) { frameRate = et_Rate.text; // get value from text box } // ================================ // set comp length for still images // ================================ if(rb_Frames.value == true){ duration = et_Frames.text / 30; // take the frames value } else { var h = Number(et_TimeCodeHours.text * 3600); // multiply hours var m = Number(et_TimeCodeMinutes.text * 60); // multiply minutes var s = Number(et_TimeCodeSeconds.text); // multiply seconds var f = Number(et_TimeCodeFrames.text/30); // divide frames duration = h + m + s + f; // add'em up } // =============================================== // Get the scale values.. force them to be numbers // =============================================== scaleWidth = et_Width.text * 1; scaleHeight = et_Height.text * 1; // ============================== // Process the destination folder // ============================== var rootFolderItems = currentProject.rootFolder.numItems; var itemCollection = null; for (i = 1; i <= rootFolderItems; i++) { var item = currentProject.rootFolder.items[i]; if (item.typeName == "Folder" && item.name == destinationFolderName) { itemCollection = item.items; } } if (itemCollection == null) { itemCollection = currentProject.rootFolder.items; } // ===================== // setup array to return // ===================== var returnData = [itemCollection, frameRate, duration, scaleWidth, scaleHeight]; return returnData; } } // ******************************************************************************** // MAIN CODE - ACTUAL EXECUTION BEGINS HERE // ******************************************************************************** clearOutput(); var currentProject = app.project; // Get project // ======================== // call the dialog function // ======================== var userInfo = createDialog(); // ======================================================================================== // NOTE!!!! // by testing if anything was returned by the createDialog function, you know whether // the user ok'ed or cancelled. This main body of the script will only execute if something // was returned (i.e if userInfo isn't null); // ======================================================================================== if (userInfo) { var suffix; var targetItems; // Will hold items to compify var destinationFolder = userInfo[0]; var frameRate = userInfo[1]; var duration = userInfo[2]; var scaleWidth = userInfo[3]; var scaleHeight = userInfo[4]; // ============================================== // create undo group if user didn't cancel dialog // ============================================== app.beginUndoGroup("Compify2"); var projectItems = currentProject.items; // list of items in project writeLn("Compify2: Byron Nash, Paul Tuersley, Joe Morgan"); var createdCompositions = new Array(); // array for storing all the comps made var selectedItems = app.project.selection; // set selected import items to an array if (selectedItems.length > 0) { // check to see if anything is selected
    targetItems = app.project.selection; // if so the use the selection
    }
    else { // if not, use entire project contents
    targetItems = new Array();
    for (j = 0; j < projectItems.length; j++) { // add project list to an array targetItems[j] = projectItems[j + 1]; } } for (i = 0; i <= targetItems.length; i++) { // loop through the project var currentItem = targetItems[i]; if (currentItem instanceof FootageItem) { // check for footage items var fileExtensionPosition = currentItem.name.lastIndexOf("."); // find file extension // ================== // Extract the suffix // ================== suffix = currentItem.name.substring(fileExtensionPosition + 1, currentItem.name.length); // ===================================================== // add suffux to comp name and remove the file extension // ===================================================== var curName = currentItem.name.substring(0, fileExtensionPosition) + suffix; // ======================================================= // Truncate comp name if it exceeds the 31 character limit // ======================================================= if (curName.length > 30) {
    curName = curName.slice(0,29-suffix.length) + suffix;
    }

    // ====================
    // setup comp variables
    // ====================
    var curWidth = currentItem.width;
    var curHeight = currentItem.height;
    var curAspect = currentItem.pixelAspect;
    var curduration = currentItem.duration;
    var curRate = currentItem.frameRate;

    // ==================================================
    // Calcualte the new width and height (scale to comp)
    // ==================================================
    if (curWidth > scaleWidth || curHeight > scaleHeight) {
    var widthRatio = scaleWidth / curWidth;
    var heightRatio = scaleHeight / curHeight;
    var newScale = Math.max(widthRatio, heightRatio) * 100; // preserve 1 to 1 aspect ratio
    }

    // =====================================
    // Handle the duration and rate settings
    // =====================================
    if (curduration == 0) {
    curduration = duration //set duration to dialog value if it is a still image
    }

    if (curRate < 1) { curRate = frameRate //set frame rate to dialog value if it is a still image } // ========================= // create comp and add layer // ========================= var newComposition = destinationFolder.addComp(curName, scaleWidth, scaleHeight, curAspect, curduration, curRate); var layerItems = newComposition.layers; //variable for collection of layer objects in Comp var newLayer = layerItems.add(currentItem); //add layer newLayer.scale.setValue([newScale, newScale]); // Scale it as close to the comp as we can newLayer("Effects").addProperty("Auto Color"); // Add the "Auto Color" effect createdCompositions[createdCompositions.length] = newComposition;//add comp to array } } writeLn("Created " + createdCompositions.length + " Comps"); app.endUndoGroup(); } } //closing

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy