Skip to main content
tomr86207569
Participant
August 9, 2019
Answered

Automating the video file in a comp based on the comps name

  • August 9, 2019
  • 2 replies
  • 811 views

I am working on a project where I have footage of hundreds of trees (exciting I know), a wide and a close up of each. I need to output a comp containing 30 seconds of the wide followed by 30 seconds of the closeup for each tree, as well as a text overlay of the tree number. Is there a way I can automate this instead of creating a comp for each and replacing the footage each time? I am able to link the text to the comp name, I'm not having any luck with the video clips though.

Thanks,

Tom

This topic has been closed for replies.
Correct answer Tomas Sinkunas

Hey. Give this one a shot.

Select an item (or items) in the Project panel (be it A123, or B123 - don't matter) and run the script. Script will:

  • find items for both angles [A123, B123],
  • add both items into the composition,
  • trim layer duration to 30 seconds (feel free to modify this value at the beginning of the script)
  • add a text layer with show number
  • move the second shot and text layer to start at 30 seconds.

(function() {

    var shotDuration = 30;

  

    try {

        app.beginUndoGroup('precompose shots');

        forEachSelectedProjectItem(function(item) {

            if (!item.file) {

                return

            }

            var shotItems = getShotItems(item.name);

            precomposeShots(shotItems);

        });

        app.endUndoGroup();

    } catch (error) {

        alert(error)

    }

    function forEachSelectedProjectItem(callback) {

        var item, selection;

        selection = app.project.selection;

        for (var i = 0, il = selection.length; i < il; i++) {

            item = selection;

            callback(item)

        }

    }

    function getShotItems(itemName) {

        var angles, shotData, shotItem, shotItems, shotToFind;

        shotData = parseShotDataFromString(itemName);

        shotItems = [];

        angles = ['A', 'B'];

        for (var i = 0, il = angles.length; i < il; i++) {

            shotToFind = angles + shotData.number;

            shotItem = findItemByName(shotToFind)

            if (!shotItem) {

                throw new Error('Could not find shot by name ' + shotToFind);

            }

            shotItems.push(shotItem);

        }

        return shotItems;

        function findItemByName(name) {

            var item;

            for (var i = 1, il = app.project.numItems; i <= il; i++) {

                item = app.project.item(i);

                if (item.name === name) {

                    return item;

                }

            }

        }

    }

    function precomposeShots(shots) {

        var composition = buildCompForItem(shots[0]);

        for (var i = 0, il = shots.length; i < il; i++) {

            addItemIntoComposition(shots, composition, i);

        }

        function buildCompForItem(item) {

            var composition, name;

            name = parseShotDataFromString(item.name).number;

            composition = app.project.items.addComp(name, item.width, item.height, item.pixelAspect, 60, item.frameRate);

            composition.openInViewer();

            return composition;

        }

        function addItemIntoComposition(item, composition, index) {

            var layer, textLayer;

            layer = composition.layers.add(item);

            textLayer = addText(composition, item.name);

            layer.startTime = index * shotDuration;

            textLayer.startTime = layer.startTime;

            layer.outPoint = layer.startTime + shotDuration;

            textLayer.outPoint = layer.outPoint;

            composition.duration = layer.outPoint;

            function addText(composition, text) {

                var textDocument, textLayer, textValue;

                textLayer = composition.layers.addText(text);

                textLayer.name = text;

                textDocument = textLayer.property("ADBE Text Properties").property("ADBE Text Document");

                textValue = textDocument.value;

                textValue.font = "Arial-BoldMT";

                textValue.fontSize = 80;

                textValue.fillColor = [1, 1, 1];

                textValue.justification = ParagraphJustification.LEFT_JUSTIFY;

                textDocument.setValue(textValue);

                textLayer.property('ADBE Transform Group').property('ADBE Position').setValue([

                    50,

                    composition.height - 50

                ]);

                return textLayer;

            }

        }

    }

    function parseShotDataFromString(string) {

        var angle, number;

        angle = string.match(/[a-zA-Z]+/g);

        if (angle) {

            angle = angle[0];

        }

        number = string.match(/\d+/g);

        if (number) {

            number = number[0];

        }

        if (!angle || !number) {

            throw new Error('Could not parse angle or number from ' + string);

        }

        return {

            angle: angle,

            number: number,

        }

    }

})();

2 replies

Mathias Moehl
Community Expert
Community Expert
August 11, 2019

This tool might also be helpful:

https://aescripts.com/compsfromspreadsheet/

Mathias Möhl - Developer of tools like BeatEdit and Automation Blocks for Premiere Pro and After Effects
Tomas Sinkunas
Legend
August 9, 2019

Can you post a screenshot of your ptoject structure? Im particulary interested in file names and how wide or closup is named - do they share same name, but have different suffix? Are they in same folder, or different?

tomr86207569
Participant
August 10, 2019

I'm not able to get a screenshot until Monday unfortunately but I can explain how it's currently laid out.

The files are all labelled with a prefix A or B (A for wide, B for closeup) followed by the tree's number. So for example tree 215 has a wide labelled A215.mp4 and a closeup B215.mp4. They are filed in separate folders. I am able to change the naming and folder structure to facilitate automating the process though so that's not set in stone.

Thanks

Tomas Sinkunas
Tomas SinkunasCorrect answer
Legend
August 11, 2019

Hey. Give this one a shot.

Select an item (or items) in the Project panel (be it A123, or B123 - don't matter) and run the script. Script will:

  • find items for both angles [A123, B123],
  • add both items into the composition,
  • trim layer duration to 30 seconds (feel free to modify this value at the beginning of the script)
  • add a text layer with show number
  • move the second shot and text layer to start at 30 seconds.

(function() {

    var shotDuration = 30;

  

    try {

        app.beginUndoGroup('precompose shots');

        forEachSelectedProjectItem(function(item) {

            if (!item.file) {

                return

            }

            var shotItems = getShotItems(item.name);

            precomposeShots(shotItems);

        });

        app.endUndoGroup();

    } catch (error) {

        alert(error)

    }

    function forEachSelectedProjectItem(callback) {

        var item, selection;

        selection = app.project.selection;

        for (var i = 0, il = selection.length; i < il; i++) {

            item = selection;

            callback(item)

        }

    }

    function getShotItems(itemName) {

        var angles, shotData, shotItem, shotItems, shotToFind;

        shotData = parseShotDataFromString(itemName);

        shotItems = [];

        angles = ['A', 'B'];

        for (var i = 0, il = angles.length; i < il; i++) {

            shotToFind = angles + shotData.number;

            shotItem = findItemByName(shotToFind)

            if (!shotItem) {

                throw new Error('Could not find shot by name ' + shotToFind);

            }

            shotItems.push(shotItem);

        }

        return shotItems;

        function findItemByName(name) {

            var item;

            for (var i = 1, il = app.project.numItems; i <= il; i++) {

                item = app.project.item(i);

                if (item.name === name) {

                    return item;

                }

            }

        }

    }

    function precomposeShots(shots) {

        var composition = buildCompForItem(shots[0]);

        for (var i = 0, il = shots.length; i < il; i++) {

            addItemIntoComposition(shots, composition, i);

        }

        function buildCompForItem(item) {

            var composition, name;

            name = parseShotDataFromString(item.name).number;

            composition = app.project.items.addComp(name, item.width, item.height, item.pixelAspect, 60, item.frameRate);

            composition.openInViewer();

            return composition;

        }

        function addItemIntoComposition(item, composition, index) {

            var layer, textLayer;

            layer = composition.layers.add(item);

            textLayer = addText(composition, item.name);

            layer.startTime = index * shotDuration;

            textLayer.startTime = layer.startTime;

            layer.outPoint = layer.startTime + shotDuration;

            textLayer.outPoint = layer.outPoint;

            composition.duration = layer.outPoint;

            function addText(composition, text) {

                var textDocument, textLayer, textValue;

                textLayer = composition.layers.addText(text);

                textLayer.name = text;

                textDocument = textLayer.property("ADBE Text Properties").property("ADBE Text Document");

                textValue = textDocument.value;

                textValue.font = "Arial-BoldMT";

                textValue.fontSize = 80;

                textValue.fillColor = [1, 1, 1];

                textValue.justification = ParagraphJustification.LEFT_JUSTIFY;

                textDocument.setValue(textValue);

                textLayer.property('ADBE Transform Group').property('ADBE Position').setValue([

                    50,

                    composition.height - 50

                ]);

                return textLayer;

            }

        }

    }

    function parseShotDataFromString(string) {

        var angle, number;

        angle = string.match(/[a-zA-Z]+/g);

        if (angle) {

            angle = angle[0];

        }

        number = string.match(/\d+/g);

        if (number) {

            number = number[0];

        }

        if (!angle || !number) {

            throw new Error('Could not parse angle or number from ' + string);

        }

        return {

            angle: angle,

            number: number,

        }

    }

})();