How can I access Composition Markers through a script?
Copy link to clipboard
Copied
I've dug through the docs and object browser, but I can't seem to find a way to get at Composition Markers, even just to read them. Only Layer Markers seem readily accessible. Am I missing something really obvious here, or is there just no interface for getting at this information?
Copy link to clipboard
Copied
Hi c.carlin,
There is no access to composition markers at this time. You can submit a feature request for this support at http://www.adobe.com/go/wish/.
Jeff
Copy link to clipboard
Copied
I'm having the same problem. However according to the newest documentation here: http://help.adobe.com/en_US/aftereffects/cs/using/WS3878526689cb91655866c1103906c6dea-7a0ca.html#WS9... composition markers ARE accessible through script commands.
However using commands like this:
var activeItem = app.project.selection; //after selecting several comps
thisComp = activeItem[0];
alert(thisComp.marker.key(1).time);
...give me an "undefined" error every time. Is there any work around to be able to access comp markers?
Thanks very much for any suggestions at all.
Copy link to clipboard
Copied
I think you're looking at the documentation for expressions (where comp markers are accessible), not scripting (where they are not accessible).
Dan
Copy link to clipboard
Copied
But of course, if they're accessible through expressions then they're accessible through scripts that make use of expressions. Here's an example script:
var activeItem = app.project.activeItem;
var tempNull = activeItem.layers.addNull(activeItem.duration);
var tempPos = tempNull.property("ADBE Transform Group").property("ADBE Position");
tempPos.expression = "x = thisComp.marker.numKeys;[x,0];";
var result = tempPos.value[0];
alert("There are " + result + " comp markers");
for (x = 1; x <= result; x++) {
tempPos.expression = "x = thisComp.marker.key(" + x + ").time;[x,0];";
alert("Marker " + x + " time = " + tempPos.value[0]);
}
tempNull.remove();
Copy link to clipboard
Copied
Wow - first thank you for such a fast reply. Second, thank you for a solution that works! I've never used expressions in scripts before.
Speaking of which, is there a good place to go which explains the ins and outs of using expressions in scripts the way you have? As someone who is barely literate in javascript I'm struggling to thoroughly understand what's going on here:
"x = thisComp.marker.numKeys;[x,0];";
...more specifically the ";[x,0]" part. Sorry if it's a noob question.
Copy link to clipboard
Copied
Using expressions in scripts isn't really any different from using them normally. You are just assembling a string that will be applied as the expression. That expression is two lines (it's good practice to always end lines with a semi-colon) and I could have included a \n (line return character) after the first one so it appears as two lines in the expression editor but it isn't necessary as the semi-colons separate the lines.
I didn't want to apply it to Opacity as that is limited to 0-100, so I'm applying the expression to the Position property but I only actually need one value despite it being a two dimensional property. So the first part grabs the value I'm interested in:
x = thisComp.marker.numKeys;
but I still need to have the result of the expression be an array of two values suitable for the Position property, so I store my value in the X dimension (my use of x as a variable is arbitrary) and just put zero in the Y dimension:
[x,0];
When I then read the value I just read the X dimension (array indexes start from 0):
tempPos.value[0];
Copy link to clipboard
Copied
Ah. I get it now. That's really clever. Thank you for explaining!
Copy link to clipboard
Copied
This is a genius solution to grab comp markers. Thank you for sharing this technique.
Copy link to clipboard
Copied
Awesome, thanks Paul. To grab the comp marker comments as well, I'd suggest to use a text layer:
var tempLayer = app.project.activeItem.layers.addText(app.project.activeItem.duration);
var tempText = tempLayer.property("Text").property("Source Text");
tempText.expression = "thisComp.marker.numKeys;";
var numMarkers = parseInt(tempText.value);
for (var i = 1; i <= numMarkers; i++) {
tempText.expression = "thisComp.marker.key(" + i + ").time;";
var markerTime = parseFloat(tempText.value);
tempText.expression = "thisComp.marker.key(" + i + ").comment;";
var markerComment = tempText.value.toString();
alert("Marker " + i + " time = " + markerTime + ", comment = " + markerComment);
}
tempLayer.remove();
Copy link to clipboard
Copied
Thanks Paul, this is already helpful.
But now I seem to get stuck with trying to get your part of code into the one I already have, one to add every 3 keyframes a marker on a layer.
Example:
on a chosen layer there are 4 markers.
marker 1 is at frame 1
marker 2 is at frame 6
marker 3 is at frame 9
marker 4 is at frame 100
Is there a way to let this code add layers markers from the moment I put the cursor e.g. on frame 10 and stop adding markers when he finds the next marker at frame 100?
(This is the code I would like to add your techniques in:)
var myComp = app.project.activeItem;
var layer = app.project.activeItem.selectedLayers[0];
var value = new MarkerValue("")
app.beginUndoGroup("New Markers")
var t = layer.time;
while (t < layer.outPoint){
var newMarkerKeys = layer.property("Marker").addKey(t);
var theNewMarkers = t += myComp.frameDuration*3;
}
app.endUndoGroup();
Cheers,
Marc
Copy link to clipboard
Copied
As a bonus: here is how to get all the marker's custom property fields:
var pre = "thisComp.marker.key(" + i + ")";
tempText.expression = "m = " + pre + "; s = \"{\"; f = true; for (p in m.parameters) { if (f) { f = false; } else { s += \",\"; } s += \"\\\"\" + p + \"\\\":\\\"\" + m.parameters
+ \"\\\"\"; } s += \"}\"; s";
var params = tempText.value.toString();
var paramsTable = JSON.parse(params);

