|
ISO14496
The Programmer's Reference Guide: ISO14496 Class
PHP-Reader Documentation: ISO14496 ClassBy svollbehr IntroductionThe ISO14496 class provides a full implementation of the ISO 14496 Part 12 standard, or the ISO Base Media File Format as defined by ISO.org. The ISO Base Media File Format is designed to contain timed media information for a presentation in a flexible, extensible format that facilitates interchange, management, editing, and presentation of the media. This presentation may be local to the system containing the presentation, or may be via a network or other stream delivery mechanism. The file structure is object-oriented; a file can be decomposed into constituent objects very simply, and the structure of the objects inferred directly from their type. The file format is designed to be independent of any particular network protocol while enabling efficient support for them in general. The ISO Base Media File Format is a base format for media file formats such as Apple QuickTime, Apple iTunes AAC, and MPEG-4 Video. The class is capable of parsing all the file information. Table of Contents
Class Information
ISO 14496 Part 12 BoxesAn overall view of the normal encapsulation structure is provided in the following table. The table shows those boxes that may occur at the top-level in the left-most column; indentation is used to show possible containment. Thus, for example, a Track Header Box (tkhd) is found in a Track Box (trak), which is found in a Movie Box (moov). Not all boxes need be used in all files; the mandatory boxes are marked with bold typeface. See the description of the individual boxes for a discussion of what must be assumed if the optional boxes are not present. User data objects shall be placed only in Movie or Track Boxes, and objects using an extended type may be placed in a wide variety of containers, not just the top level.
Non-Standard ExtensionsThere are two non-standard extensions to the ISO 14496 standard that add the ability to include file meta information. Both the boxes reside under moov.udta.meta.
ExamplesExample #1: How to read ISO 14496 file informationThe ISO 14496 Part 12 is an object oriented base file format and thus has all its information in nested boxes. Even the main ISO14496 class is mere a container box, and hence all the box methods apply to it too. Besides the fact that the format is easy to structure with an object oriented language, it also allows readers to skip any boxes they do not know (and thus allow extensions). Accessing information happens mainly by walking the boxes according to the box hierarchy. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
foreach ($isom->getBoxes() as $name => $boxes)
foreach ($boxes as $box)
echo "Box $name\n";The above example prints all the top level boxes found in the file. The file must contain at least ftyp and moov top level boxes to be valid. All the required boxes are marked with bold typeface in the box hierarchy table seen before. A bit more advanced example follows printing object information recursively. <?php
require_once("ISO14496.php");
/**
* Prints ISO 14496-12 box information recursively.
*
* @param ISO14496_Box $box The box where to start.
* @param integer $depth The recursion level the start box is in.
* @return void
*/
function printRecurse($box, $depth = 0) {
foreach ($box->boxes as $name => $boxes) {
foreach ($boxes as $atom) {
echo str_repeat(" ", $depth * 4) . "Atom " . $name . " @ " .
$atom->offset . " of size: " . $atom->size . ", ends @ " .
($atom->offset + $atom->size) . "\n";
if ($atom->isContainer())
printRecurse($atom, $depth + 1);
}
}
}
$isom = new ISO14496("file.(m4a|mp4|..)");
printRecurse($isom);The following example shows how to get the file type information from the ftyp box. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
$ftyp = $isom->getBoxesByIdentifier("ftyp"); // the file type information box
$brand = $ftyp->getMajorBrand(); // the type of data this file contains
$version = $ftyp->getMinorVersion(); // the version number of the brandThere is a simpler way to access the boxes, too, as shown in the example below. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
$duration = $isom->moov->mvhd->duration /
$isom->moov->mvhd->timescale; // will always work, as mvhd is mandatory
$userdata = $isom->moov->udta; // works only if optional udta is present
$trak = $isom->moov->trak; // returns the first mandatory trak box only, or..
$trak = $isom->moov->getBoxesByIdentifier("trak");
// ..an array of trak boxesNote that the shorthands will always return the first box available. If all the boxes need to be returned, one must use the getBoxesByIdentifier method as shown in the example. It is also good idea to check box existence before accessing boxes that might not exist. The following example shows how to properly check for box existence to avoid run time errors. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
if ($isom->hasBox("mdat"))
$mdat = $isom->mdat;
// or ..
if (isset($isom->mdat))
$mdat = $isom->mdat;Since the ISO14496 class supports partial write, accessing a box that is not present will yield into attempt to create it and add it to the containing box. Only ID32 and ILST boxes currently support write, and accessing any other undefined box will give you Warning: Missing argument 1. Example #2: Reading iTunes/iPod tag informationApple has specified an extension to ISO 14496 standard to allow storing of media information. The information is located in an ilst box under moov.udta.meta. The ilst box is a container of other boxes that represent the fields. Each field contains one or more data boxes that represent the field value. Hence, getting all the information from the tag is rather straightforward as illustrated below. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
if (isset($isom->moov->udta->meta->ilst)) {
$ilst = $isom->moov->udta->meta->ilst;
foreach ($ilst->boxes as $name => $boxes)
foreach ($boxes as $box)
echo "$name : {$box->data->value}\n";
} else {
// no tag found
}The type of the value the data box contains is defined in the box flags field. For example, the cover image uses either JPEG (0xd) or PNG (0xe) binary image data. In order to know which, one needs to check the flags. The example below shows how one can echo the cover image data to a browser with the right headers. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
if (isset($isom->moov->udta->meta->ilst)) {
$ilst = $isom->moov->udta->meta->ilst;
if (isset($ilst->covr)) {
if ($ilst->covr->data->hasFlag(ISO14496_Box_DATA::JPEG))
header("Content-Type: image/jpeg");
if ($ilst->covr->data->hasFlag(ISO14496_Box_DATA::PNG))
header("Content-Type: image/png");
echo $ilst->covr->data->value;
} else {
echo "No image";
}
} else {
// no tag found
}Example #3: Reading ID3v2 tag informationMP4 registration authority has specified an extension to ISO 14496 standard to allow storing of media information. The extension uses ID3v2 tag to store the information and only provides with a box to contain the tag data. The tag is located in an id32 box under moov.udta.meta. Its use is hence as easy as getting the tag out, as shown below. <?php
require_once("ID3v2.php");
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)");
if (isset($isom->moov->udta->meta->id32)) {
$id32 = $isom->moov->udta->meta->id32->tag;
// id3 contains an instance of ID3v2 class
} else {
// no tag found
}Please refer to ID3v2 documentation for details on how to get information from the tag. Example #4: Writing changes back to the media fileThe ISO14496 class supports the write operation on both the extension boxes. The example below shows how to add a new ID3v2 tag to ISO base media file. <?php
require_once("ID3v2.php");
require_once("ISO14496.php");
$id3 = new ID3v2();
$id3->tit2->text = "My song";
$id3->tpe1->text = "By me!";
$isom = new ISO14496("file.(m4a|mp4|..)");
$isom->moov->udta->meta->id32->tag = $id3;
$isom->write();The previously written tag can also be edited just as easily, as shown next. <?php
require_once("ID3v2.php");
require_once("ISO14496.php");
if (isset($isom->moov->udta->meta->id32)) {
$id3 =& $isom->moov->udta->meta->id32->tag;
$id3->talb->text = "My album too";
$isom->write();
}Example #5: Optimizing running timeParsing all the boxes can take significant amount of time (as opposed to parsing only what we need). The ISO base media file format is designed to have a lot of tables and lists to ease the decoding process. However, these are only rarely used in a read only web application. Hence, the ISO14496 class also supports the option to limit parsing to a certain level, or node. The base option limits parsing to only boxes that contain the specified minimum base path. The options are passed to the class as an array parameter. <?php
require_once("ISO14496.php");
$isom = new ISO14496("file.(m4a|mp4|..)", array("base" => "moov.udta.meta.id32"));
// the isom only knows boxes under moov.udta.meta.id32, inclusiveSee the class documentation found in the source package for the documentation for all the available boxes and their methods. Also, leave a comment if you come up with an idea for an example that would be nice to have added here! |
Sign in to add a comment