ADOBE AFTER EFFECTS: Forum Expressions Tutorials Creative Cloud

Script to move keyframes to markers

COW Forums : Adobe After Effects

<< PREVIOUS   •   FAQ   •   VIEW ALL   •   PRINT   •   NEXT >>
Frederic AntoinetteScript to move keyframes to markers
by on Nov 24, 2016 at 10:11:16 pm

I've been trying to do that for a while, and I realise it can only be done through script rather than expression.
the main use is for lip syncing, have used several method including time remap to markers, haracter animator, and autoLipSync from mamo world. The two previous just jump to the shape, and the later uses deformation, but doesn't do it by modifing the shape of a shape layer, and I want to do it with a shape layer, and make it morph towards the next shape instead of jump, or get deform likes its an image instead of a shape.

I tryed to learn scripting but I got way over my head.

So here here is my idea that could make it work:

First I have a shape layer, with all the different mouth shape I want, keyframe and layer markers at each keyframe
I then have a null object with markers labelled same as the shape layer, but the markers are set to where I want each different shape to come. Like that:

Now the script should work like that.
First I select the path property with all the keyframes, and then run the script
The script then ask me which layer are the end results markers, in my case the Null layer

the script then makes a copy of the shape layer,
delete all the keyframes in the selected property, on that copied shape layer
Reads the markers from the Null layer
And copies the value equivalent to that marker from the original layer to the result layer.

here is the result I expect, I've colored circled the keyframe to demonstrate which keyframe is reproduced where;

I'm pretty sure that it can be done, and having the selected property as a variable this could work for any keyframable property, at least i think it should.

I hope I makes sense.
Is there already a script somewhere that can do that? Or can someone help me writing it.


Return to posts index

Frederic AntoinetteRe: Script to move keyframes to markers
by on Nov 28, 2016 at 12:26:23 pm

Wasn't that easy after all,
But spent the whole week end trying to figure it out. if any one is interested
It works only for one property, if some one wants to enhance it to be able to select multiple properties you are welcome to do so.
below is the code.
Maybe someone can clean it up a little, this is the first time I write a script, and I'm pretty happy about the results.

Works like that:
Create your keyframes and add markers to what I call the origin layer.
Create a null and place the markers with there corresponding comment to where you need them.
Select the property from the origin layer and run the script


var myComp = app.project.activeItem; // get the selected layer
var layerIdx = myComp.selectedLayers[0].index; // grab index of selected layer
var layer = myComp.layer(layerIdx); //set the selected layer
var propIdx = layer.selectedProperties.length - 1; //Get how many properties are selected if more than one only the last one is retained, had to do this as for path it always select the group and the path
var prop = layer.selectedProperties[propIdx]; // set variable to point to the last selected propertiies
var oNumMarkers, origList, nL, layerList, mLayer, dupLayer;

layerList = new Array();
origList = new Array();


function dialog(){

// get how many layers there are in the composition
nL = myComp.numLayers;

// create a list of all the comp name for a drop down list
for (var q = 1; q<=nL; q++) {

layerList[layerList.length] = q + " - " + myComp.layer(q).name;

// create the popup window
var myWin = new Window("palette","Select marked layer", undefined);
var dd = myWin.add("dropdownlist",undefined,layerList) ;
dd.selection =layerIdx - 2; // set selection to a layer higher than selected layer (assuming this is where you will placed your marked layer)
var but = myWin.add("button",undefined,"Select Layer");
but.onClick = function () {

// This is where the fun starts
app.beginUndoGroup ("Match keys to markers");

mLayer = myComp.layer(dd.selection.index + 1); // set the layer continaing the final marker in position
oNumMarkers ="Marker").numKeys; // get the total number of markers availble in the original layer

// Create an array containing the value at each marker from the original layer
for (var i = 1; i <=oNumMarkers; i++) {

var name"Marker").keyValue(i).comment;

var time ="Marker").keyTime(i);

var val = prop.valueAtTime(time,true);

origList[origList.length] = {'name': name, 'time': time, 'value': val}


// Duplicate the selected layer, rename the duplicated layer same as original layer. and rename original layer to append Results at the end
// Ended up to be easier to make a copy of the original layer, and then modify the original layer rather that modify the keys from the duplicated layer

dupLayer = layer.duplicate(); =; = + "_Results";
dupLayer.enabled = false; // Disable duplicated layer

// Remove all markers and keyframes from the original layer, safe now since we have duplicated it and have already store all the data it contains in origList array
for (var j = 1; j <=oNumMarkers; j ++){"Marker").removeKey(1);

//Place the correspondies keyframe to the corresponding markers by
// Getting the first marker comment and time
// then looping through origList to find the corresponding comment, and get its value
// finally place that value on in the corresponding properties

for (var k = 1; k <="Marker").numKeys; k ++) {

rName ="Marker").keyValue(k).comment;
rTime ="Marker").keyTime(k);
for (var r = 0; r < oNumMarkers; r++){
if (rName == origList[r].name) {
rVal = origList[r].value;
var mv = new MarkerValue(rName);"Marker").setValueAtTime(rTime,mv);
layer.moveBefore(mLayer); // move the result layer before the layer with the markers


Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 All Rights Reserved