Expressions/Scripts/Presets

Moderator: byronnash

 
Avinash Ramanath
Topic Author
Posts: 7
Joined: Wed Apr 19, 2017 4:53 am

rd_Slated to work with precomps/nested comps

Mon Apr 24, 2017 11:44 am

// rd_Slated.jsx
// Copyright (c) 2008-2013 Jeffrey R. Almasol. All rights reserved.
// portfolio: http://www.redefinery.com
//
// Name: rd_Slated
// Version: 1.2
//
// Description:
// This script renders slates, single-frame images of a specific template composition
// whose data is fed by the information in a text file exported from a spreadsheet.
//
// Prerequisites:
//  -- This script requires After Effects CS4 or later.
//
// Usage:
//  1. Run this script.
//  2. Select the project containing the template composition named "comp"
//     to use for the slates.
//  3. Select the tab-delimited data file whose columnar data values match
//      the layer names in the "comp" template.
//  4. Select the output folder into which the slates will be rendered.
//
// The slates will be rendered in Photoshop format.
//
// Notes:
//  -- The machine on which you run the script should have an output module
//  template named "Photoshop", which should be available in the default set
// of templates.
//
// Legal Notices:
// This script is provided "as is," without warranty of any kind, expressed or implied.
// In no event shall the script's author be held liable for any damages arising in any
// way from the use of this script.
//
// This script is excerpted from Adobe After Effects CC Visual Effects and Compositing Studio Techniques by Mark Christiansen.
// (c) 2013. Published by Adobe Press. All rights reserved. A complete chapter on scripting
// by Jeff Almasol is included with the book. Additional scripts are available at
// http://aescripts.com/rd-studio-techniques/



