See: Description
| Package | Description |
|---|---|
| tv.amwa.maj.constant |
Defines constant values used throughout the MAJ API and defined by external specifications.
|
| tv.amwa.maj.enumeration |
Defines Java enumerations representing the enumerations specified in the AAF object
specification and other enumerations used across the MAJ API.
|
| tv.amwa.maj.example |
Example code demonstrating the use of the MAJ API.
|
| tv.amwa.maj.exception |
Specific exceptions thrown due to exceptional behaviour during the execution of method calls
from the MAJ API.
|
| tv.amwa.maj.extensions.avid | |
| tv.amwa.maj.extensions.avid.impl | |
| tv.amwa.maj.extensions.example |
Example code demonstrating an extension built with the
auto generator.
|
| tv.amwa.maj.extensions.example.impl | |
| tv.amwa.maj.extensions.quantel | |
| tv.amwa.maj.extensions.quantel.impl | |
| tv.amwa.maj.extensions.st436 | |
| tv.amwa.maj.extensions.st436.impl | |
| tv.amwa.maj.industry |
Industry for manufacturing, storing and making instances of classes and meta-classes,
referenced by names and registered identifiers.
|
| tv.amwa.maj.integer |
Provides annotations to label that a value of a Java primitive type in the current
context should be interpreted as a particular AAF integer data type.
|
| tv.amwa.maj.io.aaf | |
| tv.amwa.maj.io.file | |
| tv.amwa.maj.io.mxf |
Support for the serialization of AAF data to and from KLV format files and streams according
to the SMPTE MXF standards.
|
| tv.amwa.maj.io.mxf.impl | |
| tv.amwa.maj.io.xml |
Support for the input and output of metadata objects as XML fragments and
documents.
|
| tv.amwa.maj.meta |
Specifications of all the meta-classes of AAF that provides meta-information about classes, properties
and data types.
|
| tv.amwa.maj.meta.impl |
A meta engine providing loosely-coupled class, property and type management services.
|
| tv.amwa.maj.misctype |
Provides annotations that describe the mapping of miscellaneous
AAF data types to Java data types.
|
| tv.amwa.maj.model |
Specifications of all the interchangeable classes of AAF as Java interfaces.
|
| tv.amwa.maj.model.impl |
Implementation of the AAF interchange object classes.
|
| tv.amwa.maj.record |
Specifications of representations of structured values,
such as those of the AAF record data types.
|
| tv.amwa.maj.record.impl |
Implementations of structured values that can be embedded as properties of
entity beans.
|
| tv.amwa.maj.union |
Provides interfaces to a union type representing values which may contain one of many different sub-types.
|
| tv.amwa.maj.union.impl |
Implementations of classes used to package up collections of values as an argument to
a method of the MAJ API.
|
| tv.amwa.maj.util |
Static utility methods and generators used internally by the MAJ API that may also be useful to
applications using the API.
|
This documentation describes the Media Authoring with Java API (MAJ API), some generic media industry and an implementation of the classes of the Advanced Authoring Format specification in Java. The media industry is a general purpose library code for making and manipulating structures defined according to SMPTE registers. The AAF classes are implemented as plain old Java objects (POJOs) and that can be mapped to EJB3-style persistent entities.
This API provides the basis for applications that capture. edit, manage and distribute media according to professional standards. The API provides support for AAF, MXF and Reg-XML file formats. It provides extensions mechanism to allow implementors to extend the core classes to meet new standards or represent private data. This API is being developed as a project of the Advanced Media Workflow Association and is licensed under the Apache 2.0 License. Note, however, that support for manipulating essence with MAJ is currently very limited.
This is a developer's release 1.1.4, a number chosen to indicate the level of object model support similar to the AAF SDK reference implementation. The documentation of all the packages is rich and complete, so worthwhile exploring for a technical person. In particular, media engine, forge, and warehouse are at the heart of the API's capabilities, so it is a good place to start exploring.
This page provides some getting started topics:
An application can be written using the AAF data model from scratch without the need to read or write files. One difference between MAJ and the AAF SDK is that you can write code that uses classes of the AAF model without the need to contain them within a virtual file at runtime. For more details, see the documentation of the industry package.
The starting point is to initialize the local Java virtual machine so that it supports
processing the AAF data model with MediaEngine.initializeAAF().
You can then start creating objects of the AAF data model, including
packages, tracks,
sequences and source clips,
using the make... methods of the @linkplain tv.amwa.maj.industry.Forge forge}, for example
make(Class, Object...).
Every class in MAJ provides a registered XML representation as its toString()
output, which in turn is created by
MediaEngine.toString(MetadataObject).
This make debugging fairly easy as you can query a value in the debugger and see a human-readable XML format.
To help you get started, here is a code example:
package tv.amwa.maj.example;
import tv.amwa.maj.industry.Forge;
import tv.amwa.maj.industry.MediaEngine;
import tv.amwa.maj.model.*;
public class AMWADemoClass
implements tv.amwa.maj.constant.CommonConstants {
public static void main(String[] args) throws Exception {
MediaEngine.initializeAAF(); // Required to initialize AAF specified classes
MaterialPackage amwaPackage = Forge.makeByName(
AAF_XML_NAMESPACE, "MaterialPackage",
"PackageID", Forge.randomUMID(), // Randomly generated
"Name", "AMWADemoPackage",
"PackageLastModified", Forge.now(),
"CreationTime", Forge.now());
Sequence amwaVideoSequence = Forge.makeByName(
AAF_XML_NAMESPACE, "Sequence",
"ComponentDataDefinition", "Picture");
amwaVideoSequence.appendComponentObject(
Forge.make(
SourceClip.class,
"ComponentDataDefinition", "Picture",
"ComponentLength", 60l,
"SourcePackageID", "urn:smpte:umid:060c2b34.02051101.01001000.13000000.11ee08d4.040311d4.8e3d0090.27dfca7c",
"SourceTrackID", 1,
"StartPosition", 10l));
TimelineTrack amwaVideoTrack = Forge.make(
TimelineTrack.class,
"TrackID", 1,
"TrackSegment", amwaVideoSequence,
"EditRate", "25/1",
"Origin", 0l);
amwaVideoTrack.setTrackName("AMWA VIDEO TRACK");
amwaPackage.appendPackageTrack(amwaVideoTrack);
amwaPackage.appendPackageUserComment("company", "portability 4 media");
System.out.println(amwaPackage.toString());
}
}
For a more complex example, see the source for the composition example that is part of the AMWA training course.
MXF files, also known as AAF-KLV files, consist of sequence of partitions. Partitions contain
a partition header and may contain metadata, index tables and/or essence data. Support for reading
and writing MXF files is provided in package
tv.amwa.maj.io.mxf.
MXF files contain one or more partitions. The first step in reading an MXF file is to build an in memory cache of the structure of those partitions. To do this:
import tv.amwa.maj.industry.MediaEngine;
import tv.amwa.maj.io.mxf.MXFFactory;
import tv.amwa.maj.io.mxf.MXFFile;
...
MXFFile mxfFile = MXFFactory.readPartitions("filename.mxf");
All MXF files contain a header partition. Most also contain a footer partition. To access these:
import tv.amwa.maj.io.mxf.HeaderPartition; import tv.amwa.maj.io.mxf.FooterPartition; ... HeaderPartition header = mxfFile.getHeaderPartition(); FooterPartition footer = mxfFile.getFooterPartition();
Partitions can contain header metadata and this is split into a primer pack and a preface. The metadata can be read into memory from file using the readHeaderMetadata() method.
If a footer partition is present in an MXF file and it contains header metadata, this version is often the most trusted source for metadata about the file as it was written once the rest of the file is complete. If the footer partition is not present or does not contain header metadata, read the header partition's header metadata.
import tv.amwa.maj.model.Preface;
import tv.amwa.maj.io.mxf.HeaderMetadata;
...
HeaderMetadata headerMD = null;
if ((footer != null) && (footer.hasHeaderMetadata())
headerMD = footer.readHeaderMetadata();
else
headerMD = header.readHeaderMetadata();
Preface preface = headerMD.getPreface();
Methods from the preface interface can be used to interrogate what is in the MXF file, or you
can call toString() on the preface to get an XML representation.
This code is still in development, but it will take the form of an application altering an existing preface, setting it to replace that within existing header metadata and calling a write method. Well structured MXF should have padding at the end of the existing metadata, allowing the existing metadata to be overwritten and extended. Writing will fail if insufficient padding space is available.
An index table maps edit unit indexes to stream offsets in essence containers. This enables the data representing a specific frame of video or audio sample to be located in the file, for example to generate a still frame or carry out a partial restore. Any long GOP structure used to store the essence can also be interrogated to work out a safe point to break a file, e.g. don't forget the previous I-frame!
Any partition may have an index table. To read the index table and find the stream offset to the 10th frame 2nd element, measured in bytes from the beginning of its essence container, use ...
import tv.amwa.maj.io.mxf.IndexTable; ... IndexTable index = footer.readIndexTable(); long tenthFrameOffset = index.streamOffset(10, 2);
Note that in interleaved streams, the element number determines whether it is an edit unit worth of video, audio or data track being referred to. You need to know your stream layout to insert the correct element number.
AAF files, also known as AAF-SS or AAF structured storage files, store AAF structured data in a Microsoft structured storage container. To read and write these files, MAJ uses the Apache POI library version 3.7.
Support for reading
and writing AAF files is provided in package
tv.amwa.maj.io.aaf. MAJ provides a
helper class AAFFactory as a starting point for reading and writing
AAF files.
To read a preface from an AAF file, such as those generated by Avid, use the
AAFFactory#readPreface(java.lang.String) readPreface() method
of the AAFFactory class. For example:
import tv.amwa.maj.io.aaf.AAFFactory;
import tv.amwa.maj.iface.Preface;
import tv.amwa.maj.extensions.avid.AvidFactory;
...
AvidFactory.registerAvidExtensions();
Preface fromAAF = AAFFactory.readPreface("filename.aaf");
Some warning messages will be printed if extensions are unknown. These can be ignored unless the extension data is important to your application.
MAJ supports writing metadata-only AAF files, files that do not contain any essence data. AAF is commonly used as a metadata-only representation so this limitation means MAJ still works in many use cases.
To write an existing preface to an AAF file, make sure the Avid extensions are registered (as for
reading) and use the
AAFFactory#writePreface(tv.amwa.maj.model.Preface, java.lang.String) writePreface()
method of the AAFFactory class.
import tv.amwa.maj.io.AAFFactory; import tv.amwa.maj.iface.Preface; ... Preface prefaceToWrite = ...; AAFFactory.writePreface(prefaceToWrite, "filename.aaf");
MAJ will create a dynamic meta dictionary and, if the preface does not contain a valid dictionary already, add in all the required definitions to make the file valid.
AAF XML files are also known as registered data XML files (SMPTE draft standard 2001). MAJ uses
this format for the return value of toString() methods almost everywhere, so it is easy to get to learn
this format. When you use a debugger and hover over a variable that is a MAJ type, you will see the same XML format.
Support for reading
and writing XML files is provided in package
tv.amwa.maj.io.xml. MAJ provides a helper
class XMLBuilder as a starting point for reading and writing
AAF fragments to and from XML.
The methods the serialize objects to and from XML are useful for providing RESTful and web service interfaces to an AAF-based repository. Reading and writing complete files allows XML to be used in file-based workflows in place of the harder-to-analyse MXF and AAF formats.
To convert a single object and any of its contained strong referenced objects to XML, use method
toXML() methods
of the XML builder.
import tv.amwa.maj.io.xml.XMLBuilder; import tv.amwa.maj.iface.MaterialPackage; ... MaterialPackage material = ...; String packageAsXML = XMLBuilder.toXML(material);
Any objects that implement XMLSerializable or
MetadataObject can be serialized to XML fragments.
To read the XML representation of an object in XML and create an instance in memory,
use either the createFromXML() or
createFromXMLString() methods of the
XML builder.
import tv.amwa.maj.io.xml.XMLBuilder;
import tv.amwa.maj.iface.MaterialPackage;
...
MaterialPackage material =
(MaterialPackage) XMLBulder.createFromXMLString(packageAsXML);
Complete XML files have a root <AAF> root element.
To read a preface from an XML file, register all the required data types and then
use the readPreface()
static method of the XML factory.
import tv.amwa.maj.io.xml.XMLFactory;
import tv.amwa.maj.model.Preface;
....
Preface preface = XMLFactory.readPreface("input_file.xml");
Catch IO exceptions to find out about any problems parsing the XML.
Note that the automatic processing of extension metadata that is not registered with MAJ is not supported in the current version of the MAJ API.
Complete XML files have a root <AAF> root element.
To write a complete Reg XML file, use the
writePreface() static method
of the XML factory.
import tv.amwa.maj.io.xml.XMLFactory; .... XMLFactory.writePreface(preface, "output_file.xml");
The preface will be automatically updated with a correct dictionary and any extensions classes will be added to the output. Note that an application is expected to have added an appropriate identification to the preface to identify the current version of the file before calling this method.
Writing extensions, for example to represent your companies descriptive metadata scheme, can be
achieved by writing Java interfaces and classes that represent those extensions. How to do this
is described in the industry package and
in particular in the description of the MediaClass and
MediaProperty annotations. In fact, if you have some
existing Java beans, annotating them to work as media classes with MAJ may be quite simple.
If writing all that Java is a scary thought, MAJ provides an auto generator that can take an XML description of metadata extensions and create Java package sourcecode that can be compiled and used with MAJ.
Some Avid Media Composer extensions are provided in package
tv.amwa.maj.extensions.avid.
MAJ provides a means for generating Java Persistence API compatible object-relational mappings from its own internal representation of media classes.
MAJ can generate an XML representation of classes, properties and types that it knows about using static method MediaEngine.generateMetaDictionary().
(c)2007-2016 Richard Cartwright, all rights reserved. Licensed under Apache 2 license and subject to the AMWA IPR policy.