diff --git a/src/ISO14496.php b/src/ISO14496.php
index c3f7cef..60c9887 100644
--- a/src/ISO14496.php
+++ b/src/ISO14496.php
@@ -76,14 +76,20 @@ require_once("ISO14496/Box.php");
* be placed in a wide variety of containers, not just the top level.
*
*
- * - ftyp -- {@link ISO14496_Box_FTYP File Type Box}; file type and compatibility
- *
- pdin -- {@link ISO14496_Box_PDIN Progressive Download Information Box}
- *
- moov -- {@link ISO14496_Box_MOOV Movie Box}; container for all the metadata
+ *
- ftyp -- {@link ISO14496_Box_FTYP File Type Box}; file type
+ * and compatibility
+ *
- pdin -- {@link ISO14496_Box_PDIN Progressive Download Information
+ * Box}
+ *
- moov -- {@link ISO14496_Box_MOOV Movie Box}; container for
+ * all the metadata
*
- * - mvhd -- {@link ISO14496_Box_MVHD Movie Header Box}; overall declarations
- *
- trak -- {@link ISO14496_Box_TRAK Track Box}; container for an individual track or stream
+ *
- mvhd -- {@link ISO14496_Box_MVHD Movie Header Box};
+ * overall declarations
+ *
- trak -- {@link ISO14496_Box_TRAK Track Box}; container
+ * for an individual track or stream
*
- * - tkhd -- {@link ISO14496_Box_TKHD Track Header Box}; overall information about the track
+ *
- tkhd -- {@link ISO14496_Box_TKHD Track Header Box};
+ * overall information about the track
*
- tref -- {@link ISO14496_Box_TREF Track Reference Box}
*
- edts -- {@link ISO14496_Box_EDTS Edit Box}
*
@@ -91,36 +97,57 @@ require_once("ISO14496/Box.php");
*
* - mdia -- {@link ISO14496_Box_MDIA Media Box}
*
- * - mdhd -- {@link ISO14496_Box_MDHD Media Header Box}; overall information about the media
- *
- hdlr -- {@link ISO14496_Box_HDLR Handler Reference Box}; declares the media type
- *
- minf -- {@link ISO14496_Box_MINF Media Information Box}
+ *
- mdhd -- {@link ISO14496_Box_MDHD Media Header Box};
+ * overall information about the media
+ *
- hdlr -- {@link ISO14496_Box_HDLR Handler Reference
+ * Box}; declares the media type
+ *
- minf -- {@link ISO14496_Box_MINF Media Information
+ * Box}
*
- * - vmhd -- {@link ISO14496_Box_VMHD Video Media Header Box}; overall information (video track only)
- *
- smhd -- {@link ISO14496_Box_SMHD Sound Media Header Box}; overall information (sound track only)
- *
- hmhd -- {@link ISO14496_Box_HMHD Hint Media Header Box}; overall information (hint track only)
- *
- nmhd -- {@link ISO14496_Box_NMHD Null Media Header Box}; overall information (some tracks only)
- *
- dinf -- {@link ISO14496_Box_DINF Data Information Box}
+ *
- vmhd -- {@link ISO14496_Box_VMHD Video Media Header Box};
+ * overall information (video track only)
+ *
- smhd -- {@link ISO14496_Box_SMHD Sound Media Header Box};
+ * overall information (sound track only)
+ *
- hmhd -- {@link ISO14496_Box_HMHD Hint Media Header Box};
+ * overall information (hint track only)
+ *
- nmhd -- {@link ISO14496_Box_NMHD Null Media Header Box};
+ * overall information (some tracks only)
+ *
- dinf -- {@link ISO14496_Box_DINF Data Information
+ * Box}
*
- * - dref -- {@link ISO14496_Box_DREF Data Reference Box}
+ *
- dref -- {@link ISO14496_Box_DREF Data Reference
+ * Box}
*
* - stbl -- {@link ISO14496_Box_STBL Sample Table Box}
*
- * - stsd -- {@link ISO14496_Box_STSD Sample Descriptions Box}
- *
- stts -- {@link ISO14496_Box_STTS Decoding Time To Sample Box}
- *
- ctts -- {@link ISO14496_Box_CTTS Composition Time To Sample Box}
- *
- stsc -- {@link ISO14496_Box_STSC Sample To Chunk Box}
+ *
- stsd -- {@link ISO14496_Box_STSD Sample Descriptions
+ * Box}
+ *
- stts -- {@link ISO14496_Box_STTS Decoding Time To
+ * Sample Box}
+ *
- ctts -- {@link ISO14496_Box_CTTS Composition Time To Sample
+ * Box}
+ *
- stsc -- {@link ISO14496_Box_STSC Sample To Chunk
+ * Box}
*
- stsz -- {@link ISO14496_Box_STSZ Sample Size Box}
- *
- stz2 -- {@link ISO14496_Box_STZ2 Compact Sample Size Box}
- *
- stco -- {@link ISO14496_Box_STCO Chunk Offset Box}; 32-bit
- *
- co64 -- {@link ISO14496_Box_CO64 Chunk Ooffset Box}; 64-bit
+ *
- stz2 -- {@link ISO14496_Box_STZ2 Compact Sample Size
+ * Box}
+ *
- stco -- {@link ISO14496_Box_STCO Chunk Offset
+ * Box}; 32-bit
+ *
- co64 -- {@link ISO14496_Box_CO64 Chunk Ooffset Box};
+ * 64-bit
*
- stss -- {@link ISO14496_Box_STSS Sync Sample Table Box}
- *
- stsh -- {@link ISO14496_Box_STSH Shadow Sync Sample Table Box}
+ *
- stsh -- {@link ISO14496_Box_STSH Shadow Sync Sample Table
+ * Box}
*
- padb -- {@link ISO14496_Box_PADB Padding Bits Box}
- *
- stdp -- {@link ISO14496_Box_STDP Sample Degradation Priority Box}
- *
- sdtp -- {@link ISO14496_Box_SDTP Independent and Disposable Samples Box}
+ *
- stdp -- {@link ISO14496_Box_STDP Sample Degradation Priority
+ * Box}
+ *
- sdtp -- {@link ISO14496_Box_SDTP Independent and Disposable
+ * Samples Box}
*
- sbgp -- {@link ISO14496_Box_SBGP Sample To Group Box}
- *
- sgpd -- {@link ISO14496_Box_SGPD Sample Group Description}
- *
- subs -- {@link ISO14496_Box_SUBS Sub-Sample Information Box}
+ *
- sgpd -- {@link ISO14496_Box_SGPD Sample Group
+ * Description}
+ *
- subs -- {@link ISO14496_Box_SUBS Sub-Sample Information
+ * Box}
*
*
*
@@ -134,20 +161,25 @@ require_once("ISO14496/Box.php");
*
* - moof -- {@link ISO14496_Box_MOOF Movie Fragment Box}
*
- * - mfhd -- {@link ISO14496_Box_MFHD Movie Fragment Header Box}
+ *
- mfhd -- {@link ISO14496_Box_MFHD Movie Fragment Header
+ * Box}
*
- traf -- {@link ISO14496_Box_TRAF Track Fragment Box}
*
- * - tfhd -- {@link ISO14496_Box_TFHD Track Fragment Header Box}
+ *
- tfhd -- {@link ISO14496_Box_TFHD Track Fragment Header
+ * Box}
*
- trun -- {@link ISO14496_Box_TRUN Track Fragment Run}
- *
- sdtp -- {@link ISO14496_Box_SDTP Independent and Disposable Samples}
+ *
- sdtp -- {@link ISO14496_Box_SDTP Independent and Disposable
+ * Samples}
*
- sbgp -- {@link ISO14496_Box_SBGP SampleToGroup Box}
*
- subs -- {@link ISO14496_Box_SUBS Sub-Sample Information Box}
*
*
* - mfra -- {@link ISO14496_Box_MFRA Movie Fragment Random Access Box}
*
- * - tfra -- {@link ISO14496_Box_TFRA Track Fragment Random Access Box}
- *
- mfro -- {@link ISO14496_Box_MFRO Movie Fragment Random Access Offset Box}
+ *
- tfra -- {@link ISO14496_Box_TFRA Track Fragment Random Access
+ * Box}
+ *
- mfro -- {@link ISO14496_Box_MFRO Movie Fragment Random Access
+ * Offset Box}
*
* - mdat -- {@link ISO14496_Box_MDAT Media Data Box}
*
- free -- {@link ISO14496_Box_FREE Free Space Box}
@@ -160,16 +192,19 @@ require_once("ISO14496/Box.php");
*
* - meta -- {@link ISO14496_Box_META The Meta Box}
*
- * - hdlr -- {@link ISO14496_Box_HDLR Handler Reference Box}; declares the metadata type
+ *
- hdlr -- {@link ISO14496_Box_HDLR Handler Reference Box};
+ * declares the metadata type
*
- dinf -- {@link ISO14496_Box_DINF Data Information Box}
*
- * - dref -- {@link ISO14496_Box_DREF Data Reference Box}; declares source(s) of metadata items
+ *
- dref -- {@link ISO14496_Box_DREF Data Reference Box}; declares
+ * source(s) of metadata items
*
* - ipmc -- {@link ISO14496_Box_IPMC IPMP Control Box}
*
- iloc -- {@link ISO14496_Box_ILOC Item Location Box}
*
- ipro -- {@link ISO14496_Box_IPRO Item Protection Box}
*
- * - sinf -- {@link ISO14496_Box_SINF Protection Scheme Information Box}
+ *
- sinf -- {@link ISO14496_Box_SINF Protection Scheme Information
+ * Box}
*
* - frma -- {@link ISO14496_Box_FRMA Original Format Box}
*
- imif -- {@link ISO14496_Box_IMIF IPMP Information Box}
@@ -192,11 +227,13 @@ require_once("ISO14496/Box.php");
* moov.udta.meta.
*
*
- * - moov -- {@link ISO14496_Box_MOOV Movie Box}; container for all the metadata
+ *
- moov -- {@link ISO14496_Box_MOOV Movie Box}; container for
+ * all the metadata
*
- udta -- {@link ISO14496_Box_UDTA User Data Box}
*
- meta -- {@link ISO14496_Box_META The Meta Box}
*
- * - ilst -- {@link ISO14496_Box_ILST The iTunes/iPod Tag Container Box}
+ *
- ilst -- {@link ISO14496_Box_ILST The iTunes/iPod Tag Container
+ * Box}
*
- id32 -- {@link ISO14496_Box_ID32 The ID3v2 Box}
*
*
@@ -210,19 +247,134 @@ require_once("ISO14496/Box.php");
*/
class ISO14496 extends ISO14496_Box
{
+ /** @var string */
+ private $_filename;
+
/**
- * Constructs the ISO14496 class with given file.
+ * Constructs the ISO14496 class with given file and options.
+ *
+ * The following options are currently recognized:
+ * o base -- Indicates that only boxes with the given base path are parsed
+ * from the ISO base media file. Parsing all boxes can possibly have a
+ * significant impact on running time. Base path is a list of nested boxes
+ * separated by a dot.
+ * o readonly -- Indicates that the file is read from a temporary location
+ * or another source it cannot be written back to. The use of base option
+ * implies readonly option.
*
* @param string $filename The path to the file or file descriptor of an
* opened file.
+ * @param Array $options The options array.
*/
- public function __construct($filename)
+ public function __construct($filename, $options = array())
{
- $this->_reader = new Reader($filename);
- $this->_offset = 0;
- $this->_size = $this->_reader->getSize();
- $this->_type = "file";
- $this->_container = true;
+ $this->_reader = new Reader($this->_filename = $filename);
+ if (isset($options["base"]))
+ $options["readonly"] = true;
+ $this->setOptions($options);
+ $this->setOffset(0);
+ $this->setSize($this->_reader->getSize());
+ $this->setType("file");
+ $this->setContainer(true);
$this->constructBoxes();
}
+
+ /**
+ * Writes the changes back to the original media file.
+ *
+ * Please note: currently the method writes only ID32 and ILST boxes to
+ * moov.udta.meta. Changes to any other box are discarded. Write
+ * operation will overwrite moov.udta, if found.
+ */
+ public function write()
+ {
+ if (!isset($this->moov->udta->meta->ilst) &&
+ !isset($this->moov->udta->meta->id32))
+ throw new ISO14496_Exception("Nothing to write");
+
+ if ($this->getOption("readonly", false) !== false)
+ throw new ISO14496_Exception("File is read only");
+
+ if (($fd = fopen($this->_filename, file_exists
+ ($this->_filename) ? "r+b" : "wb")) === false)
+ throw new ISO14496_Exception
+ ("Unable to open file for writing: " . $filename);
+
+ $this->moov->udta->meta->hdlr->setHandlerType("mdir");
+
+ /* Calculate start position */
+ $mark = ($this->moov->udta->getOffset() > 0 ?
+ $this->moov->udta->getOffset() :
+ $this->moov->getOffset() + $this->moov->getSize());
+
+ /* Calculate file size */
+ fseek($fd, 0, SEEK_END);
+ $oldFileSize = ftell($fd);
+ $newFileSize = $oldFileSize -
+ ($this->moov->udta->getOffset() > 0 ? $this->moov->udta->getSize() : 0) -
+ (isset($this->moov->udta->meta->free) ?
+ $this->moov->udta->meta->free->getSize() : 0) +
+ strlen($this->moov->udta);
+
+ /* Calculate free space size */
+ if ($oldFileSize < $newFileSize) {
+ // Add free space to the file calculated using the following logaritmic
+ // equation: log(0.2(x + 10)), ranging from 1k to 9k given the file size
+ // of 0..4G
+ $this->moov->udta->meta->free->setSize
+ (ceil(log(0.2 * ($newFileSize / 1024 + 10), 10) * 1024));
+ ftruncate($fd, $newFileSize += $this->moov->udta->meta->free->getSize());
+
+ // Move data to the end of the file
+ for ($i = 1, $cur = $oldFileSize; $cur > $mark; $cur -= 1024, $i++) {
+ fseek($fd, -(($i * 1024) +
+ ($excess = $cur - 1024 > $mark ? 0 : $cur - $mark - 1024) +
+ ($newFileSize - $oldFileSize)), SEEK_END);
+ $buffer = fread($fd, 1024);
+ fseek($fd, -(($i * 1024) + $excess), SEEK_END);
+ fwrite($fd, $buffer, 1024);
+ }
+
+ // Update stco/co64 to correspond the data move
+ foreach ($this->moov->getBoxesByIdentifier("trak") as $trak) {
+ $chunkOffsetBox =
+ (isset($trak->mdia->minf->stbl->stco) ?
+ $trak->mdia->minf->stbl->stco : $trak->mdia->minf->stbl->co64);
+ $chunkOffsetTable = $chunkOffsetBox->getChunkOffsetTable();
+ $chunkOffsetTableCount = count($chunkOffsetTable);
+ $chunkOffsetDelta = $newFileSize - $oldFileSize;
+ for ($i = 1; $i <= $chunkOffsetTableCount; $i++)
+ $chunkOffsetTable[$i] += $chunkOffsetDelta;
+ $chunkOffsetBox->setChunkOffsetTable($chunkOffsetTable);
+ fseek($fd, $chunkOffsetBox->getOffset());
+ fwrite($fd, $chunkOffsetBox, $chunkOffsetBox->getSize());
+ }
+ }
+ else
+ $this->moov->udta->meta->free->setSize($oldFileSize - $newFileSize);
+
+ /* Update the target box */
+ fseek($fd, $mark);
+ $this->moov->udta->setSize(fwrite($fd, $this->moov->udta));
+
+ /* Update the parent box */
+ fseek($fd, $this->moov->getOffset());
+ fwrite($fd, Transform::toUInt32BE($this->moov->getSize()));
+
+ fclose($fd);
+ }
+
+ /**
+ * Returns the raw data of the ISO14496 file.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ if ($this->isContainer())
+ foreach ($this->getBoxes() as $name => $boxes)
+ foreach ($boxes as $box)
+ $data .= $box;
+ return $data;
+ }
}
diff --git a/src/ISO14496/Box.php b/src/ISO14496/Box.php
index a2071ba..a1afffe 100644
--- a/src/ISO14496/Box.php
+++ b/src/ISO14496/Box.php
@@ -58,64 +58,164 @@ class ISO14496_Box
*/
protected $_reader;
- /**
- * The file offset to box start.
- *
- * @var integer
- */
- protected $_offset;
+ /** @var Array */
+ private $_options;
- /**
- * The object size in bytes, including the size and type header, fields, and
- * all contained boxes.
- *
- * @var integer
- */
- protected $_size;
+ /** @var integer */
+ private $_offset = -1;
+
+ /** @var integer */
+ private $_size = -1;
/** @var string */
- protected $_type;
+ private $_type;
+
+
+ /** @var ISO14496_Box */
+ private $_parent = null;
/** @var boolean */
- protected $_container = false;
-
- /**
- * An array of boxes the box contains.
- *
- * @var Array
- */
- protected $_boxes = array();
+ private $_container = false;
+ /** @var Array */
+ private $_boxes = array();
+
+ /** @var Array */
+ private static $_path = array();
/**
* Constructs the class with given parameters.
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- $this->_reader = $reader;
- $this->_offset = $this->_reader->getOffset();
- $this->_size = $this->_reader->readUInt32BE();
- $this->_type = $this->_reader->read(4);
+ if (($this->_reader = $reader) === null) {
+ $this->_type = strtolower(substr(get_class($this), -4));
+ } else {
+ $this->_offset = $this->_reader->getOffset();
+ $this->_size = $this->_reader->readUInt32BE();
+ $this->_type = $this->_reader->read(4);
- if ($this->_size == 1)
- $this->_size = $this->_reader->readInt64BE();
- if ($this->_size == 0)
- $this->_size = $this->_reader->getSize() - $offset;
+ if ($this->_size == 1)
+ $this->_size = $this->_reader->readInt64BE();
+ if ($this->_size == 0)
+ $this->_size = $this->_reader->getSize() - $this->_offset;
- if ($this->_type == "uuid")
- $this->_type = $this->_reader->readGUID();
+ if ($this->_type == "uuid")
+ $this->_type = $this->_reader->readGUID();
+ }
+ $this->_options = $options;
}
/**
- * Returns the type of the ISO base media file object.
+ * Returns the options array.
+ *
+ * @return Array
+ */
+ public function getOptions() { return $this->_options; }
+
+ /**
+ * Returns the given option value, or the default value if the option is not
+ * defined.
+ *
+ * @param string $option The name of the option.
+ * @param mixed $defaultValue The default value to be returned.
+ */
+ public function getOption($option, $defaultValue = false)
+ {
+ if (isset($this->_options[$option]))
+ return $this->_options[$option];
+ return $defaultValue;
+ }
+
+ /**
+ * Sets the options array. See {@link ISO14496} class for available options.
+ *
+ * @param Array $options The options array.
+ */
+ public function setOptions(&$options) { $this->_options = $options; }
+
+ /**
+ * Sets the given option the given value.
+ *
+ * @param string $option The name of the option.
+ * @param mixed $value The value to set for the option.
+ */
+ public function setOption($option, $value)
+ {
+ $this->_options[$option] = $value;
+ }
+
+ /**
+ * Returns the file offset to box start, or -1 if the box was created on heap.
+ *
+ * @return integer
+ */
+ public function getOffset() { return $this->_offset; }
+
+ /**
+ * Sets the file offset where the box starts.
+ *
+ * @param integer $offset The file offset to box start.
+ */
+ public function setOffset($offset) { $this->_offset = $offset; }
+
+ /**
+ * Returns the box size in bytes, including the size and type header,
+ * fields, and all contained boxes, or -1 if the box was created on heap.
+ *
+ * @return integer
+ */
+ public function getSize() { return $this->_size; }
+
+ /**
+ * Sets the box size. The size must include the size and type header,
+ * fields, and all contained boxes.
+ *
+ * The method will propagate size change to box parents.
+ *
+ * @todo Size does not propagate to parent
+ * @param integer $size The box size.
+ */
+ public function setSize($size)
+ {
+ if ($this->_parent !== null)
+ $this->_parent->setSize
+ (($this->_parent->getSize() > 0 ? $this->_parent->getSize() : 0) +
+ $size - ($this->_size > 0 ? $this->_size : 0));
+ $this->_size = $size;
+ }
+
+ /**
+ * Returns the box type.
*
* @return string
*/
public function getType() { return $this->_type; }
+ /**
+ * Sets the box type.
+ *
+ * @param string $type The box type.
+ */
+ public function setType($type) { $this->_type = $type; }
+
+ /**
+ * Returns the parent box containing this box.
+ *
+ * @return ISO14496_Box
+ */
+ public function getParent() { return $this->_parent; }
+
+ /**
+ * Sets the parent containing box.
+ *
+ * @param ISO14496_Box $parent The parent box.
+ */
+ public function setParent(&$parent) { $this->_parent = $parent; }
+
/**
* Returns a boolean value corresponding to whether the box is a container.
*
@@ -142,35 +242,57 @@ class ISO14496_Box
/**
* Reads and constructs the boxes found within this box.
+ *
+ * @todo Does not parse iTunes internal ---- boxes.
*/
protected function constructBoxes($defaultclassname = "ISO14496_Box")
{
+ $base = $this->getOption("base", "");
+ if ($this->getType() != "file")
+ self::$_path[] = $this->getType();
+ $path = implode(self::$_path, ".");
+
while (true) {
$offset = $this->_reader->getOffset();
if ($offset >= $this->_offset + $this->_size)
break;
$size = $this->_reader->readUInt32BE();
- $type = $this->_reader->read(4);
+ $type = rtrim($this->_reader->read(4), " ");
if ($size == 1)
$size = $this->_reader->readInt64BE();
if ($size == 0)
$size = $this->_reader->getSize() - $offset;
- $this->_reader->setOffset($offset);
-
- if (@fopen($filename = "ISO14496/Box/" . strtoupper($type) . ".php",
- "r", true) !== false)
- require_once($filename);
- if (class_exists($classname = "ISO14496_Box_" . strtoupper($type)))
- $box = new $classname($this->_reader);
- else
- $box = new $defaultclassname($this->_reader);
-
- if (!isset($this->_boxes[$type]))
- $this->_boxes[$type] = array();
- $this->_boxes[$type][] = $box;
+ if (preg_match("/^\xa9?[a-z]{3,4}$/i", $type) &&
+ substr($base, 0, min(strlen($base), strlen
+ ($tmp = $path . ($path ? "." : "") . $type))) ==
+ substr($tmp, 0, min(strlen($base), strlen($tmp))))
+ {
+ $this->_reader->setOffset($offset);
+ if (@fopen($filename = "ISO14496/Box/" . strtoupper($type) . ".php",
+ "r", true) !== false)
+ require_once($filename);
+ if (class_exists($classname = "ISO14496_Box_" . strtoupper($type)))
+ $box = new $classname($this->_reader, $this->_options);
+ else
+ $box = new $defaultclassname($this->_reader, $this->_options);
+ $box->setParent($this);
+ if (!isset($this->_boxes[$box->getType()]))
+ $this->_boxes[$box->getType()] = array();
+ $this->_boxes[$box->getType()][] = $box;
+ }
$this->_reader->setOffset($offset + $size);
}
+
+ array_pop(self::$_path);
+ }
+
+ protected function getPath()
+ {
+ $path = "";
+ echo "box: " .$this->getType() . ", parent: " . $this->getParent()."\n";
+ for ($child = $this; ($parent = $child->getParent()) !== null; $child = $parent){echo "parent found";$path = $parent->getType() . "." . $path;};
+ return $path;
}
/**
@@ -227,8 +349,23 @@ class ISO14496_Box
foreach ($this->_boxes as $identifier => $boxes)
if (preg_match($searchPattern, $identifier))
foreach ($boxes as $box)
- $boxes[] = $box;
- return $boxes;
+ $matches[] = $box;
+ return $matches;
+ }
+
+ /**
+ * Adds a new box into the current box and returns it.
+ *
+ * @param ISO14496_Box The box to add
+ * @return ISO14496_Box
+ */
+ public function addBox($box)
+ {
+ $box->setParent($this);
+ $box->setOptions($this->_options);
+ if (!$this->hasBox($box->getType()))
+ $this->_boxes[$box->getType()] = array();
+ return $this->_boxes[$box->getType()][] = $box;
}
/**
@@ -237,7 +374,9 @@ class ISO14496_Box
* matches the identifier, and if not found, invoke a getter method.
*
* If there are no boxes or getter methods with given name, the method
- * will yield an exception.
+ * attempts to create a frame with given identifier.
+ *
+ * If none of these work, an exception is thrown.
*
* @param string $name The box or field name.
* @return mixed
@@ -248,9 +387,29 @@ class ISO14496_Box
return $this->_boxes[$name][0];
if (method_exists($this, "get" . ucfirst($name)))
return call_user_func(array($this, "get" . ucfirst($name)));
+ if (@fopen($filename = "ISO14496/Box/" .
+ strtoupper($name) . ".php", "r", true) !== false)
+ require_once($filename);
+ if (class_exists($classname = "ISO14496_Box_" . strtoupper($name)))
+ return $this->addBox(new $classname());
throw new ISO14496_Exception("Unknown box/field: " . $name);
}
+ /**
+ * Magic function so that assignments with $obj->value will work.
+ *
+ * @param string $name The field name.
+ * @param string $value The field value.
+ * @return mixed
+ */
+ public function __set($name, $value)
+ {
+ if (method_exists($this, "set" . ucfirst($name)))
+ call_user_func
+ (array($this, "set" . ucfirst($name)), $value);
+ else throw new ISO14496_Exception("Unknown field: " . $name);
+ }
+
/**
* Magic function so that isset($obj->value) will work. This method checks
* whether the box is a container and contains a box that matches the
@@ -263,4 +422,39 @@ class ISO14496_Box
{
return ($this->isContainer() && isset($this->_boxes[$name]));
}
+
+ /**
+ * Magic function so that unset($obj->value) will work. This method removes
+ * all the boxes from this container that match the identifier.
+ *
+ * @param string $name The box name.
+ */
+ public function __unset($name)
+ {
+ if ($this->isContainer())
+ unset($this->_boxes[$name]);
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ if ($this->isContainer())
+ foreach ($this->getBoxes() as $name => $boxes)
+ foreach ($boxes as $box)
+ $data .= $box;
+ $size = strlen($data) + 8;
+ if ($size > 0xffffffff)
+ $size += 8;
+ if (strlen($this->_type) > 4)
+ $size += 16;
+ return ($size > 0xffffffff ?
+ Transform::toUInt32BE(1) : Transform::toUInt32BE($size)) .
+ (strlen($this->_type) > 4 ? "uuid" : $this->_type) .
+ ($size > 0xffffffff ? Transform::toInt64BE($size) : "") .
+ (strlen($this->_type) > 4 ? Transform::toGUID($this->_type) : "") . $data;
+ }
}
diff --git a/src/ISO14496/Box/BXML.php b/src/ISO14496/Box/BXML.php
index fb8e821..3fd5c1c 100644
--- a/src/ISO14496/Box/BXML.php
+++ b/src/ISO14496/Box/BXML.php
@@ -66,12 +66,12 @@ final class ISO14496_Box_BXML extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_data = $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
}
/**
diff --git a/src/ISO14496/Box/CDSC.php b/src/ISO14496/Box/CDSC.php
index 3369235..0effe2b 100644
--- a/src/ISO14496/Box/CDSC.php
+++ b/src/ISO14496/Box/CDSC.php
@@ -61,11 +61,11 @@ final class ISO14496_Box_CDSC extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- while ($this->_reader->getOffset <= $this->_size)
+ while ($this->_reader->getOffset <= $this->getSize())
$this->_trackId[] = $this->_reader->readUInt32BE();
}
diff --git a/src/ISO14496/Box/CO64.php b/src/ISO14496/Box/CO64.php
index 51f7b80..8aa5c59 100644
--- a/src/ISO14496/Box/CO64.php
+++ b/src/ISO14496/Box/CO64.php
@@ -74,13 +74,16 @@ final class ISO14496_Box_CO64 extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
- $this->_chunkOffsetTable[$i] = $this->_reader->readInt64BE();
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
+ $this->_chunkOffsetTable[$i] =
+ Transform::fromInt64BE(substr($data, ($i - 1) * 8, 8));
}
/**
@@ -90,8 +93,30 @@ final class ISO14496_Box_CO64 extends ISO14496_Box_Full
*
* @return Array
*/
- public function getChunkOffsetTable()
+ public function getChunkOffsetTable() { return $this->_chunkOffsetTable; }
+
+ /**
+ * Sets an array of chunk offsets. Each entry must have the entry number as
+ * its index and a 64 bit integer that gives the offset of the start of a
+ * chunk into its containing media file as its value.
+ *
+ * @param Array $chunkOffsetTable The chunk offset array.
+ */
+ public function setChunkOffsetTable($chunkOffsetTable)
{
- return $this->_chunkOffsetTable;
+ $this->_chunkOffsetTable = $chunkOffsetTable;
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ $data = Transform::toUInt32BE(count($this->_chunkOffsetTable));
+ foreach ($this->_chunkOffsetTable as $chunkOffset)
+ $data .= Transform::toInt64BE($chunkOffset);
+ return parent::__toString($data);
}
}
diff --git a/src/ISO14496/Box/CPRT.php b/src/ISO14496/Box/CPRT.php
index b8c69f6..be1d9b7 100644
--- a/src/ISO14496/Box/CPRT.php
+++ b/src/ISO14496/Box/CPRT.php
@@ -67,15 +67,15 @@ final class ISO14496_Box_CPRT extends ISO14496_Box_Full
* @param Reader $reader The reader object.
* @todo Distinguish UTF-16?
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_language =
chr(((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) .
chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60);
$this->_notice = $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
}
/**
diff --git a/src/ISO14496/Box/CTTS.php b/src/ISO14496/Box/CTTS.php
index b986a31..ec539a4 100644
--- a/src/ISO14496/Box/CTTS.php
+++ b/src/ISO14496/Box/CTTS.php
@@ -67,15 +67,19 @@ final class ISO14496_Box_CTTS extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
$this->_compositionOffsetTable[$i] = array
- ("sampleCount" => $this->_reader->readUInt32BE(),
- "sampleOffset" => $this->_reader->readUInt32BE());
+ ("sampleCount" =>
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)),
+ "sampleOffset" =>
+ Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4)));
}
/**
diff --git a/src/ISO14496/Box/DINF.php b/src/ISO14496/Box/DINF.php
index da969b4..a8dfbbe 100644
--- a/src/ISO14496/Box/DINF.php
+++ b/src/ISO14496/Box/DINF.php
@@ -58,10 +58,14 @@ final class ISO14496_Box_DINF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/DREF.php b/src/ISO14496/Box/DREF.php
index 9e59a2d..ced6db9 100644
--- a/src/ISO14496/Box/DREF.php
+++ b/src/ISO14496/Box/DREF.php
@@ -64,25 +64,25 @@ final class ISO14496_Box_DREF extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
- $count = $this->_reader->readUInt32BE();
- for ($i = 0; $i < $count; $i++) {
- $offset = $this->_reader->getOffset();
- $size = $this->_reader->readUInt32BE();
- $type = $this->_reader->read(4);
- $this->_reader->setOffset($offset);
- if ($type == "url ") {
- require_once("ISO14496/Box/URL.php");
- $this->_boxes[] = new ISO14496_Box_URL($this->_reader);
- }
- if ($type == "urn ") {
- require_once("ISO14496/Box/URN.php");
- $this->_boxes[] = new ISO14496_Box_URN($this->_reader);
- }
- $this->_reader->setOffset($offset + $size);
- }
+
+ if ($reader === null)
+ return;
+
+ $this->_reader->skip(4);
+ $this->constructBoxes();
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString(Transform::toUInt32BE(count($this->_boxes)));
}
}
diff --git a/src/ISO14496/Box/EDTS.php b/src/ISO14496/Box/EDTS.php
index 322c992..0e24e13 100644
--- a/src/ISO14496/Box/EDTS.php
+++ b/src/ISO14496/Box/EDTS.php
@@ -63,10 +63,14 @@ final class ISO14496_Box_EDTS extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/ELST.php b/src/ISO14496/Box/ELST.php
index bc81fde..e424f2e 100644
--- a/src/ISO14496/Box/ELST.php
+++ b/src/ISO14496/Box/ELST.php
@@ -63,9 +63,9 @@ final class ISO14496_Box_ELST extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
for ($i = 1; $i <= $entryCount; $i++) {
diff --git a/src/ISO14496/Box/FREE.php b/src/ISO14496/Box/FREE.php
index dcf9607..f239e5f 100644
--- a/src/ISO14496/Box/FREE.php
+++ b/src/ISO14496/Box/FREE.php
@@ -54,4 +54,23 @@ require_once("ISO14496/Box.php");
*/
final class ISO14496_Box_FREE extends ISO14496_Box
{
+ /**
+ * Constructs the class with given parameters.
+ *
+ * @param Reader $reader The reader object.
+ */
+ public function __construct($reader = null, &$options = array())
+ {
+ parent::__construct($reader, $options);
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString(str_repeat("\0", $this->getSize() - 8));
+ }
}
diff --git a/src/ISO14496/Box/FRMA.php b/src/ISO14496/Box/FRMA.php
index 8d6d2cb..bb180e8 100644
--- a/src/ISO14496/Box/FRMA.php
+++ b/src/ISO14496/Box/FRMA.php
@@ -61,9 +61,9 @@ final class ISO14496_Box_FRMA extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_dataFormat = $this->_reader->read(4);
}
diff --git a/src/ISO14496/Box/FTYP.php b/src/ISO14496/Box/FTYP.php
index 1e40ce3..550e583 100644
--- a/src/ISO14496/Box/FTYP.php
+++ b/src/ISO14496/Box/FTYP.php
@@ -108,13 +108,13 @@ final class ISO14496_Box_FTYP extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_majorBrand = $this->_reader->readString8(4);
$this->_minorVersion = $this->_reader->readUInt32BE();
- while ($this->_reader->getOffset() < $this->_size)
+ while ($this->_reader->getOffset() < $this->getSize())
if (($brand = $this->_reader->readString8(4)) != "")
$this->_compatibleBrands[] = $brand;
}
diff --git a/src/ISO14496/Box/Full.php b/src/ISO14496/Box/Full.php
index 094cfff..06e7ab9 100644
--- a/src/ISO14496/Box/Full.php
+++ b/src/ISO14496/Box/Full.php
@@ -52,10 +52,10 @@ require_once("ISO14496/Box.php");
abstract class ISO14496_Box_Full extends ISO14496_Box
{
/** @var integer */
- protected $_version;
+ protected $_version = 0;
/** @var integer */
- protected $_flags;
+ protected $_flags = 0;
/**
* Constructs the class with given parameters and reads box related data from
@@ -63,10 +63,13 @@ abstract class ISO14496_Box_Full extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
+ if ($reader === null)
+ return;
+
$this->_version = (($field = $this->_reader->readUInt32BE()) >> 24) & 0xff;
$this->_flags = $field & 0xffffff;
}
@@ -78,6 +81,13 @@ abstract class ISO14496_Box_Full extends ISO14496_Box
*/
public function getVersion() { return $this->_version; }
+ /**
+ * Sets the version of this format of the box.
+ *
+ * @param integer $version The version.
+ */
+ public function setVersion($version) { $this->_version = $version; }
+
/**
* Checks whether or not the flag is set. Returns true if the flag
* is set, false otherwise.
@@ -93,4 +103,22 @@ abstract class ISO14496_Box_Full extends ISO14496_Box
* @return integer
*/
public function getFlags() { return $this->_flags; }
+
+ /**
+ * Sets the map of flags.
+ *
+ * @param string $flags The map of flags.
+ */
+ public function setFlags($flags) { $this->_flags = $flags; }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString
+ (Transform::toUInt32BE($this->_version << 24 | $this->_flags) . $data);
+ }
}
diff --git a/src/ISO14496/Box/HDLR.php b/src/ISO14496/Box/HDLR.php
index 5112481..61b88d3 100644
--- a/src/ISO14496/Box/HDLR.php
+++ b/src/ISO14496/Box/HDLR.php
@@ -69,15 +69,18 @@ final class ISO14496_Box_HDLR extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
+
+ if ($reader === null)
+ return;
$this->_reader->skip(4);
$this->_handlerType = $this->_reader->read(4);
$this->_reader->skip(12);
$this->_name = $this->_reader->readString8
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
}
/**
@@ -96,6 +99,25 @@ final class ISO14496_Box_HDLR extends ISO14496_Box_Full
*/
public function getHandlerType() { return $this->_handlerType; }
+ /**
+ * Sets the handler type.
+ *
+ * When present in a media box, the value must be set to one of the following
+ * values, or a value from a derived specification:
+ * o vide Video track
+ * o soun Audio track
+ * o hint Hint track
+ *
+ * When present in a meta box, the value must be set to an appropriate value
+ * to indicate the format of the meta box contents.
+ *
+ * @param string $handlerType The handler type.
+ */
+ public function setHandlerType($handlerType)
+ {
+ $this->_handlerType = $handlerType;
+ }
+
/**
* Returns the name string. The name is in UTF-8 characters and gives a
* human-readable name for the track type (for debugging and inspection
@@ -104,4 +126,25 @@ final class ISO14496_Box_HDLR extends ISO14496_Box_Full
* @return integer
*/
public function getName() { return $this->_name; }
+
+ /**
+ * Sets the name string. The name must be in UTF-8 and give a human-readable
+ * name for the track type (for debugging and inspection purposes).
+ *
+ * @param string $name The human-readable description.
+ */
+ public function setName($name) { $this->_name = $name; }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString
+ ("appl" . $this->_handlerType . Transform::toUInt32BE(0) .
+ Transform::toUInt32BE(0) . Transform::toUInt32BE(0) . $this->_name .
+ "\0");
+ }
}
diff --git a/src/ISO14496/Box/HINT.php b/src/ISO14496/Box/HINT.php
index 365618a..286f3e5 100644
--- a/src/ISO14496/Box/HINT.php
+++ b/src/ISO14496/Box/HINT.php
@@ -62,11 +62,11 @@ final class ISO14496_Box_HINT extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- while ($this->_reader->getOffset <= $this->_size)
+ while ($this->_reader->getOffset <= $this->getSize())
$this->_trackId[] = $this->_reader->readUInt32BE();
}
diff --git a/src/ISO14496/Box/HMHD.php b/src/ISO14496/Box/HMHD.php
index 49ca254..3c39f2c 100644
--- a/src/ISO14496/Box/HMHD.php
+++ b/src/ISO14496/Box/HMHD.php
@@ -70,9 +70,9 @@ final class ISO14496_Box_HMHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_maxPDUSize = $this->_reader->readUInt16BE();
$this->_avgPDUSize = $this->_reader->readUInt16BE();
diff --git a/src/ISO14496/Box/ID32.php b/src/ISO14496/Box/ID32.php
index 8693752..7f1c44f 100644
--- a/src/ISO14496/Box/ID32.php
+++ b/src/ISO14496/Box/ID32.php
@@ -54,7 +54,7 @@ require_once("ISO14496/Box/Full.php");
final class ISO14496_Box_ID32 extends ISO14496_Box_Full
{
/** @var string */
- private $_language;
+ private $_language = "und";
/** @var ID3v2 */
private $_tag;
@@ -65,9 +65,12 @@ final class ISO14496_Box_ID32 extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
+
+ if ($reader === null)
+ return;
$this->_language =
chr(((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) .
@@ -84,10 +87,45 @@ final class ISO14496_Box_ID32 extends ISO14496_Box_Full
*/
public function getLanguage() { return $this->_language; }
+ /**
+ * Sets the three byte language code as specified in the
+ * {@link http://www.loc.gov/standards/iso639-2/ ISO 639-2} standard.
+ *
+ * @param string $language The language code.
+ */
+ public function setLanguage($language) { $this->_language = $language; }
+
/**
* Returns the {@link ID3v2} tag class instance.
*
* @return string
*/
public function getTag() { return $this->_tag; }
+
+ /**
+ * Sets the {@link ID3v2} tag class instance using given language.
+ *
+ * @param ID3v2 $tag The tag instance.
+ * @param string $language The language code.
+ */
+ public function setTag($tag, $language = false)
+ {
+ $this->_tag = $tag;
+ if ($language !== false)
+ $this->_language = $language;
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString
+ (Transform::toUInt16BE
+ (((ord($language[0]) - 0x60) << 10) |
+ ((ord($language[1]) - 0x60) << 5) |
+ ord($language[2]) - 0x60) . $this->_tag);
+ }
}
diff --git a/src/ISO14496/Box/IINF.php b/src/ISO14496/Box/IINF.php
index 1f96b4d..a45270b 100644
--- a/src/ISO14496/Box/IINF.php
+++ b/src/ISO14496/Box/IINF.php
@@ -63,11 +63,25 @@ final class ISO14496_Box_IINF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
- $this->_reader->skip(2);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
+ $this->_reader->skip(2);
$this->constructBoxes();
}
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString(Transform::toUInt16BE(count($this->_boxes)));
+ }
}
diff --git a/src/ISO14496/Box/ILOC.php b/src/ISO14496/Box/ILOC.php
index 62d9dbe..315e7e9 100644
--- a/src/ISO14496/Box/ILOC.php
+++ b/src/ISO14496/Box/ILOC.php
@@ -94,9 +94,9 @@ final class ISO14496_Box_ILOC extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$offsetSize = (($tmp = $this->_reader->readUInt32BE()) >> 28) & 0xf;
$lengthSize = ($tmp >> 24) & 0xf;
diff --git a/src/ISO14496/Box/ILST.php b/src/ISO14496/Box/ILST.php
index 2ea62dd..22c5de9 100644
--- a/src/ISO14496/Box/ILST.php
+++ b/src/ISO14496/Box/ILST.php
@@ -52,20 +52,44 @@ require_once("ISO14496/Box.php");
*/
final class ISO14496_Box_ILST extends ISO14496_Box
{
- private $_data = array();
-
/**
* Constructs the class with given parameters and reads box related data from
* the ISO Base Media file.
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes("ISO14496_Box_ILST_Container");
}
+
+ /**
+ * Override magic function so that $obj->value on a box will return the data
+ * box instead of the data container box.
+ *
+ * @param string $name The box or field name.
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ if (strlen($name) == 3)
+ $name = "\xa9" . $name;
+ if ($name[0] == "_")
+ $name = "\xa9" . substr($name, 1, 3);
+ if ($this->hasBox($name)) {
+ $boxes = $this->getBoxesByIdentifier($name);
+ return $boxes[0]->data;
+ }
+ if (method_exists($this, "get" . ucfirst($name)))
+ return call_user_func(array($this, "get" . ucfirst($name)));
+ return $this->addBox(new ISO14496_Box_ILST_Container($name))->data;
+ }
}
/**
@@ -82,11 +106,16 @@ final class ISO14496_Box_ILST extends ISO14496_Box
*/
final class ISO14496_Box_ILST_Container extends ISO14496_Box
{
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct(is_string($reader) ? null : $reader, $options);
$this->setContainer(true);
- $this->constructBoxes();
+
+ if (is_string($reader)) {
+ $this->setType($reader);
+ $this->addBox(new ISO14496_Box_DATA());
+ } else
+ $this->constructBoxes();
}
}
@@ -134,18 +163,21 @@ final class ISO14496_Box_DATA extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
+
+ if ($reader === null)
+ return;
$this->_reader->skip(4);
$data = $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
switch ($this->getFlags()) {
case self::INTEGER:
case self::INTEGER_OLD_STYLE:
for ($i = 0; $i < strlen($data); $i++)
- $this->_value .= ord($data[$i]);
+ $this->_value .= Transform::fromInt8($data[$i]);
break;
case self::STRING:
default:
@@ -159,4 +191,61 @@ final class ISO14496_Box_DATA extends ISO14496_Box_Full
* @return mixed
*/
public function getValue() { return $this->_value; }
+
+ /**
+ * Sets the value this box contains.
+ *
+ * @return mixed
+ */
+ public function setValue($value, $type = false)
+ {
+ $this->_value = (string)$value;
+ if ($type === false && is_string($value))
+ $this->_flags = self::STRING;
+ if ($type === false && is_int($value))
+ $this->_flags = self::INTEGER;
+ if ($type !== false)
+ $this->_flags = $type;
+ }
+
+ /**
+ * Override magic function so that $obj->data will return the current box
+ * instead of an error. For other values the method will attempt to call a
+ * getter method.
+ *
+ * If there are no getter methods with given name, the method will yield an
+ * exception.
+ *
+ * @param string $name The box or field name.
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ if ($name == "data")
+ return $this;
+ if (method_exists($this, "get" . ucfirst($name)))
+ return call_user_func(array($this, "get" . ucfirst($name)));
+ throw new ISO14496_Exception("Unknown box/field: " . $name);
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ switch ($this->getFlags()) {
+ case self::INTEGER:
+ case self::INTEGER_OLD_STYLE:
+ $data = "";
+ for ($i = 0; $i < strlen($this->_value); $i++)
+ $data .= Transform::toInt8($this->_value[$i]);
+ break;
+ case self::STRING:
+ default:
+ $data = $this->_value;
+ }
+ return parent::__toString("\0\0\0\0" . $data);
+ }
}
diff --git a/src/ISO14496/Box/IMIF.php b/src/ISO14496/Box/IMIF.php
index e42a32e..a8fcf8f 100644
--- a/src/ISO14496/Box/IMIF.php
+++ b/src/ISO14496/Box/IMIF.php
@@ -78,10 +78,14 @@ final class ISO14496_Box_IMIF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/INFE.php b/src/ISO14496/Box/INFE.php
index d48d6fa..28740bb 100644
--- a/src/ISO14496/Box/INFE.php
+++ b/src/ISO14496/Box/INFE.php
@@ -72,15 +72,16 @@ final class ISO14496_Box_INFE extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_itemId = $this->_reader->readUInt16BE();
$this->_itemProtectionIndex = $this->_reader->readUInt16BE();
list($this->_itemName, $this->_contentType, $this->_contentEncoding) =
- preg_split("/\\x00/", $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset()));
+ preg_split
+ ("/\\x00/", $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()));
}
/**
diff --git a/src/ISO14496/Box/IPRO.php b/src/ISO14496/Box/IPRO.php
index 45c4fce..658fd0c 100644
--- a/src/ISO14496/Box/IPRO.php
+++ b/src/ISO14496/Box/IPRO.php
@@ -58,11 +58,25 @@ final class ISO14496_Box_IPRO extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
- $this->_reader->skip(2);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
+ $this->_reader->skip(2);
$this->constructBoxes();
}
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ return parent::__toString(Transform::toUInt16BE(count($this->_boxes)));
+ }
}
diff --git a/src/ISO14496/Box/MDAT.php b/src/ISO14496/Box/MDAT.php
index a9f66b7..84441c7 100644
--- a/src/ISO14496/Box/MDAT.php
+++ b/src/ISO14496/Box/MDAT.php
@@ -59,8 +59,8 @@ final class ISO14496_Box_MDAT extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
}
}
diff --git a/src/ISO14496/Box/MDHD.php b/src/ISO14496/Box/MDHD.php
index b3c32f3..e0211eb 100644
--- a/src/ISO14496/Box/MDHD.php
+++ b/src/ISO14496/Box/MDHD.php
@@ -73,9 +73,9 @@ final class ISO14496_Box_MDHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
if ($this->getVersion() == 1) {
$this->_creationTime = $this->_reader->readInt64BE();
diff --git a/src/ISO14496/Box/MDIA.php b/src/ISO14496/Box/MDIA.php
index c06df11..70f399a 100644
--- a/src/ISO14496/Box/MDIA.php
+++ b/src/ISO14496/Box/MDIA.php
@@ -58,10 +58,14 @@ final class ISO14496_Box_MDIA extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MEHD.php b/src/ISO14496/Box/MEHD.php
index 3bdc5cd..8d25d95 100644
--- a/src/ISO14496/Box/MEHD.php
+++ b/src/ISO14496/Box/MEHD.php
@@ -62,9 +62,9 @@ final class ISO14496_Box_MEHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
if ($this->getVersion() == 1)
$this->_fragmentDuration = $this->_reader->readInt64BE();
diff --git a/src/ISO14496/Box/META.php b/src/ISO14496/Box/META.php
index 60ce1f0..0e7e532 100644
--- a/src/ISO14496/Box/META.php
+++ b/src/ISO14496/Box/META.php
@@ -77,10 +77,14 @@ final class ISO14496_Box_META extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MFHD.php b/src/ISO14496/Box/MFHD.php
index 42199d1..eb64359 100644
--- a/src/ISO14496/Box/MFHD.php
+++ b/src/ISO14496/Box/MFHD.php
@@ -64,9 +64,9 @@ final class ISO14496_Box_MFHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_sequenceNumber = $this->_reader->readUInt32BE();
}
diff --git a/src/ISO14496/Box/MFRA.php b/src/ISO14496/Box/MFRA.php
index 1d09357..54eb649 100644
--- a/src/ISO14496/Box/MFRA.php
+++ b/src/ISO14496/Box/MFRA.php
@@ -72,10 +72,14 @@ final class ISO14496_Box_MFRA extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MFRO.php b/src/ISO14496/Box/MFRO.php
index d7ec28e..08008e2 100644
--- a/src/ISO14496/Box/MFRO.php
+++ b/src/ISO14496/Box/MFRO.php
@@ -59,7 +59,7 @@ require_once("ISO14496/Box/Full.php");
final class ISO14496_Box_MFRO extends ISO14496_Box_Full
{
/** @var integer */
- private $_size;
+ private $_parentSize;
/**
* Constructs the class with given parameters and reads box related data from
@@ -67,11 +67,11 @@ final class ISO14496_Box_MFRO extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- $this->_size = $this->_reader->readUInt32BE();
+ $this->_parentSize = $this->_reader->readUInt32BE();
}
/**
@@ -81,5 +81,5 @@ final class ISO14496_Box_MFRO extends ISO14496_Box_Full
*
* @return integer
*/
- public function getSize() { return $this->_size; }
+ public function getParentSize() { return $this->_parentSize; }
}
diff --git a/src/ISO14496/Box/MINF.php b/src/ISO14496/Box/MINF.php
index 017e621..cf5dd1b 100644
--- a/src/ISO14496/Box/MINF.php
+++ b/src/ISO14496/Box/MINF.php
@@ -58,10 +58,14 @@ final class ISO14496_Box_MINF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MOOF.php b/src/ISO14496/Box/MOOF.php
index 17cc950..55e3c1c 100644
--- a/src/ISO14496/Box/MOOF.php
+++ b/src/ISO14496/Box/MOOF.php
@@ -68,10 +68,14 @@ final class ISO14496_Box_MOOF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MOOV.php b/src/ISO14496/Box/MOOV.php
index 74308c7..208f200 100644
--- a/src/ISO14496/Box/MOOV.php
+++ b/src/ISO14496/Box/MOOV.php
@@ -59,10 +59,14 @@ final class ISO14496_Box_MOOV extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MVEX.php b/src/ISO14496/Box/MVEX.php
index 9dcf7c7..f4d4a4a 100644
--- a/src/ISO14496/Box/MVEX.php
+++ b/src/ISO14496/Box/MVEX.php
@@ -61,10 +61,14 @@ final class ISO14496_Box_MVEX extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/MVHD.php b/src/ISO14496/Box/MVHD.php
index 2ff90dc..dac4288 100644
--- a/src/ISO14496/Box/MVHD.php
+++ b/src/ISO14496/Box/MVHD.php
@@ -80,9 +80,9 @@ final class ISO14496_Box_MVHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
if ($this->getVersion() == 1) {
$this->_creationTime = $this->_reader->readInt64BE();
diff --git a/src/ISO14496/Box/PDIN.php b/src/ISO14496/Box/PDIN.php
index 0a3af25..5bb3a40 100644
--- a/src/ISO14496/Box/PDIN.php
+++ b/src/ISO14496/Box/PDIN.php
@@ -68,11 +68,11 @@ final class ISO14496_Box_PDIN extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- while ($this->_reader->getOffset() < $this->_offset + $this->_size())
+ while ($this->_reader->getOffset() < $this->getOffset() + $this->getSize())
$this->_progressiveDownloadInfo[] = array
("rate" => $this->_reader->readUInt32BE(),
"initialDelay" => $this->_reader->readUInt32BE());
diff --git a/src/ISO14496/Box/PITM.php b/src/ISO14496/Box/PITM.php
index b9fed10..465f48d 100644
--- a/src/ISO14496/Box/PITM.php
+++ b/src/ISO14496/Box/PITM.php
@@ -66,9 +66,9 @@ final class ISO14496_Box_PITM extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_itemId = $this->_reader->readUInt16BE();
}
diff --git a/src/ISO14496/Box/SBGP.php b/src/ISO14496/Box/SBGP.php
index 606dc28..299cccd 100644
--- a/src/ISO14496/Box/SBGP.php
+++ b/src/ISO14496/Box/SBGP.php
@@ -76,16 +76,20 @@ final class ISO14496_Box_SBGP extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$groupingType = $this->_reader->readUInt32BE();
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
$this->_sampleToGroupTable[$i] = array
- ("sampleCount" => $this->_reader->readUInt32BE(),
- "groupDescriptionIndex" => $this->_reader->readUInt32BE());
+ ("sampleCount" =>
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)),
+ "groupDescriptionIndex" =>
+ Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4)));
}
/**
diff --git a/src/ISO14496/Box/SCHI.php b/src/ISO14496/Box/SCHI.php
index 19cba02..2e7c43e 100644
--- a/src/ISO14496/Box/SCHI.php
+++ b/src/ISO14496/Box/SCHI.php
@@ -61,10 +61,14 @@ final class ISO14496_Box_SCHI extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/SCHM.php b/src/ISO14496/Box/SCHM.php
index 79934d2..148448b 100644
--- a/src/ISO14496/Box/SCHM.php
+++ b/src/ISO14496/Box/SCHM.php
@@ -66,16 +66,16 @@ final class ISO14496_Box_SCHM extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_schemeType = $this->_reader->read(4);
$this->_schemeVersion = $this->_reader->readUInt32BE();
if ($this->hasFlag(1))
$this->_schemeUri = preg_split
("/\\x00/", $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset()));
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()));
}
/**
diff --git a/src/ISO14496/Box/SDTP.php b/src/ISO14496/Box/SDTP.php
index a16167d..b5b6818 100644
--- a/src/ISO14496/Box/SDTP.php
+++ b/src/ISO14496/Box/SDTP.php
@@ -87,14 +87,17 @@ final class ISO14496_Box_SDTP extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- for ($i = 0; $this->_reader->getOffset() <
- $this->_offset + $this->_size; $i++)
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ $dataSize = strlen($data);
+ for ($i = 1; $i <= $dataSize; $i++)
$this->_sampleDependencyTypeTable[$i] = array
- ("sampleDependsOn" => (($tmp = $this->_reader->readInt8()) >> 4) & 0x3,
+ ("sampleDependsOn" => (($tmp = Transform::fromInt8
+ ($data[$i - 1])) >> 4) & 0x3,
"sampleIsDependedOn" => ($tmp >> 2) & 0x3,
"sampleHasRedundancy" => $tmp & 0x3);
}
diff --git a/src/ISO14496/Box/SINF.php b/src/ISO14496/Box/SINF.php
index 947be52..5651b75 100644
--- a/src/ISO14496/Box/SINF.php
+++ b/src/ISO14496/Box/SINF.php
@@ -74,10 +74,14 @@ final class ISO14496_Box_SINF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/SKIP.php b/src/ISO14496/Box/SKIP.php
index be37347..fa8ab98 100644
--- a/src/ISO14496/Box/SKIP.php
+++ b/src/ISO14496/Box/SKIP.php
@@ -60,10 +60,14 @@ final class ISO14496_Box_SKIP extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/SMHD.php b/src/ISO14496/Box/SMHD.php
index d557513..9881452 100644
--- a/src/ISO14496/Box/SMHD.php
+++ b/src/ISO14496/Box/SMHD.php
@@ -59,8 +59,8 @@ final class ISO14496_Box_SMHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
}
}
diff --git a/src/ISO14496/Box/STBL.php b/src/ISO14496/Box/STBL.php
index c63fca7..8793f77 100644
--- a/src/ISO14496/Box/STBL.php
+++ b/src/ISO14496/Box/STBL.php
@@ -77,10 +77,14 @@ final class ISO14496_Box_STBL extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/STCO.php b/src/ISO14496/Box/STCO.php
index 66c0d27..de83e94 100644
--- a/src/ISO14496/Box/STCO.php
+++ b/src/ISO14496/Box/STCO.php
@@ -74,13 +74,16 @@ final class ISO14496_Box_STCO extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
- $this->_chunkOffsetTable[$i] = $this->_reader->readUInt32BE();
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
+ $this->_chunkOffsetTable[$i] =
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 4, 4));
}
/**
@@ -90,8 +93,30 @@ final class ISO14496_Box_STCO extends ISO14496_Box_Full
*
* @return Array
*/
- public function getChunkOffsetTable()
+ public function getChunkOffsetTable() { return $this->_chunkOffsetTable; }
+
+ /**
+ * Sets an array of chunk offsets. Each entry must have the entry number as
+ * its index and a 32 bit integer that gives the offset of the start of a
+ * chunk into its containing media file as its value.
+ *
+ * @param Array $chunkOffsetTable The chunk offset array.
+ */
+ public function setChunkOffsetTable($chunkOffsetTable)
{
- return $this->_chunkOffsetTable;
+ $this->_chunkOffsetTable = $chunkOffsetTable;
+ }
+
+ /**
+ * Returns the box raw data.
+ *
+ * @return string
+ */
+ public function __toString($data = "")
+ {
+ $data = Transform::toUInt32BE(count($this->_chunkOffsetTable));
+ foreach ($this->_chunkOffsetTable as $chunkOffset)
+ $data .= Transform::toUInt32BE($chunkOffset);
+ return parent::__toString($data);
}
}
diff --git a/src/ISO14496/Box/STDP.php b/src/ISO14496/Box/STDP.php
index b070924..5eb371c 100644
--- a/src/ISO14496/Box/STDP.php
+++ b/src/ISO14496/Box/STDP.php
@@ -62,11 +62,11 @@ final class ISO14496_Box_STDP extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
- while ($this->_reader->getOffset() < $this->_offset + $this->_size)
+ while ($this->_reader->getOffset() < $this->getOffset() + $this->getSize())
$this->_values[] = array("priority" => $this->_reader->readUInt16BE());
}
diff --git a/src/ISO14496/Box/STSC.php b/src/ISO14496/Box/STSC.php
index e14a84a..b0fc13e 100644
--- a/src/ISO14496/Box/STSC.php
+++ b/src/ISO14496/Box/STSC.php
@@ -69,16 +69,21 @@ final class ISO14496_Box_STSC extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
$this->_sampleToChunkTable[$i] = array
- ("firstChunk" => $this->_reader->readUInt32BE(),
- "samplesPerChunk" => $this->_reader->readUInt32BE(),
- "sampleDescriptionIndex" => $this->_reader->readUInt32BE());
+ ("firstChunk" =>
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 12, 4)),
+ "samplesPerChunk" =>
+ Transform::fromUInt32BE(substr($data, $i * 12 - 8, 4)),
+ "sampleDescriptionIndex" =>
+ Transform::fromUInt32BE(substr($data, $i * 12 - 4, 4)));
}
/**
diff --git a/src/ISO14496/Box/STSH.php b/src/ISO14496/Box/STSH.php
index 1324e64..3990a0e 100644
--- a/src/ISO14496/Box/STSH.php
+++ b/src/ISO14496/Box/STSH.php
@@ -86,15 +86,19 @@ final class ISO14496_Box_STSH extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
for ($i = 0; $i < $entryCount; $i++)
$this->_shadowSyncSampleTable[$i] = array
- ("shadowedSampleNumber" => $this->_reader->readUInt32BE(),
- "syncSampleNumber" => $this->_reader->readUInt32BE());
+ ("shadowedSampleNumber" =>
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)),
+ "syncSampleNumber" =>
+ Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4)));
}
/**
diff --git a/src/ISO14496/Box/STSS.php b/src/ISO14496/Box/STSS.php
index 662e2b5..c5c3285 100644
--- a/src/ISO14496/Box/STSS.php
+++ b/src/ISO14496/Box/STSS.php
@@ -63,13 +63,16 @@ final class ISO14496_Box_STSS extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
- $this->_syncSampleTable[$i] = $this->_reader->readUInt32BE();
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
+ $this->_syncSampleTable[$i] =
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 4, 4));
}
/**
diff --git a/src/ISO14496/Box/STSZ.php b/src/ISO14496/Box/STSZ.php
index b827ae2..264900e 100644
--- a/src/ISO14496/Box/STSZ.php
+++ b/src/ISO14496/Box/STSZ.php
@@ -73,15 +73,19 @@ final class ISO14496_Box_STSZ extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_sampleSize = $this->_reader->readUInt32BE();
$sampleCount = $this->_reader->readUInt32BE();
- if ($this->_sampleSize == 0)
- for ($i = 1; $i < $sampleCount; $i++)
- $this->_sampleSizeTable[$i] = $this->_reader->readUInt32BE();
+ if ($this->_sampleSize == 0) {
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $sampleCount; $i++)
+ $this->_sampleSizeTable[$i] =
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 4, 4));
+ }
}
/**
diff --git a/src/ISO14496/Box/STTS.php b/src/ISO14496/Box/STTS.php
index 7d08d8d..446abd4 100644
--- a/src/ISO14496/Box/STTS.php
+++ b/src/ISO14496/Box/STTS.php
@@ -78,15 +78,19 @@ final class ISO14496_Box_STTS extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++)
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $entryCount; $i++)
$this->_timeToSampleTable[$i] = array
- ("sampleCount" => $this->_reader->readUInt32BE(),
- "sampleDelta" => $this->_reader->readUInt32BE());
+ ("sampleCount" =>
+ Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)),
+ "sampleDelta" =>
+ Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4)));
}
/**
diff --git a/src/ISO14496/Box/STZ2.php b/src/ISO14496/Box/STZ2.php
index b7f44f6..fdcdc1b 100644
--- a/src/ISO14496/Box/STZ2.php
+++ b/src/ISO14496/Box/STZ2.php
@@ -68,26 +68,29 @@ final class ISO14496_Box_STZ2 extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_reader->skip(3);
$fieldSize = $this->_reader->readInt8();
$sampleCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $sampleCount; $i++) {
+ $data = $this->_reader->read
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
+ for ($i = 1; $i <= $sampleCount; $i++) {
switch ($fieldSize) {
case 4:
$this->_sampleSizeTable[$i] =
- (($tmp = $this->_reader->readInt8()) >> 4) & 0xf;
+ (($tmp = Transform::fromInt8($data[$i - 1])) >> 4) & 0xf;
if ($i + 1 < $sampleCount)
$this->_sampleSizeTable[$i++] = $tmp & 0xf;
break;
case 8:
- $this->_sampleSizeTable[$i] = $this->_reader->readInt8();
+ $this->_sampleSizeTable[$i] = Transform::fromInt8($data[$i - 1]);
break;
case 16:
- $this->_sampleSizeTable[$i] = $this->_reader->readUInt16BE();
+ $this->_sampleSizeTable[$i] =
+ Transform::fromUInt16BE(substr($data, ($i - 1) * 2, 2));
break;
}
}
diff --git a/src/ISO14496/Box/SUBS.php b/src/ISO14496/Box/SUBS.php
index bb53e61..eeda868 100644
--- a/src/ISO14496/Box/SUBS.php
+++ b/src/ISO14496/Box/SUBS.php
@@ -79,9 +79,9 @@ final class ISO14496_Box_SUBS extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
for ($i = 0; $i < $entryCount; $i++) {
diff --git a/src/ISO14496/Box/TFHD.php b/src/ISO14496/Box/TFHD.php
index b9a93f6..288dece 100644
--- a/src/ISO14496/Box/TFHD.php
+++ b/src/ISO14496/Box/TFHD.php
@@ -111,9 +111,9 @@ final class ISO14496_Box_TFHD extends ISO14496_Box_Full
* @param Reader $reader The reader object.
* @todo The sample flags could be parsed further
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_trackId = $this->_reader->readUInt32BE();
if ($this->hasFlag(self::BASE_DATA_OFFSET))
diff --git a/src/ISO14496/Box/TFRA.php b/src/ISO14496/Box/TFRA.php
index 70eb42a..177f6df 100644
--- a/src/ISO14496/Box/TFRA.php
+++ b/src/ISO14496/Box/TFRA.php
@@ -73,9 +73,9 @@ final class ISO14496_Box_TFRA extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_trackId = $this->_reader->readUInt32BE();
@@ -83,7 +83,7 @@ final class ISO14496_Box_TFRA extends ISO14496_Box_Full
$trunNumberSize = ($tmp >> 2) & 0x3;
$sampleNumberSize = $tmp & 0x3;
$entryCount = $this->_reader->readUInt32BE();
- for ($i = 1; $i < $entryCount; $i++) {
+ for ($i = 1; $i <= $entryCount; $i++) {
$entry = array();
if ($this->getVersion() == 1) {
$entry["time"] = $this->_reader->readInt64BE();
diff --git a/src/ISO14496/Box/TKHD.php b/src/ISO14496/Box/TKHD.php
index c6a8750..f27e39d 100644
--- a/src/ISO14496/Box/TKHD.php
+++ b/src/ISO14496/Box/TKHD.php
@@ -92,9 +92,9 @@ final class ISO14496_Box_TKHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
if ($this->getVersion() == 1) {
$this->_creationTime = $this->_reader->readInt64BE();
diff --git a/src/ISO14496/Box/TRAF.php b/src/ISO14496/Box/TRAF.php
index dc1d6b3..69a7bb7 100644
--- a/src/ISO14496/Box/TRAF.php
+++ b/src/ISO14496/Box/TRAF.php
@@ -64,10 +64,14 @@ final class ISO14496_Box_TRAF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/TRAK.php b/src/ISO14496/Box/TRAK.php
index e3ce5d1..8d6110f 100644
--- a/src/ISO14496/Box/TRAK.php
+++ b/src/ISO14496/Box/TRAK.php
@@ -70,10 +70,14 @@ final class ISO14496_Box_TRAK extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/TREF.php b/src/ISO14496/Box/TREF.php
index 5cb654b..33e7f27 100644
--- a/src/ISO14496/Box/TREF.php
+++ b/src/ISO14496/Box/TREF.php
@@ -68,10 +68,14 @@ final class ISO14496_Box_TREF extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/TREX.php b/src/ISO14496/Box/TREX.php
index 9183fa8..b0e4361 100644
--- a/src/ISO14496/Box/TREX.php
+++ b/src/ISO14496/Box/TREX.php
@@ -75,9 +75,9 @@ final class ISO14496_Box_TREX extends ISO14496_Box_Full
* @param Reader $reader The reader object.
* @todo The sample flags could be parsed further
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_trackId = $this->_reader->readUInt32BE();
$this->_defaultSampleDescriptionIndex = $this->_reader->readUInt32BE();
diff --git a/src/ISO14496/Box/TRUN.php b/src/ISO14496/Box/TRUN.php
index 10500c2..c6fcc12 100644
--- a/src/ISO14496/Box/TRUN.php
+++ b/src/ISO14496/Box/TRUN.php
@@ -100,9 +100,9 @@ final class ISO14496_Box_TRUN extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$flags = $this->_flags;
$sampleCount = $this->_reader->readUInt32BE();
diff --git a/src/ISO14496/Box/UDTA.php b/src/ISO14496/Box/UDTA.php
index 724d831..e38b18d 100644
--- a/src/ISO14496/Box/UDTA.php
+++ b/src/ISO14496/Box/UDTA.php
@@ -62,10 +62,14 @@ final class ISO14496_Box_UDTA extends ISO14496_Box
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader = null, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->setContainer(true);
+
+ if ($reader === null)
+ return;
+
$this->constructBoxes();
}
}
diff --git a/src/ISO14496/Box/URL.php b/src/ISO14496/Box/URL.php
index f8b7809..2c210d8 100644
--- a/src/ISO14496/Box/URL.php
+++ b/src/ISO14496/Box/URL.php
@@ -66,12 +66,12 @@ final class ISO14496_Box_URL extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_location = $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
}
/**
diff --git a/src/ISO14496/Box/URN.php b/src/ISO14496/Box/URN.php
index ae4c9b8..6d5ce99 100644
--- a/src/ISO14496/Box/URN.php
+++ b/src/ISO14496/Box/URN.php
@@ -69,13 +69,13 @@ final class ISO14496_Box_URN extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
list ($this->_name, $this->_location) = preg_split
("/\\x00/", $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset()));
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()));
}
/**
diff --git a/src/ISO14496/Box/VMHD.php b/src/ISO14496/Box/VMHD.php
index fbf0e9c..a460161 100644
--- a/src/ISO14496/Box/VMHD.php
+++ b/src/ISO14496/Box/VMHD.php
@@ -58,8 +58,8 @@ final class ISO14496_Box_VMHD extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
}
}
diff --git a/src/ISO14496/Box/XML.php b/src/ISO14496/Box/XML.php
index 42d8617..5d5aa4f 100644
--- a/src/ISO14496/Box/XML.php
+++ b/src/ISO14496/Box/XML.php
@@ -67,12 +67,12 @@ final class ISO14496_Box_XML extends ISO14496_Box_Full
*
* @param Reader $reader The reader object.
*/
- public function __construct($reader)
+ public function __construct($reader, &$options = array())
{
- parent::__construct($reader);
+ parent::__construct($reader, $options);
$this->_xml = $this->_reader->read
- ($this->_offset + $this->_size - $this->_reader->getOffset());
+ ($this->getOffset() + $this->getSize() - $this->_reader->getOffset());
}
/**