[color=#000000][size=120][font=monospace]
(function rd_Slated()[/font][/size][/color][color=#000000][size=120][font=monospace]
{[/font][/size][/color][color=#000000][size=120][font=monospace]
   // Globals[/font][/size][/color]
   [color=#000000][size=120][font=monospace]
   // Store all constants in a global object, for consolidated organization in ExtendScript Toolkit's Data Browser[/font][/size][/color][color=#000000][size=120][font=monospace]
   var rd_SlatedData = new Object();[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.scriptName = "rd: Slated";[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.scriptTitle = rd_SlatedData.scriptName + " v1.2";[/font][/size][/color]
   [color=#000000][size=120][font=monospace]
   // Various text strings are defined as associative arrays (dictionaries) to support localizability via rd_localize() function[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strTplCompName = {en: "template"};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strSelTplProj = {en: "Select the template project"};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strSelDataFile = {en: "Select the text file containing slate data"};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strSelOutFolder = {en: "Select the output folder for rendered slates"};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strSlatesFolderSuffix = {en: " Slates"};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strErrOpenProj = {en: "Could not open the template project."};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strErrNoTplComp = {en: "Could not find a comp named 'template'."};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strErrCreateOutFolder = {en: "Could not create the output folder."};[/font][/size][/color][color=#000000][size=120][font=monospace]
   rd_SlatedData.strMinAE90 = {en: "This script requires Adobe After Effects CS4 or later."};[/font][/size][/color]
   
   
   
   [color=#000000][size=120][font=monospace]
   // rd_localize()[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Description:[/font][/size][/color][color=#000000][size=120][font=monospace]
   // This function localizes the given string variable based on the current locale.[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Parameters:[/font][/size][/color][color=#000000][size=120][font=monospace]
   //   strVar - The string variable's name.[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Returns:[/font][/size][/color][color=#000000][size=120][font=monospace]
   // String.[/font][/size][/color][color=#000000][size=120][font=monospace]
   //[/font][/size][/color][color=#000000][size=120][font=monospace]
   function rd_localize(strVar)[/font][/size][/color][color=#000000][size=120][font=monospace]
   {[/font][/size][/color][color=#000000][size=120][font=monospace]
      return strVar["en"];[/font][/size][/color][color=#000000][size=120][font=monospace]
   }[/font][/size][/color]
   
   
   
   [color=#000000][size=120][font=monospace]
   // rd_Slated_main()[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Description:[/font][/size][/color][color=#000000][size=120][font=monospace]
   // This function performs the main operation of the script.[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Parameters:[/font][/size][/color][color=#000000][size=120][font=monospace]
   // None.[/font][/size][/color][color=#000000][size=120][font=monospace]
   // [/font][/size][/color][color=#000000][size=120][font=monospace]
   // Returns:[/font][/size][/color][color=#000000][size=120][font=monospace]
   // Nothing.[/font][/size][/color][color=#000000][size=120][font=monospace]
   //[/font][/size][/color][color=#000000][size=120][font=monospace]
   function rd_Slated_main()[/font][/size][/color][color=#000000][size=120][font=monospace]
   {[/font][/size][/color][color=#000000][size=120][font=monospace]
      // Select/open the template project[/font][/size][/color][color=#000000][size=120][font=monospace]
      var projFile = File.openDialog(rd_localize(rd_SlatedData.strSelTplProj));[/font][/size][/color][color=#000000][size=120][font=monospace]
      if ((projFile === null) || !projFile.exists)[/font][/size][/color][color=#000000][size=120][font=monospace]
         return;[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      var proj = app.open(projFile);[/font][/size][/color][color=#000000][size=120][font=monospace]
      if (proj === null)[/font][/size][/color][color=#000000][size=120][font=monospace]
         return;[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Check that the template comp exists[/font][/size][/color][color=#000000][size=120][font=monospace]
      var comp = null;[/font][/size][/color][color=#000000][size=120][font=monospace]
      for (var i=1; i<=proj.numItems; i++)[/font][/size][/color][color=#000000][size=120][font=monospace]
      {[/font][/size][/color][color=#000000][size=120][font=monospace]
         if ((proj.item(i) instanceof CompItem) && (proj.item(i).name === rd_localize(rd_SlatedData.strTplCompName)))[/font][/size][/color][color=#000000][size=120][font=monospace]
         {[/font][/size][/color][color=#000000][size=120][font=monospace]
            comp = proj.item(i);[/font][/size][/color][color=#000000][size=120][font=monospace]
            break;[/font][/size][/color][color=#000000][size=120][font=monospace]
         }[/font][/size][/color][color=#000000][size=120][font=monospace]
      }[/font][/size][/color][color=#000000][size=120][font=monospace]
      // If comp is still null, the comp doesn't exist in the project[/font][/size][/color][color=#000000][size=120][font=monospace]
      if (comp === null)[/font][/size][/color][color=#000000][size=120][font=monospace]
      {[/font][/size][/color][color=#000000][size=120][font=monospace]
         alert(rd_localize(rd_SlatedData.strErrNoTplComp), rd_SlatedData.scriptName);[/font][/size][/color][color=#000000][size=120][font=monospace]
         return;[/font][/size][/color][color=#000000][size=120][font=monospace]
      }[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Select the data file[/font][/size][/color][color=#000000][size=120][font=monospace]
      var dataFile = File.openDialog(rd_localize(rd_SlatedData.strSelDataFile));[/font][/size][/color][color=#000000][size=120][font=monospace]
      if ((dataFile === null) || !dataFile.exists)[/font][/size][/color][color=#000000][size=120][font=monospace]
         return;[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Select the folder where the slates will be rendered[/font][/size][/color][color=#000000][size=120][font=monospace]
      var outFolder = Folder.selectDialog(rd_localize(rd_SlatedData.strSelOutFolder));[/font][/size][/color][color=#000000][size=120][font=monospace]
      if (outFolder === null)[/font][/size][/color][color=#000000][size=120][font=monospace]
         return;[/font][/size][/color][color=#000000][size=120][font=monospace]
      // If the folder doesn't exist, create it[/font][/size][/color][color=#000000][size=120][font=monospace]
      if (!outFolder.exists)[/font][/size][/color][color=#000000][size=120][font=monospace]
      {[/font][/size][/color][color=#000000][size=120][font=monospace]
         if (!outFolder.create())[/font][/size][/color][color=#000000][size=120][font=monospace]
         {[/font][/size][/color][color=#000000][size=120][font=monospace]
            alert(rd_localize(rd_SlatedData.strErrCreateOutFolder), rd_SlatedData.scriptName);[/font][/size][/color][color=#000000][size=120][font=monospace]
            return;[/font][/size][/color][color=#000000][size=120][font=monospace]
         }[/font][/size][/color][color=#000000][size=120][font=monospace]
      }[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Build a catalog of layer names for text and footage layers, the types of layers that can be replaced[/font][/size][/color][color=#000000][size=120][font=monospace]
      var layerCat = new Array();[/font][/size][/color][color=#000000][size=120][font=monospace]
      for (var i=1; i<=comp.numLayers; i++)[/font][/size][/color][color=#000000][size=120][font=monospace]
      {[/font][/size][/color][color=#000000][size=120][font=monospace]
         // Look for text (TextLayer) and footage (AVLayer) layers only[/font][/size][/color][color=#000000][size=120][font=monospace]
         var layer = comp.layer(i);[/font][/size][/color][color=#000000][size=120][font=monospace]
         if ((layer instanceof TextLayer) || (layer instanceof AVLayer))[/font][/size][/color][color=#000000][size=120][font=monospace]
         {[/font][/size][/color][color=#000000][size=120][font=monospace]
            var layerName = layer.name;[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Check if the layer's name was previously stored; this allows multiple layers[/font][/size][/color][color=#000000][size=120][font=monospace]
            // to be updated[/font][/size][/color][color=#000000][size=120][font=monospace]
            if (layerCat[layerName] === undefined)[/font][/size][/color][color=#000000][size=120][font=monospace]
            {[/font][/size][/color][color=#000000][size=120][font=monospace]
               // Layer name wasn't previously encountered, so create a new array to store layer indices[/font][/size][/color][color=#000000][size=120][font=monospace]
               layerCat[layerName] = new Array();[/font][/size][/color][color=#000000][size=120][font=monospace]
            }[/font][/size][/color][color=#000000][size=120][font=monospace]
            // Append the current layer's index to the newly created or existing (if same layer name was previously encountered)[/font][/size][/color][color=#000000][size=120][font=monospace]
            layerCat[layerName].push(i);[/font][/size][/color][color=#000000][size=120][font=monospace]
         }[/font][/size][/color][color=#000000][size=120][font=monospace]
      }[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Create a subfolder to place the slate comps and any footage needed for each[/font][/size][/color][color=#000000][size=120][font=monospace]
      // Subfolder name will be based on the data file name[/font][/size][/color][color=#000000][size=120][font=monospace]
      var slatesFolder = app.project.items.addFolder(dataFile.name + rd_localize(rd_SlatedData.strSlatesFolderSuffix));[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Process the lines of text from the data file[/font][/size][/color][color=#000000][size=120][font=monospace]
      // First line should be the field names, tab-separated, with subsequent lines the data[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Open the data file for reading[/font][/size][/color][color=#000000][size=120][font=monospace]
      dataFile.open("r");[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Read the first line, which are the field names[/font][/size][/color][color=#000000][size=120][font=monospace]
      var fields = dataFile.readln();[/font][/size][/color][color=#000000][size=120][font=monospace]
      if (!dataFile.eof)[/font][/size][/color][color=#000000][size=120][font=monospace]
      {[/font][/size][/color][color=#000000][size=120][font=monospace]
         // Split the field string at tab characters[/font][/size][/color][color=#000000][size=120][font=monospace]
         var fieldNames = fields.split("\t");[/font][/size][/color]
         [color=#000000][size=120][font=monospace]
         // Read the rest of the lines, and create slate comps for each[/font][/size][/color]
         [color=#000000][size=120][font=monospace]
         var dataLine, dataValues, layersToUpdate, layerData, currLayer;[/font][/size][/color][color=#000000][size=120][font=monospace]
         while (!dataFile.eof)[/font][/size][/color][color=#000000][size=120][font=monospace]
         {[/font][/size][/color][color=#000000][size=120][font=monospace]
            dataLine = dataFile.readln();[/font][/size][/color][color=#000000][size=120][font=monospace]
            dataValues = dataLine.split("\t");[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Make sure the data line contains the same number of values as there are fields[/font][/size][/color][color=#000000][size=120][font=monospace]
            if (dataValues.length !== fieldNames.length)[/font][/size][/color][color=#000000][size=120][font=monospace]
               continue;[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Duplicate the comp for the current line of data, and move it into the slates folder[/font][/size][/color][color=#000000][size=120][font=monospace]
            var slateComp = comp.duplicate();[/font][/size][/color][color=#000000][size=120][font=monospace]
            slateComp.parentFolder = slatesFolder;[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Name the comp based on the first field's value (hopefully, it's unique)[/font][/size][/color][color=#000000][size=120][font=monospace]
            if (fieldNames.length > 0)[/font][/size][/color][color=#000000][size=120][font=monospace]
               slateComp.name = dataValues[0];[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Loop through the fields and match up the data to the layers[/font][/size][/color][color=#000000][size=120][font=monospace]
            for (var f=0; f<fieldNames.length; f++)[/font][/size][/color][color=#000000][size=120][font=monospace]
            {[/font][/size][/color][color=#000000][size=120][font=monospace]
               // Get the set of layers matching the current field's name[/font][/size][/color][color=#000000][size=120][font=monospace]
               layersToUpdate = layerCat[fieldNames[f]];[/font][/size][/color][color=#000000][size=120][font=monospace]
               // Get the data to use for the field[/font][/size][/color][color=#000000][size=120][font=monospace]
               layerData = dataValues[f];[/font][/size][/color]
               [color=#000000][size=120][font=monospace]
               // Loop through all matching layers, and update their content using the data to use[/font][/size][/color][color=#000000][size=120][font=monospace]
               for (var l=1; l<layersToUpdate.length; l++)[/font][/size][/color][color=#000000][size=120][font=monospace]
               {[/font][/size][/color][color=#000000][size=120][font=monospace]
                  currLayer = slateComp.layer(layersToUpdate[l]);[/font][/size][/color]
                  [color=#000000][size=120][font=monospace]
                  // Depending on the layer type, update as appropriate[/font][/size][/color][color=#000000][size=120][font=monospace]
                  if (currLayer instanceof TextLayer)[/font][/size][/color][color=#000000][size=120][font=monospace]
                  {[/font][/size][/color][color=#000000][size=120][font=monospace]
                     // For a text layer, use the data value as the source text[/font][/size][/color][color=#000000][size=120][font=monospace]
                     currLayer.sourceText.setValue(new TextDocument(layerData));[/font][/size][/color][color=#000000][size=120][font=monospace]
                  }[/font][/size][/color][color=#000000][size=120][font=monospace]
                  else if (currLayer instanceof AVLayer)[/font][/size][/color][color=#000000][size=120][font=monospace]
                  {[/font][/size][/color][color=#000000][size=120][font=monospace]
                     // For a footage layer, import the data value (hopefully is the footage's file name) and replace the source for the layer[/font][/size][/color][color=#000000][size=120][font=monospace]
                     if (File(layerData).exists)[/font][/size][/color][color=#000000][size=120][font=monospace]
                     {[/font][/size][/color][color=#000000][size=120][font=monospace]
                        var fItem = proj.importFile(new ImportOptions(File(layerData)));[/font][/size][/color][color=#000000][size=120][font=monospace]
                        if (fItem !== null)[/font][/size][/color][color=#000000][size=120][font=monospace]
                        {[/font][/size][/color][color=#000000][size=120][font=monospace]
                           // Move footage to the slates folder, then replace the footage layer[/font][/size][/color][color=#000000][size=120][font=monospace]
                           fItem.parentFolder = slatesFolder;[/font][/size][/color][color=#000000][size=120][font=monospace]
                           currLayer.replaceSource(fItem, false);[/font][/size][/color][color=#000000][size=120][font=monospace]
                        }[/font][/size][/color][color=#000000][size=120][font=monospace]
                     }[/font][/size][/color][color=#000000][size=120][font=monospace]
                  }[/font][/size][/color][color=#000000][size=120][font=monospace]
               }[/font][/size][/color][color=#000000][size=120][font=monospace]
            }[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Trim the comp to the first frame of the work area[/font][/size][/color][color=#000000][size=120][font=monospace]
            slateComp.workAreaDuration = slateComp.frameDuration;[/font][/size][/color]
            [color=#000000][size=120][font=monospace]
            // Add the comp to the render queue; use Photoshop output module template[/font][/size][/color][color=#000000][size=120][font=monospace]
            var rqItem = proj.renderQueue.items.add(slateComp);[/font][/size][/color][color=#000000][size=120][font=monospace]
            rqItem.outputModule(1).applyTemplate("Photoshop");[/font][/size][/color][color=#000000][size=120][font=monospace]
            rqItem.outputModule(1).file = new File(outFolder.fsName + "/" + slateComp.name + "_[#####].psd");[/font][/size][/color][color=#000000][size=120][font=monospace]
         }[/font][/size][/color][color=#000000][size=120][font=monospace]
      }[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Close the data file when done[/font][/size][/color][color=#000000][size=120][font=monospace]
      dataFile.close();[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Start the render[/font][/size][/color][color=#000000][size=120][font=monospace]
      proj.renderQueue.render();[/font][/size][/color]
      [color=#000000][size=120][font=monospace]
      // Select only the slates folder[/font][/size][/color][color=#000000][size=120][font=monospace]
      for (var i=1; i&lt;=proj.numItems; i++)[/font][/size][/color][color=#000000][size=120][font=monospace]
         proj.item(i).selected = false;[/font][/size][/color][color=#000000][size=120][font=monospace]
      slatesFolder.selected = true;[/font][/size][/color][color=#000000][size=120][font=monospace]
   }[/font][/size][/color]
   
   
   
   [color=#000000][size=120][font=monospace]
   // main code:[/font][/size][/color][color=#000000][size=120][font=monospace]
   //[/font][/size][/color]
   [color=#000000][size=120][font=monospace]
   // Prerequisite check for After Effects CS4 or later[/font][/size][/color][color=#000000][size=120][font=monospace]
   if (parseFloat(app.version) &lt; 9.0)[/font][/size][/color][color=#000000][size=120][font=monospace]
      alert(rd_localize(rd_SlatedData.strMinAE90), rd_SlatedData.scriptName);[/font][/size][/color][color=#000000][size=120][font=monospace]
   else[/font][/size][/color][color=#000000][size=120][font=monospace]
      rd_Slated_main();[/font][/size][/color][color=#000000][size=120][font=monospace]
})();[/font][/size][/color]


 
Avinash Ramanath
Topic Author
Posts: 7
Joined: Wed Apr 19, 2017 4:53 am

Re: rd_Slated to work with precomps/nested comps

Mon Apr 24, 2017 11:45 am

Could any one of you please make this script work with text and footage when its precomped

Who is online

Users browsing this forum: No registered users and 2 guests