Skip to main content
RichardLalancette
Participating Frequently
September 23, 2013
Answered

How to add custom attributes or properties to compositions and layers

  • September 23, 2013
  • 3 replies
  • 3953 views

Hi all,

Would it be possible to add custom properties to compositions and layers that our exporter would then be able to process?


These would have no visuals in AE but would affect the rendering in our engine.

An example of this would be to add a propery to a layer to indicate it is a password edit text box.

Any leads would be greatly appreciated.

This topic has been closed for replies.
Correct answer Christian Lett

You could try using the built-in XMP metadata. I was playing around with it in an old script to store data in the project without resorting to using text layer hacks and it worked fine.

Two functions - one for writing the data:

function setMetadata(data) {

    var proj = app.project;

 

    if(ExternalObject.AdobeXMPScript == undefined) {

        ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

    }

    var metaData = new XMPMeta(proj.xmpPacket);

    var schemaNS = XMPMeta.getNamespaceURI("MyNamespace");

    if(schemaNS == "" || schemaNS == undefined) {

        schemaNS = XMPMeta.registerNamespace("MyNamespace", "MyNamespace");

    }

    try {

        metaData.setProperty(schemaNS, "MyNamespace:compInQuestion", data.compID);  // Assume these variables are pre-set

        metaData.setProperty(schemaNS, "MyNamespace:layerIndex", data.layerIndex);

        metaData.setProperty(schemaNS, "MyNamespace:dataToStore", data.myData);

    } catch(err) {

        alert(err.toString());

        return -1;

    }

    proj.xmpPacket = metaData.serialize();

}

// To get metadata from within a script, a function like so:

function getMetadata(property) {

    var proj = app.project;

    if(ExternalObject.AdobeXMPScript == undefined) {

        ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

    }

    var metaData = new XMPMeta(proj.xmpPacket);

    var schemaNS = XMPMeta.getNamespaceURI("MyNamespace");

    if(schemaNS == "" || schemaNS == undefined) {

        return undefined;

    }

    var metaValue = metaData.getProperty(schemaNS, property);

    if(!metaValue) {

        return undefined;

    }

    return metaValue.value;

}

Because the XMP functionality is an external object, you should be able to access it from outside a script, such as in a C++ IO plugin.

Christian

3 replies

Christian LettCorrect answer
Inspiring
September 28, 2013

You could try using the built-in XMP metadata. I was playing around with it in an old script to store data in the project without resorting to using text layer hacks and it worked fine.

Two functions - one for writing the data:

function setMetadata(data) {

    var proj = app.project;

 

    if(ExternalObject.AdobeXMPScript == undefined) {

        ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

    }

    var metaData = new XMPMeta(proj.xmpPacket);

    var schemaNS = XMPMeta.getNamespaceURI("MyNamespace");

    if(schemaNS == "" || schemaNS == undefined) {

        schemaNS = XMPMeta.registerNamespace("MyNamespace", "MyNamespace");

    }

    try {

        metaData.setProperty(schemaNS, "MyNamespace:compInQuestion", data.compID);  // Assume these variables are pre-set

        metaData.setProperty(schemaNS, "MyNamespace:layerIndex", data.layerIndex);

        metaData.setProperty(schemaNS, "MyNamespace:dataToStore", data.myData);

    } catch(err) {

        alert(err.toString());

        return -1;

    }

    proj.xmpPacket = metaData.serialize();

}

// To get metadata from within a script, a function like so:

function getMetadata(property) {

    var proj = app.project;

    if(ExternalObject.AdobeXMPScript == undefined) {

        ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript');

    }

    var metaData = new XMPMeta(proj.xmpPacket);

    var schemaNS = XMPMeta.getNamespaceURI("MyNamespace");

    if(schemaNS == "" || schemaNS == undefined) {

        return undefined;

    }

    var metaValue = metaData.getProperty(schemaNS, property);

    if(!metaValue) {

        return undefined;

    }

    return metaValue.value;

}

Because the XMP functionality is an external object, you should be able to access it from outside a script, such as in a C++ IO plugin.

Christian

Legend
February 4, 2015

Hi Christian,

After the setMetadata() method you wrote is executed, will the new schema appear in the Metadata window (Window > Metadata) under the listed 'Project' group?  I thought I might have to go into the panel's context menu "Project Metadata Display...", but after I run your script, I'm not seeing it in there either.  Just curious if it does appear there or not.

UPDATE:  I am able to successfully set and retrieve custom, static, Metadata, but for some reason that data does not show up in the Metadata panel nor in the list of schemas found in "Project Metadata Display...".  I suppose the last resort is to build a custom UI that can display all the Metadata that my script writes, but that seems like overkill.  Any ideas on how to get metadata added to a project file with .setProperty() to display in the Metadata panel?

Thanks,
Arie

Participant
September 24, 2013

I've done a couple things that do more or less what you're asking. You can use either or mix and match as needed.

First is to leave variables as text in an invisible text box within your comp. They can be set or checked programatically and can be on or offscreen. I usually lock mine and keep the layer visible but turn the opacity down to zero (just in case garbage collection might throw the non-rendering elements out.) This allows me to check and set variables or other properties. For testing I can turn up the opacity of my variable layers and see what data the comps are receiving and what they're being set to. It's handy.

The second way which you can use in conjunction with the first method, would be to use the layer name as an instance name for your property. So if you're using text boxes, let's say the comp is named "text_box_comp" but you have two text boxes drawn on screen. You can place them where you want but change the layer names to "text_box_user", "text_box_pass". Then in your renderer, you can see if the layer has user and pass text fields by their layer names and render them appropriately.

Kevin

RichardLalancette
Participating Frequently
September 24, 2013

I was hoping not to hack it up that way, but I was also not expecting there would be a way to do this cleanly either.

Thank you.

Dan Ebberts
Community Expert
Community Expert
September 23, 2013

I'n not sure if this helps, but layers and comps (actually, anything in the project bin) have a seldom-used comment field that may work for your purposes.

Dan