One of the best ways to get started using XMP is to take a look at how Adobe is using it to embed speech-to-text data inside video files using Adobe Premiere.
As Flash Platform devs, the easiest way to get access to the XMP data in a video file created by Adobe Premiere is to make sure you handle the onXMPData callback that NetStream fires (Flash Player 10 only). One way to do this is by extending NetStream and adding a callback handler method that looks like this:
// callback handler inside a NetStream subclass dispatches a custom event that // forwards the xmp data found in the callback handler public function onXMPData( info:Object ):void { dispatchEvent( new XMPEvent( XMPEvent.XMP_STRING, info.data, true ) ); } |
Next you need to make sure you’re listening for the XMPEvent, then load the MPEG-4 AVC / F4V / FLV media:
// pseudo code var video:NetStream = new NetStream( connection ); video.addEventListener( XMPEvent.XMP_STRING, xmpHandler, false, 0, true ); video.play( "h264_captions.f4v" ); |
Now its time to see what XMP looks like. We’ll use the AS3 XMP library that Adobe has up on labs:
private function xmpHandler( e:XMPEvent ):void { // XMPMeta is root data structure for xmp data. Pass in the xmp data // we received from the NetStream callback var xmp:XMPMeta = new XMPMeta( e.xmp ); var xml:XML = xmp.serializeToXML(); trace( xml.toXMLString() ); } |
The output of the previous trace should look something like this (full example xml available here):

As you can see in the example above the much of the XMP information is stored in the Adobe Dynamic Media schema that uses the xmpDM namespace.

XMP itself builds on top of another metadata framework called RDF (Rich Description Framework). You can think of RDF as the raw building blocks or data structures necessary to generically describe data.

The gigantic mess of RDF and XMP namespace elements that need to be mixed and matched can be overwhelming, but keep yer cool–Adobe’s AS3 XMP library makes it relatively simple to parse, modify or create XMP metadata.
First off let’s come to a basic understanding of the core RDF elements used in XMP:
Luckily, Adobe’s AS3 XMP library has a similar ActionScript object data model:
Let’s take a look at the speech-to-text data again and see if we can piece together some of the details.

Now lets see how we could use this information to parse the XMP data and extract values:
private function xmpHandler( e:XMPEvent ):void { var xmp:XMPMeta = new XMPMeta( e.xmp ); // define a namespace that will allow us to "dot down" into the data // the XMP lib provides constants for many of the common XMP schemas var xmpDM:Namespace = XMPConst.xmpDM; // "Tracks" is a Bag array containing XMPStruct types. // Let's take a look at how we can parse out the values in // first XMPStruct. NOTE: All XMP arrays start at 1 rather than 0. var track1:XMPStruct = xmp.xmpDM::Tracks[1]; trace( track1.xmpDM::trackName ); trace( track1.xmpDM::frameRate ); // the second struct contains the array of speech-to-text // markers that we're interested in. var track2:XMPStruct = xmp.xmpDM::Tracks[2]; var markers:XMPArray = track2.xmpDM::markers; var item:XMPStruct; for ( var i:int = 1; i < markers.length + 1; i++ ) { item = markers[i]; // a reference to the current marker of type XMPStruct // now we can simply look at all of the property values for each // item in the array trace( "startTime: " + item.xmpDM::startTime ); trace( "duration: " + item.xmpDM::duration ); trace( "name: " + item.xmpDM::name ); trace( "speaker: " + item.xmpDM::speaker ); trace( "probability: " + item.xmpDM::probability + "\n"); } } |
Ok, so that wasn’t too bad was it? Armed with some basic RDF knowledge, the Adobe AS3 XMP lib actually makes it pretty easy to parse out any XMP metadata you’re likely to run into. But we can do better than that, right? Let’s use the XMP lib and our reverse engineered knowledge of the Adobe XMP Dynamic Media schema to create some XMP marker data from scratch.
private function createXMPMarkers():void { // create an xmp object and create a namespace for the Adobe DynamicMedia schema var xmp:XMPMeta = new XMPMeta(); var xmpDM:Namespace = XMPConst.xmpDM; // create some markers and set some properties var item1:XMPStruct = new XMPStruct(); item1.xmpDM::name = "XMP Standard Schemas"; item1.xmpDM::startTime = 0; item1.xmpDM::duration = 15000; item1.xmpDM::type = "Chapter"; var item2:XMPStruct = new XMPStruct(); item2.xmpDM::name = "Dublin Core schema"; item2.xmpDM::startTime = 0; item2.xmpDM::duration = 9999; item2.xmpDM::type = "Index"; var item3:XMPStruct = new XMPStruct(); item3.xmpDM::name = "XMP Dynamic Media schema"; item3.xmpDM::startTime = 10000; item3.xmpDM::duration = 5000; item3.xmpDM::type = "Index"; var item4:XMPStruct = new XMPStruct(); item4.xmpDM::name = "Specialized Schema"; item4.xmpDM::startTime = 15001; item4.xmpDM::duration = 50000; item4.xmpDM::type = "Chapter"; // create an sequenced array to hold all of the markers var markers:XMPArray = XMPArray.newSeq(); markers.append( item1 ); markers.append( item2 ); markers.append( item3 ); markers.append( item4 ); //Create Tracks Struct var tracks:XMPStruct = new XMPStruct(); tracks.xmpDM::trackName = "TOC Markers"; tracks.xmpDM::markers = markers; // Add the "Tracks" property to the xmp object and set its value equal to the track variable. xmp.xmpDM::Tracks[1] = tracks; var xml:XML = xmp.serializeToXML(); trace( xml.toXMLString() ); } |
That’s it for now kids – y’all should be XMP parsing and generating machines by now. Look for an upcoming tutorial on creating and using custom XMP schemas / namespaces to store application specific metadata in your media files.
The final day of a conference is always brutal. Multiple nights of vendor supplied beer, limited sleep, and a steady river of technical information lead to, well, a sore ass and a limited attention span. Despite this the final day of MAX 08 was solid for moi. Here’s the round up.
I was blown away by the morning session on the Flash Platform’s new text engine. It seems the InDesign team has been hard at work on an AS3 framework called TLF that will be released to labs this Friday. TLF provides enormous framework agnostic (works with Flex or Flash) layout capabilities built on top of Flash Player’s low-level APIs. Very cool stuff that definitely builds on Flash Player’s legend as a cutting edge experience-delivery runtime.
It’s areas like this where you really see the enormous payoff from the Adobe / Macromedia merger. Not many people in the world have the deep typographic and layout knowledge necessary to fully utilize the low level text API’s exposed in Flash Player 10. Adobe, however, has deep roots in type with everything from print drivers, to document formats designed for consistent cross-platform type rendering, to best-of-breed layout tooling. There’s scary potential for the platform when you consider they’ve already delivered Pixel Bender shader effects and are sitting on top of serious video tooling / expertise.
Next I sat in a fantastic Pixel Bender lab put on by the AIF crew. These guys ran the best code oriented lab I’ve ever sat in. I wish I could describe code as clearly and efficiently as these cats–I’d be a code super hero, or an even larger pain in the ass to other developers. Regardless, I should note there’s killer tooling built up around Pixel Bender. A shader language with a code hinting IDE, debugging, breakpoints and export of pbj (bytecode Flash Player 10 runs). Slick stuff–the little girlies over at Adobe should be proud.
I also got to sit in another session on XMP with some silly name like, “Use XMP Metadata to Label, Track, and Manage Assets within Creative Suite.” I’m hoping it was the designerish name that scared everyone off–less than 15 people were in the session. That’s seriously disappointing my fellow meta-nerds. Regardless, Gunar (a Sr. PM with Adobe) gave a super articulate overview of what XMP is, it’s alignment with various industry standards and how it provides tangible benefits throughout the create, edit, publish, deploy and consumption lifecycle. Good stuff that should be mandatory viewing for the lot of you (if only so you can mock my meta fetish).
That’s a wrap for MAX day three. If I get a chance I’ll type up some additional thoughts on the long plane ride home.
Turns out that After Effects will generate markers automatically based on XMP, but you must toggle this feature on in your global preferences.

This would allow you to import a Premiere Pro file with speech-to-text transcription and get markers automatically generated.
