My favorites | Sign in
Logo
                
Search
for
Updated Apr 02, 2009 by svollbehr
Labels: Phase-Implementation
ISO14496  
The Programmer's Reference Guide: ISO14496 Class

PHP-Reader Documentation: ISO14496 Class

By svollbehr

Introduction

The 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 Boxes

An 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.

ftyp File Type Box; file type and compatibility
pdin Progressive Download Information Box
moov Movie Box; container for all the metadata
mvhd Movie Header Box; overall declarations
trak Track Box; container for an individual track or stream
tkhd Track Header Box; overall information about the track
tref Track Reference Box
edts Edit Box
elst Edit List Box
mdia Media Box
mdhd Media Header Box; overall information about the media
hdlr Handler Reference Box; declares the media type
minf Media Information Box
vmhd Video Media Header Box; overall information (video track only)
smhd Sound Media Header Box; overall information (sound track only)
hmhd Hint Media Header Box; overall information (hint track only)
nmhd Null Media Header Box; overall information (some tracks only)
dinf Data Information Box
dref Data Reference Box
stbl Sample Table Box
stsd Sample Descriptions Box
stts Decoding Time To Sample Box
ctts Composition Time To Sample Box
stsc Sample To Chunk Box
stsz Sample Size Box
stz2 Compact Sample Size Box
stco Chunk Offset Box; 32-bit
co64 Chunk Ooffset Box; 64-bit
stss Sync Sample Table Box
stsh Shadow Sync Sample Table Box
padb Padding Bits Box
stdp Sample Degradation Priority Box
sdtp Independent and Disposable Samples Box
sbgp Sample To Group Box
sgpd Sample Group Description
subs Sub-Sample Information Box
mvex Movie Extends Box
mehd Movie Extends Header Box
trex Track Extends Box
ipmc IPMP Control Box
moof Movie Fragment Box
mfhd Movie Fragment Header Box
traf Track Fragment Box
tfhd Track Fragment Header Box
trun Track Fragment Run
sdtp Independent and Disposable Samples
sbgp SampleToGroup Box
subs Sub-Sample Information Box
mfra Movie Fragment Random Access Box
tfra Track Fragment Random Access Box
mfro Movie Fragment Random Access Offset Box
mdat Media Data Box
free Free Space Box
skip Free Space Box
udta User Data Box
cprt Copyright Box
meta The Meta Box
hdlr Handler Reference Box; declares the metadata type
dinf Data Information Box
dref Data Reference Box; declares source(s) of metadata items
ipmc IPMP Control Box
iloc Item Location Box
ipro Item Protection Box
sinf Protection Scheme Information Box
frma Original Format Box
imif IPMP Information Box
schm Scheme Type Box
schi Scheme Information Box
iinf Item Information Box
infe Item Information Entry Box
xml XML Box
bxml Binary XML Box
pitm Primary Item Reference Box

Non-Standard Extensions

There 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.

moov Movie Box; container for all the metadata
udta User Data Box
meta The Meta Box
ilst The iTunes/iPod Container Box
©nam Name of the track
©ART Name of the artist
aART Name of the album artist
©alb Name of the album
©grp Grouping
©day Year of publication
trkn Track number (number/total)
disk Disk number (number/total)
tmpo BPM tempo
©wrt Name of the composer
©cmt Comments
©gen Genre as string
gnre Genre as an ID3v1 code, added by one
cpil Part of a compilation (0/1)
tvsh Name of the (television) show
sonm Sort name of the track
soar Sort name of the artist
soaa Sort name of the album artist
soal Sort name of the album
soco Sort name of the composer
sosn Sort name of the show
©lyr Lyrics
covr Cover (or other) artwork binary data
©too Information about the software
id32 The ID3v2 Tag Box

Examples

Example #1: How to read ISO 14496 file information

The 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 brand

There 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 boxes

Note 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 information

Apple 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 information

MP4 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 file

The 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 time

Parsing 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, inclusive

See 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
Hosted by Google Code