diff --git a/nbproject/project.properties b/nbproject/project.properties index 78c2af4..60707c1 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -1,2 +1,7 @@ -source.encoding=UTF-8 -version=4 +include.path=${php.global.include.path} +source.encoding=UTF-8 +src.dir=src +tags.asp=false +tags.short=true +test.src.dir=tests +web.root=. diff --git a/nbproject/project.xml b/nbproject/project.xml index 738564c..07fb1e7 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -1,9 +1,9 @@ - - - org.netbeans.modules.php.project - - - php-reader - - - + + + org.netbeans.modules.php.project + + + php-reader + + + diff --git a/src/ASF.php b/src/ASF.php deleted file mode 100644 index e2edf9d..0000000 --- a/src/ASF.php +++ /dev/null @@ -1,216 +0,0 @@ - - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class ASF extends ASF_Object_Container -{ - /** @var string */ - private $_filename; - - /** - * Constructs the ASF class with given file and options. - * - * The following options are currently recognized: - * o encoding -- Indicates the encoding that all the texts are presented - * with. By default this is set to utf-8. See the documentation of iconv - * for accepted values. - * o readonly -- Indicates that the file is read from a temporary location - * or another source it cannot be written back to. - * - * @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, $options = array()) - { - $this->_reader = new Reader($this->_filename = $filename); - $this->setOptions($options); - if ($this->getOption("encoding", false) === false) - $this->setOption("encoding", "utf-8"); - $this->setOffset(0); - $this->setSize($this->_reader->getSize()); - $this->constructObjects - (array - (self::HEADER => "Header", - self::DATA => "Data", - self::SIMPLE_INDEX => "SimpleIndex", - self::INDEX => "Index", - self::MEDIA_OBJECT_INDEX => "MediaObjectIndex", - self::TIMECODE_INDEX => "TimecodeIndex")); - } - - /** - * Returns the mandatory header object contained in this file. - * - * @return ASF_Object_Header - */ - public function getHeader() - { - $header = $this->getObjectsByIdentifier(self::HEADER); - return $header[0]; - } - - /** - * Returns the mandatory data object contained in this file. - * - * @return ASF_Object_Data - */ - public function getData() - { - $data = $this->getObjectsByIdentifier(self::DATA); - return $data[0]; - } - - /** - * Returns an array of index objects contained in this file. - * - * @return Array - */ - public function getIndices() - { - return $this->getObjectsByIdentifier - (self::SIMPLE_INDEX . "|" . self::INDEX . "|" . - self::MEDIA_OBJECT_INDEX . "|" . self::TIMECODE_INDEX); - } - - /** - * Writes the changes back to the original media file. - */ - public function write($filename = false) - { - if ($filename === false) - $filename = $this->_filename; - if ($filename !== false && $this->_filename !== false && - realpath($filename) != realpath($this->_filename) && - !copy($this->_filename, $filename)) { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unable to copy source to destination: " . - realpath($this->_filename) . "->" . realpath($filename)); - } - - if (($fd = fopen - ($filename, file_exists($filename) ? "r+b" : "wb")) === false) { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unable to open file for writing: " . $filename); - } - - $header = $this->getHeader(); - $headerLengthOld = $header->getSize(); - $header->removeObjectsByIdentifier(ASF_Object::PADDING); - $header->headerExtension->removeObjectsByIdentifier(ASF_Object::PADDING); - - $headerData = $header->__toString(); - $headerLengthNew = $header->getSize(); - - // Fits right in - if ($headerLengthOld == $headerLengthNew) { - } - - // Fits with adjusted padding - else if ($headerLengthOld >= $headerLengthNew + 24 /* for header */) { - $header->headerExtension->padding->setSize - ($headerLengthOld - $headerLengthNew); - $headerData = $header->__toString(); - $headerLengthNew = $header->getSize(); - } - - // Must expand - else { - $header->headerExtension->padding->setSize(4096); - $headerData = $header->__toString(); - $headerLengthNew = $header->getSize(); - - fseek($fd, 0, SEEK_END); - $oldFileSize = ftell($fd); - ftruncate - ($fd, $newFileSize = $headerLengthNew - $headerLengthOld + - $oldFileSize); - for ($i = 1, $cur = $oldFileSize; $cur > 0; $cur -= 1024, $i++) { - fseek($fd, -(($i * 1024) + ($newFileSize - $oldFileSize)), SEEK_END); - $buffer = fread($fd, 1024); - fseek($fd, -($i * 1024), SEEK_END); - fwrite($fd, $buffer, 1024); - } - } - - fseek($fd, 0); - fwrite($fd, $headerData, $headerLengthNew); - fclose($fd); - - $this->_filename = $filename; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } -} diff --git a/src/ASF/Exception.php b/src/ASF/Exception.php deleted file mode 100644 index cc29c08..0000000 --- a/src/ASF/Exception.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class ASF_Exception extends Exception -{ -} diff --git a/src/ASF/Object.php b/src/ASF/Object.php deleted file mode 100644 index c81d109..0000000 --- a/src/ASF/Object.php +++ /dev/null @@ -1,301 +0,0 @@ - - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ASF_Object -{ - /* ASF Objects */ - const HEADER = "75b22630-668e-11cf-a6d9-00aa0062ce6c"; - const DATA = "75b22636-668e-11cf-a6d9-00aa0062ce6c"; - const SIMPLE_INDEX = "33000890-e5b1-11cf-89f4-00a0c90349cb"; - const INDEX = "d6e229d3-35da-11d1-9034-00a0c90349be"; - const MEDIA_OBJECT_INDEX = "feb103f8-12ad-4c64-840f-2a1d2f7ad48c"; - const TIMECODE_INDEX = "3cb73fd0-0c4a-4803-953d-edf7b6228f0c"; - - /* Header Objects */ - const FILE_PROPERTIES = "8cabdca1-a947-11cf-8ee4-00c00c205365"; - const STREAM_PROPERTIES = "b7dc0791-a9b7-11cf-8ee6-00c00c205365"; - const HEADER_EXTENSION = "5fbf03b5-a92e-11cf-8ee3-00c00c205365"; - const CODEC_LIST = "86d15240-311d-11d0-a3a4-00a0c90348f6"; - const SCRIPT_COMMAND = "1efb1a30-0b62-11d0-a39b-00a0c90348f6"; - const MARKER = "f487cd01-a951-11cf-8ee6-00c00c205365"; - const BITRATE_MUTUAL_EXCLUSION = "d6e229dc-35da-11d1-9034-00a0c90349be"; - const ERROR_CORRECTION = "75b22635-668e-11cf-a6d9-00aa0062ce6c"; - const CONTENT_DESCRIPTION = "75b22633-668e-11cf-a6d9-00aa0062ce6c"; - const EXTENDED_CONTENT_DESCRIPTION = "d2d0a440-e307-11d2-97f0-00a0c95ea850"; - const CONTENT_BRANDING = "2211b3fa-bd23-11d2-b4b7-00a0c955fc6e"; - const STREAM_BITRATE_PROPERTIES = "7bf875ce-468d-11d1-8d82-006097c9a2b2"; - const CONTENT_ENCRYPTION = "2211b3fb-bd23-11d2-b4b7-00a0c955fc6e"; - const EXTENDED_CONTENT_ENCRYPTION = "298ae614-2622-4c17-b935-dae07ee9289c"; - const DIGITAL_SIGNATURE = "2211b3fc-bd23-11d2-b4b7-00a0c955fc6e"; - const PADDING = "1806d474-cadf-4509-a4ba-9aabcb96aae8"; - - /* Header Extension Objects */ - const EXTENDED_STREAM_PROPERTIES = "14e6a5cb-c672-4332-8399-a96952065b5a"; - const ADVANCED_MUTUAL_EXCLUSION = "a08649cf-4775-4670-8a16-6e35357566cd"; - const GROUP_MUTUAL_EXCLUSION = "d1465a40-5a79-4338-b71b-e36b8fd6c249"; - const STREAM_PRIORITIZATION = "d4fed15b-88d3-454f-81f0-ed5c45999e24"; - const BANDWIDTH_SHARING = "a69609e6-517b-11d2-b6af-00c04fd908e9"; - const LANGUAGE_LIST = "7c4346a9-efe0-4bfc-b229-393ede415c85"; - const METADATA = "c5f8cbea-5baf-4877-8467-aa8c44fa4cca"; - const METADATA_LIBRARY = "44231c94-9498-49d1-a141-1d134e457054"; - const INDEX_PARAMETERS = "d6e229df-35da-11d1-9034-00a0c90349be"; - const MEDIA_OBJECT_INDEX_PARAMETERS = "6b203bad-3f11-48e4-aca8-d7613de2cfa7"; - const TIMECODE_INDEX_PARAMETERS = "f55e496d-9797-4b5d-8c8b-604dfe9bfb24"; - const COMPATIBILITY = "75b22630-668e-11cf-a6d9-00aa0062ce6c"; - const ADVANCED_CONTENT_ENCRYPTION = "43058533-6981-49e6-9b74-ad12cb86d58c"; - - /** - * The reader object. - * - * @var Reader - */ - protected $_reader; - - /** - * The options array. - * - * @var Array - */ - protected $_options; - - /** @var integer */ - private $_offset = false; - - /** @var string */ - private $_identifier = false; - - /** @var integer */ - private $_size = false; - - /** @var ASF_Object */ - private $_parent = null; - - /** - * Constructs the class with given parameters and options. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - $this->_reader = $reader; - $this->_options = &$options; - - if ($reader === null) { - if (defined($constant = "self::" . strtoupper - (preg_replace - ("/(?<=[a-z])[A-Z]/", "_$0", substr(get_class($this), 11))))) - $this->_identifier = constant($constant); - else { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Object identifier could not be determined"); - } - } else { - $this->_offset = $this->_reader->getOffset(); - $this->_identifier = $this->_reader->readGUID(); - $this->_size = $this->_reader->readInt64LE(); - } - } - - /** - * Returns the file offset to object start, or false if the object - * was created on heap. - * - * @return integer - */ - public final function getOffset() { return $this->_offset; } - - /** - * Sets the file offset where the object starts. - * - * @param integer $offset The file offset to object start. - */ - public final function setOffset($offset) { $this->_offset = $offset; } - - /** - * Returns the GUID of the ASF object. - * - * @return string - */ - public final function getIdentifier() { return $this->_identifier; } - - /** - * Set the GUID of the ASF object. - * - * @param string $id The GUID - */ - public final function setIdentifier($identifier) - { - $this->_identifier = $identifier; - } - - /** - * Returns the object size in bytes, including the header. - * - * @return integer - */ - public final function getSize() { return $this->_size; } - - /** - * Sets the object size. The size must include the 24 byte header. - * - * @param integer $size The object size. - */ - public final 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 options array. - * - * @return Array - */ - public final 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 final function getOption($option, $defaultValue = false) - { - if (isset($this->_options[$option])) - return $this->_options[$option]; - return $defaultValue; - } - - /** - * Sets the options array. See {@link ASF} class for available options. - * - * @param Array $options The options array. - */ - public final 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 final function setOption($option, $value) - { - $this->_options[$option] = $value; - } - - /** - * Returns the parent object containing this object. - * - * @return ASF_Object - */ - public final function getParent() { return $this->_parent; } - - /** - * Sets the parent containing object. - * - * @param ASF_Object $parent The parent object. - */ - public final function setParent(&$parent) { $this->_parent = $parent; } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst($name))) - return call_user_func(array($this, "get" . ucfirst($name))); - if (method_exists($this, "is" . ucfirst($name))) - return call_user_func(array($this, "is" . ucfirst($name))); - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unknown 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 { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unknown field: " . $name); - } - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public abstract function isMandatory(); - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public abstract function isMultiple(); -} diff --git a/src/ASF/Object/AdvancedContentEncryption.php b/src/ASF/Object/AdvancedContentEncryption.php deleted file mode 100644 index 9a5583d..0000000 --- a/src/ASF/Object/AdvancedContentEncryption.php +++ /dev/null @@ -1,186 +0,0 @@ -Advanced Content Encryption Object lets authors protect content by - * using Next Generation Windows Media Digital Rights Management for Network - * Devices. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_AdvancedContentEncryption extends ASF_Object -{ - const WINDOWS_MEDIA_DRM_NETWORK_DEVICES = - "7a079bb6-daa4-4e12-a5ca-91d3 8dc11a8d"; - - /** @var Array */ - private $_contentEncryptionRecords = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - $contentEncryptionRecordsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $contentEncryptionRecordsCount; $i++) { - $entry = array("systemId" => $this->_reader->readGUID(), - "systemVersion" => $this->_reader->readUInt32LE(), - "streamNumbers" => array()); - $encryptedObjectRecordCount = $this->_reader->readUInt16LE(); - for ($j = 0; $j < $encryptedObjectRecordCount; $j++) { - $this->_reader->skip(4); - $entry["streamNumbers"][] = $this->_reader->readUInt16LE(); - } - $dataCount = $this->_reader->readUInt32LE(); - $entry["data"] = $this->_reader->read($dataCount); - $this->_contentEncryptionRecords[] = $entry; - } - } - - /** - * Returns an array of content encryption records. Each record consists of the - * following keys. - * - * o systemId -- Specifies the unique identifier for the content encryption - * system. - * - * o systemVersion -- Specifies the version of the content encryption - * system. - * - * o streamNumbers -- An array of stream numbers a particular Content - * Encryption Record is associated with. A value of 0 in this field - * indicates that it applies to the whole file; otherwise, the entry - * applies only to the indicated stream number. - * - * o data -- The content protection data for this Content Encryption Record. - * - * @return Array - */ - public function getContentEncryptionRecords() - { - return $this->_contentEncryptionRecords; - } - - /** - * Sets the array of content encryption records. Each record must consist of - * the following keys. - * - * o systemId -- Specifies the unique identifier for the content encryption - * system. - * - * o systemVersion -- Specifies the version of the content encryption - * system. - * - * o streamNumbers -- An array of stream numbers a particular Content - * Encryption Record is associated with. A value of 0 in this field - * indicates that it applies to the whole file; otherwise, the entry - * applies only to the indicated stream number. - * - * o data -- The content protection data for this Content Encryption Record. - * - * @param Array $contentEncryptionRecords The array of content encryption - * records. - */ - public function setContentEncryptionRecords($contentEncryptionRecords) - { - $this->_contentEncryptionRecords = $contentEncryptionRecords; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toUInt16LE - ($contentEncryptionRecordsCount = - count($this->_contentEncryptionRecords)); - for ($i = 0; $i < $contentEncryptionRecordsCount; $i++) { - $data .= - Transform::toGUID($this->_contentEncryptionRecords["systemId"]) . - Transform::toUInt32LE - ($this->_contentEncryptionRecords["systemVersion"]) . - Transform::toUInt16LE - ($encryptedObjectRecordCount = - $this->_contentEncryptionRecords["streamNumbers"]); - for ($j = 0; $j < $encryptedObjectRecordCount; $j++) - $data .= - Transform::toUInt16LE(1) . Transform::toUInt16LE(2) . - Transform::toUInt16LE - ($this->_contentEncryptionRecords["streamNumbers"][$j]); - $data .= strlen($this->_contentEncryptionRecords["data"]) . - $this->_contentEncryptionRecords; - } - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/AdvancedMutualExclusion.php b/src/ASF/Object/AdvancedMutualExclusion.php deleted file mode 100644 index 8600655..0000000 --- a/src/ASF/Object/AdvancedMutualExclusion.php +++ /dev/null @@ -1,159 +0,0 @@ -Advanced Mutual Exclusion Object identifies streams that have a - * mutual exclusion relationship to each other (in other words, only one of the - * streams within such a relationship can be streamed—the rest are ignored). - * There should be one instance of this object for each set of objects that - * contain a mutual exclusion relationship. The exclusion type is used so that - * implementations can allow user selection of common choices, such as language. - * This object must be used if any of the streams in the mutual exclusion - * relationship are hidden. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_AdvancedMutualExclusion extends ASF_Object -{ - const MUTEX_LANGUAGE = "d6e22a00-35da-11d1-9034-00a0c90349be"; - const MUTEX_BITRATE = "d6e22a01-35da-11d1-9034-00a0c90349be"; - const MUTEX_UNKNOWN = "d6e22a02-35da-11d1-9034-00a0c90349be"; - - /** @var string */ - private $_exclusionType; - - /** @var Array */ - private $_streamNumbers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_exclusionType = $this->_reader->readGUID(); - $streamNumbersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $streamNumbersCount; $i++) - $this->_streamNumbers[] = $this->_reader->readUInt16LE(); - } - - /** - * Returns the nature of the mutual exclusion relationship. - * - * @return string - */ - public function getExclusionType() { return $this->_exclusionType; } - - /** - * Returns the nature of the mutual exclusion relationship. - * - * @return string - */ - public function setExclusionType($exclusionType) - { - $this->_exclusionType = $exclusionType; - } - - /** - * Returns an array of stream numbers. - * - * @return Array - */ - public function getStreamNumbers() { return $this->_streamNumbers; } - - /** - * Sets the array of stream numbers. - * - * @return Array - */ - public function setStreamNumbers($streamNumbers) - { - $this->_streamNumbers = $streamNumbers; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_exclusionType) . - Transform::toUInt16LE($streamNumbersCount = count($this->_streamNumbers)); - for ($i = 0; $i < $streamNumbersCount; $i++) - $data .= Transform::toUInt16LE($this->_streamNumbers[$i]); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/BandwidthSharing.php b/src/ASF/Object/BandwidthSharing.php deleted file mode 100644 index 959cd3a..0000000 --- a/src/ASF/Object/BandwidthSharing.php +++ /dev/null @@ -1,226 +0,0 @@ -Bandwidth Sharing Object indicates streams that share bandwidth in - * such a way that the maximum bandwidth of the set of streams is less than the - * sum of the maximum bandwidths of the individual streams. There should be one - * instance of this object for each set of objects that share bandwidth. Whether - * or not this object can be used meaningfully is content-dependent. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_BandwidthSharing extends ASF_Object -{ - const SHARING_EXCLUSIVE = "af6060aa-5197-11d2-b6af-00c04fd908e9"; - const SHARING_PARTIAL = "af6060ab-5197-11d2-b6af-00c04fd908e9"; - - /** @var string */ - private $_sharingType; - - /** @var integer */ - private $_dataBitrate; - - /** @var integer */ - private $_bufferSize; - - /** @var Array */ - private $_streamNumbers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader = null, $options); - - if ($reader === null) - return; - - $this->_sharingType = $this->_reader->readGUID(); - $this->_dataBitrate = $this->_reader->readUInt32LE(); - $this->_bufferSize = $this->_reader->readUInt32LE(); - $streamNumbersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $streamNumbersCount; $i++) - $this->_streamNumbers[] = $this->_reader->readUInt16LE(); - } - - /** - * Returns the type of sharing relationship for this object. Two types are - * predefined: SHARING_PARTIAL, in which any number of the streams in the - * relationship may be streaming data at any given time; and - * SHARING_EXCLUSIVE, in which only one of the streams in the relationship - * may be streaming data at any given time. - * - * @return string - */ - public function getSharingType() { return $this->_sharingType; } - - /** - * Sets the type of sharing relationship for this object. Two types are - * predefined: SHARING_PARTIAL, in which any number of the streams in the - * relationship may be streaming data at any given time; and - * SHARING_EXCLUSIVE, in which only one of the streams in the relationship - * may be streaming data at any given time. - * - * @return string - */ - public function setSharingType($sharingType) - { - $this->_sharingType = $sharingType; - } - - /** - * Returns the leak rate R, in bits per second, of a leaky bucket that - * contains the data portion of all of the streams, excluding all ASF Data - * Packet overhead, without overflowing. The size of the leaky bucket is - * specified by the value of the Buffer Size field. This value can be less - * than the sum of all of the data bit rates in the - * {@link ASF_Object_ExtendedStreamProperties Extended Stream Properties} - * Objects for the streams contained in this bandwidth-sharing relationship. - * - * @return integer - */ - public function getDataBitrate() { return $this->_dataBitrate; } - - /** - * Sets the leak rate R, in bits per second, of a leaky bucket that contains - * the data portion of all of the streams, excluding all ASF Data Packet - * overhead, without overflowing. The size of the leaky bucket is specified by - * the value of the Buffer Size field. This value can be less than the sum of - * all of the data bit rates in the - * {@link ASF_Object_ExtendedStreamProperties Extended Stream Properties} - * Objects for the streams contained in this bandwidth-sharing relationship. - * - * @param integer $dataBitrate The data bitrate. - */ - public function setDataBitrate($dataBitrate) - { - $this->_dataBitrate = $dataBitrate; - } - - /** - * Specifies the size B, in bits, of the leaky bucket used in the Data Bitrate - * definition. This value can be less than the sum of all of the buffer sizes - * in the {@link ASF_Object_ExtendedStreamProperties Extended Stream - * Properties} Objects for the streams contained in this bandwidth-sharing - * relationship. - * - * @return integer - */ - public function getBufferSize() { return $this->_bufferSize; } - - /** - * Sets the size B, in bits, of the leaky bucket used in the Data Bitrate - * definition. This value can be less than the sum of all of the buffer sizes - * in the {@link ASF_Object_ExtendedStreamProperties Extended Stream - * Properties} Objects for the streams contained in this bandwidth-sharing - * relationship. - * - * @param integer $bufferSize The buffer size. - */ - public function setBufferSize($bufferSize) - { - $this->_bufferSize = $bufferSize; - } - - /** - * Returns an array of stream numbers. - * - * @return Array - */ - public function getStreamNumbers() { return $this->_streamNumbers; } - - /** - * Sets the array of stream numbers. - * - * @param Array $streamNumbers The array of stream numbers. - */ - public function setStreamNumbers($streamNumbers) - { - $this->_streamNumbers = $streamNumbers; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_sharingType) . - Transform::toUInt32LE($this->_dataBitrate) . - Transform::toUInt32LE($this->_bufferSize) . - Transform::toUInt16LE($streamNumbersCount = count($this->_streamNumber)); - for ($i = 0; $i < $streamNumbersCount; $i++) - $data .= Transform::toUInt16LE($this->_streamNumbers[$i]); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/BitrateMutualExclusion.php b/src/ASF/Object/BitrateMutualExclusion.php deleted file mode 100644 index dbb321b..0000000 --- a/src/ASF/Object/BitrateMutualExclusion.php +++ /dev/null @@ -1,160 +0,0 @@ -Bitrate Mutual Exclusion Object identifies video streams that have - * a mutual exclusion relationship to each other (in other words, only one of - * the streams within such a relationship can be streamed at any given time and - * the rest are ignored). One instance of this object must be present for each - * set of objects that contains a mutual exclusion relationship. All video - * streams in this relationship must have the same frame size. The exclusion - * type is used so that implementations can allow user selection of common - * choices, such as bit rate. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_BitrateMutualExclusion extends ASF_Object -{ - const MUTEX_LANGUAGE = "d6e22a00-35da-11d1-9034-00a0c90349be"; - const MUTEX_BITRATE = "d6e22a01-35da-11d1-9034-00a0c90349be"; - const MUTEX_UNKNOWN = "d6e22a02-35da-11d1-9034-00a0c90349be"; - - /** @var string */ - private $_exclusionType; - - /** @var Array */ - private $_streamNumbers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_exclusionType = $this->_reader->readGUID(); - $streamNumbersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $streamNumbersCount; $i++) - $this->_streamNumbers[] = $this->_reader->readUInt16LE(); - } - - /** - * Returns the nature of the mutual exclusion relationship. - * - * @return string - */ - public function getExclusionType() { return $this->_exclusionType; } - - /** - * Sets the nature of the mutual exclusion relationship. - * - * @param string $exclusionType The nature of the mutual exclusion - * relationship. - */ - public function setExclusionType($exclusionType) - { - $this->_exclusionType = $exclusionType; - } - - /** - * Returns an array of stream numbers. - * - * @return Array - */ - public function getStreamNumbers() { return $this->_streamNumbers; } - - /** - * Sets the array of stream numbers. - * - * @param Array $streamNumbers The array of stream numbers. - */ - public function setStreamNumbers($streamNumbers) - { - $this->_streamNumbers = $streamNumbers; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_exclusionType) . - Transform::toUInt16LE($streamNumbersCount = count($this->_streamNumbers)); - for ($i = 0; $i < $streamNumbersCount; $i++) - $data .= Transform::toUInt16LE($this->_streamNumbers[$i]); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/CodecList.php b/src/ASF/Object/CodecList.php deleted file mode 100644 index 2824b52..0000000 --- a/src/ASF/Object/CodecList.php +++ /dev/null @@ -1,181 +0,0 @@ -Codec List Object provides user-friendly information about the - * codecs and formats used to encode the content found in the ASF file. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_CodecList extends ASF_Object -{ - const VIDEO_CODEC = 0x1; - const AUDIO_CODEC = 0x2; - const UNKNOWN_CODEC = 0xffff; - - /** @var string */ - private $_reserved; - - /** @var Array */ - private $_entries = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_reserved = $this->_reader->readGUID(); - $codecEntriesCount = $this->_reader->readUInt32LE(); - for ($i = 0; $i < $codecEntriesCount; $i++) { - $entry = array("type" => $this->_reader->readUInt16LE()); - $codecNameLength = $this->_reader->readUInt16LE() * 2; - $entry["codecName"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($codecNameLength)); - $codecDescriptionLength = $this->_reader->readUInt16LE() * 2; - $entry["codecDescription"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($codecDescriptionLength)); - $codecInformationLength = $this->_reader->readUInt16LE(); - $entry["codecInformation"] = - $this->_reader->read($codecInformationLength); - $this->_entries[] = $entry; - } - } - - /** - * Returns the array of codec entries. Each record consists of the following - * keys. - * - * o type -- Specifies the type of the codec used. Use one of the following - * values: VIDEO_CODEC, AUDIO_CODEC, or UNKNOWN_CODEC. - * - * o codecName -- Specifies the name of the codec used to create the - * content. - * - * o codecDescription -- Specifies the description of the format used to - * create the content. - * - * o codecInformation -- Specifies an opaque array of information bytes - * about the codec used to create the content. The meaning of these bytes - * is determined by the codec. - * - * @return Array - */ - public function getEntries() { return $this->_entries; } - - /** - * Sets the array of codec entries. Each record must consist of the following - * keys. - * - * o codecName -- Specifies the name of the codec used to create the - * content. - * - * o codecDescription -- Specifies the description of the format used to - * create the content. - * - * o codecInformation -- Specifies an opaque array of information bytes - * about the codec used to create the content. The meaning of these bytes - * is determined by the codec. - * - * @param Array $entries The array of codec entries. - */ - public function setEntries($entries) { $this->_entries = $entries; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toGUID($this->_reserved) . - Transform::toUInt32LE($codecEntriesCount = count($this->_entries)); - for ($i = 0; $i < $codecEntriesCount; $i++) { - $data .= Transform::toUInt16LE($this->_entries[$i]["type"]) . - Transform::toUInt16LE(strlen($codecName = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_entries[$i]["codecName"]) . "\0\0") / 2) . - Transform::toString16($codecName) . - Transform::toUInt16LE(strlen($codecDescription = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_entries[$i]["codecDescription"]) . "\0\0") / 2) . - Transform::toString16($codecDescription) . - Transform::toUInt16LE(strlen($this->_entries[$i]["codecInformation"])) . - $this->_entries[$i]["codecInformation"]; - } - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Compatibility.php b/src/ASF/Object/Compatibility.php deleted file mode 100644 index 6e71a5f..0000000 --- a/src/ASF/Object/Compatibility.php +++ /dev/null @@ -1,138 +0,0 @@ -Compatibility Object is reserved for future use. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Compatibility extends ASF_Object -{ - /** @var integer */ - private $_profile; - - /** @var integer */ - private $_mode; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_profile = $this->_reader->readUInt8(); - $this->_mode = $this->_reader->readUInt8(); - } - - /** - * Returns the profile field. This field is reserved and is set to 2. - * - * @return integer - */ - public function getProfile() { return $this->_profile; } - - /** - * Returns the profile field. This field is reserved and is set to 2. - * - * @param integer $profile The profile. - */ - public function setProfile($profile) { $this->_profile = $profile; } - - /** - * Returns the mode field. This field is reserved and is set to 1. - * - * @return integer - */ - public function getMode() { return $this->_mode; } - - /** - * Sets the mode field. This field is reserved and is set to 1. - * - * @param integer $mode The mode. - */ - public function setMode($mode) { $this->_mode = $mode; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toUInt8($this->_profile) . - Transform::toUInt8($this->_mode); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Container.php b/src/ASF/Object/Container.php deleted file mode 100644 index 81f424c..0000000 --- a/src/ASF/Object/Container.php +++ /dev/null @@ -1,330 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ASF_Object_Container extends ASF_Object -{ - /** @var Array */ - private $_objects = array(); - - /** - * Reads and constructs the objects found within this object. - */ - protected final function constructObjects($defaultclassnames = array()) - { - while (true) { - $offset = $this->_reader->getOffset(); - if ($offset >= $this->getOffset() + $this->getSize()) - break; - $guid = $this->_reader->readGUID(); - $size = $this->_reader->readInt64LE(); - - $this->_reader->setOffset($offset); - if (isset($defaultclassnames[$guid])) { - if (@fopen($filename = "ASF/Object/" . $defaultclassnames[$guid] . - ".php", "r", true) !== false) - require_once($filename); - if (class_exists - ($classname = "ASF_Object_" . $defaultclassnames[$guid])) - $object = new $classname($this->_reader, $this->_options); - else - $object = new ASF_Object_Unknown($this->_reader, $this->_options); - } else - $object = new ASF_Object_Unknown($this->_reader, $this->_options); - $object->setParent($this); - if (!$this->hasObject($object->getIdentifier())) - $this->_objects[$object->getIdentifier()] = array(); - $this->_objects[$object->getIdentifier()][] = $object; - $this->_reader->setOffset($offset + $size); - } - } - - /** - * Checks whether the object with given identifier is present in the file. The - * identifier can either be the object GUID, or name of the constant - * containing the GUID, or the name of the object class. - * - * Returns true if one or more objects are present, - * false otherwise. - * - * @param string $identifier The object GUID, name of the GUID constant, or - * object class name. - * @return boolean - */ - public final function hasObject($identifier) - { - if (defined($constname = get_class($this) . "::" . strtoupper - (preg_replace("/[A-Z]/", "_$0", $identifier)))) { - $objects = $this->getObjectsByIdentifier(constant($constname)); - return isset($objects[0]); - } - else - return isset($this->_objects[$identifier]); - } - - /** - * Returns all the objects the file contains as an associate array. The object - * identifiers work as keys having an array of ASF objects as associated - * value. - * - * @return Array - */ - public final function getObjects() { return $this->_objects; } - - /** - * Returns an array of objects matching the given object GUID or an empty - * array if no object matched the identifier. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * @param string $identifier The object GUID. - * @return Array - */ - public final function getObjectsByIdentifier($identifier) - { - $matches = array(); - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_objects as $identifier => $objects) - if (preg_match($searchPattern, $identifier)) - foreach ($objects as $object) - $matches[] = $object; - return $matches; - } - - /** - * Returns an array of objects matching the given object constant name or an - * empty array if no object matched the name. - * - * The object constant name can be given in three forms; either using the full - * name of the constant, the name of the class or the shorthand style of the - * class name having its first letter in lower case. - * - * One may use the shorthand $obj->name to access the first box with the name - * given directly. Shorthands will not work with user defined uuid types. - * - * The name may not contain wildcard characters. - * - * @param string $name The object constant name or class name. - * @return Array - */ - public final function getObjectsByName($name) - { - if (defined($constname = get_class($this) . "::" . $name) || - defined($constname = get_class($this) . "::" . strtoupper - (preg_replace - ("/^_/", "", preg_replace("/[A-Z]/", "_$0", $name))))) - return $this->getObjectsByIdentifier(constant($constname)); - return array(); - } - - /** - * Removes any objects matching the given object GUID. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * One may also use the shorthand unset($obj->name) to achieve the same - * result. Wildcards cannot be used with the shorthand method. - * - * @param string $identifier The object GUID. - */ - public final function removeObjectsByIdentifier($identifier) - { - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_objects as $identifier => $objects) - if (preg_match($searchPattern, $identifier)) - unset($this->_objects[$identifier]); - } - - /** - * Removes any objects matching the given object name. - * - * The name can be given in three forms; either using the full name of the - * constant, the name of the class or the shorthand style of the class name - * having its first letter in lower case. - * - * One may also use the shorthand unset($obj->name) to achieve the same - * result. - * - * The name may not contain wildcard characters. - * - * @param string $name The object constant name or class name. - */ - public final function removeObjectsByName($name) - { - if (defined($constname = get_class($this) . "::" . strtoupper - (preg_replace("/[A-Z]/", "_$0", $name)))) - unset($this->_objects[constant($constname)]); - } - - /** - * Adds a new object into the current object and returns it. - * - * @param ASF_Object $object The object to add - * @return ASF_Object - */ - public final function addObject($object) - { - $object->setParent($this); - $object->setOptions($this->_options); - if (!$this->hasObject($object->getIdentifier())) - $this->_objects[$object->getIdentifier()] = array(); - return $this->_objects[$object->getIdentifier()][] = $object; - } - - /** - * Removes the object. - * - * @param ASF_Object $object The object to remove - */ - public final function removeObject($object) - { - if ($this->hasObject($object->getIdentifier())) { - foreach ($this->_objects[$object->getIdentifier()] as $key => $value) - if ($object === $value) - unset($this->_objects[$object->getIdentifier()][$key]); - } - } - - /** - * Override magic function so that $obj->value will work as expected. - * - * The method first attempts to call the appropriate getter method. If no - * field with given name is found, the method attempts to return the right - * object instead. In other words, calling $obj->value will attempt to return - * the first object returned by $this->getObjectsByIdentifier(self::value). - * If no object is found by the given value, a respective class name is tried - * to instantiate and add to the container. - * - * @param string $name The field or object name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst($name))) - return call_user_func(array($this, "get" . ucfirst($name))); - if (method_exists($this, "is" . ucfirst($name))) - return call_user_func(array($this, "is" . ucfirst($name))); - if (defined($constname = get_class($this) . "::" . strtoupper - (preg_replace("/[A-Z]/", "_$0", $name)))) { - $objects = $this->getObjectsByIdentifier(constant($constname)); - if (isset($objects[0])) - return $objects[0]; - else { - if (@fopen($filename = "ASF/Object/" . ucfirst($name) . - ".php", "r", true) !== false) - require_once($filename); - if (class_exists - ($classname = "ASF_Object_" . ucfirst($name))) { - $obj = new $classname(); - $obj->setIdentifier(constant($constname)); - return $this->addObject($obj); - } - } - } - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unknown field/object: " . $name); - } - - /** - * Override magic function so that $obj->value will work as expected. - * - * The method first attempts to call the appropriate setter method. If no - * field with given name is found, the method attempts to set the right - * object instead. In other words, assigning to $obj->value will attempt to - * set the object with given value's identifier. - * - * Please note that using this method will override any prior objects having - * the same object identifier. - * - * @param string $name The field or object name. - * @param string $value The field value or object. - * @return mixed - */ - public function __set($name, $value) - { - if (method_exists($this, "set" . ucfirst($name))) - call_user_func(array($this, "set" . ucfirst($name)), $value); - if (defined($constname = get_class($this) . "::" . strtoupper - (preg_replace("/[A-Z]/", "_$0", $name)))) { - $value->setOptions($this->_options); - $this->_objects[constant($constname)] = array($value); - } - else { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Unknown field/object: " . $name); - } - } - - /** - * Magic function so that isset($obj->value) will work. This method checks - * whether the object by given identifier or name is contained by this - * container. - * - * @param string $name The object identifier or logical name. - * @return boolean - */ - public function __isset($name) { return $this->hasObject($name); } - - /** - * Magic function so that unset($obj->value) will work. This method removes - * all the objects with the given identifier or name. - * - * @param string $name The object identifier or logical name. - */ - public function __unset($name) { $this->removeObjectsByName($name); } -} diff --git a/src/ASF/Object/ContentBranding.php b/src/ASF/Object/ContentBranding.php deleted file mode 100644 index 9c372f9..0000000 --- a/src/ASF/Object/ContentBranding.php +++ /dev/null @@ -1,219 +0,0 @@ -Content Branding Object stores branding data for an ASF file, - * including information about a banner image and copyright associated with the - * file. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ContentBranding extends ASF_Object -{ - /** Indicates that there is no banner */ - const TYPE_NONE = 0; - - /** Indicates that the data represents a bitmap */ - const TYPE_BMP = 1; - - /** Indicates that the data represents a JPEG */ - const TYPE_JPEG = 2; - - /** Indicates that the data represents a GIF */ - const TYPE_GIF = 3; - - - /** @var integer */ - private $_bannerImageType; - - /** @var string */ - private $_bannerImageData; - - /** @var string */ - private $_bannerImageUrl; - - /** @var string */ - private $_copyrightUrl; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_bannerImageType = $this->_reader->readUInt32LE(); - $bannerImageDataSize = $this->_reader->readUInt32LE(); - $this->_bannerImageData = $this->_reader->read($bannerImageDataSize); - $bannerImageUrlLength = $this->_reader->readUInt32LE(); - $this->_bannerImageUrl = $this->_reader->read($bannerImageUrlLength); - $copyrightUrlLength = $this->_reader->readUInt32LE(); - $this->_copyrightUrl = $this->_reader->read($copyrightUrlLength); - } - - /** - * Returns the type of data contained in the Banner Image Data. Valid - * values are 0 to indicate that there is no banner image data; 1 to indicate - * that the data represent a bitmap; 2 to indicate that the data represents a - * JPEG; and 3 to indicate that the data represents a GIF. If this value is - * set to 0, then the Banner Image Data Size field is set to 0, and the - * Banner Image Data field is empty. - * - * @return integer - */ - public function getBannerImageType() { return $this->_bannerImageType; } - - /** - * Sets the type of data contained in the Banner Image Data. Valid - * values are 0 to indicate that there is no banner image data; 1 to indicate - * that the data represent a bitmap; 2 to indicate that the data represents a - * JPEG; and 3 to indicate that the data represents a GIF. If this value is - * set to 0, then the Banner Image Data Size field is set to 0, and the - * Banner Image Data field is empty. - * - * @param integer $bannerImageType The type of data. - */ - public function setBannerImageType($bannerImageType) - { - $this->_bannerImageType = $bannerImageType; - } - - /** - * Returns the entire banner image, including the header for the appropriate - * image format. - * - * @return string - */ - public function getBannerImageData() { return $this->_bannerImageData; } - - /** - * Sets the entire banner image, including the header for the appropriate - * image format. - * - * @param string $bannerImageData The entire banner image. - */ - public function setBannerImageData($bannerImageData) - { - $this->_bannerImageData = $bannerImageData; - } - - /** - * Returns, if present, a link to more information about the banner image. - * - * @return string - */ - public function getBannerImageUrl() { return $this->_bannerImageUrl; } - - /** - * Sets a link to more information about the banner image. - * - * @param string $bannerImageUrl The link. - */ - public function setBannerImageUrl($bannerImageUrl) - { - $this->_bannerImageUrl = $bannerImageUrl; - } - - /** - * Returns, if present, a link to more information about the copyright for the - * content. - * - * @return string - */ - public function getCopyrightUrl() { return $this->_copyrightUrl; } - - /** - * Sets a link to more information about the copyright for the content. - * - * @param string $copyrightUrl The copyright link. - */ - public function setCopyrightUrl($copyrightUrl) - { - $this->_copyrightUrl = $copyrightUrl; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toUInt32LE($this->_bannerImageType) . - Transform::toUInt32LE(count($this->_bannerImageData)) . - $this->_bannerImageData . - Transform::toUInt32LE(count($this->_bannerImageUrl)) . - $this->_bannerImageUrl . - Transform::toUInt32LE(count($this->_copyrightUrl)) . - $this->_copyrightUrl; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ContentDescription.php b/src/ASF/Object/ContentDescription.php deleted file mode 100644 index 12a4698..0000000 --- a/src/ASF/Object/ContentDescription.php +++ /dev/null @@ -1,238 +0,0 @@ -Content Description Object lets authors record well-known data - * describing the file and its contents. This object is used to store standard - * bibliographic information such as title, author, copyright, description, and - * rating information. This information is pertinent to the entire file. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ContentDescription extends ASF_Object -{ - /** @var string */ - private $_title; - - /** @var string */ - private $_author; - - /** @var string */ - private $_copyright; - - /** @var string */ - private $_description; - - /** @var string */ - private $_rating; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $titleLen = $this->_reader->readUInt16LE(); - $authorLen = $this->_reader->readUInt16LE(); - $copyrightLen = $this->_reader->readUInt16LE(); - $descriptionLen = $this->_reader->readUInt16LE(); - $ratingLen = $this->_reader->readUInt16LE(); - - $this->_title = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($titleLen)); - $this->_author = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($authorLen)); - $this->_copyright = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($copyrightLen)); - $this->_description = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($descriptionLen)); - $this->_rating = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($ratingLen)); - } - - /** - * Returns the title information. - * - * @return string - */ - public function getTitle() { return $this->_title; } - - /** - * Sets the title information. - * - * @param string $title The title information. - */ - public function setTitle($title) { $this->_title = $title; } - - /** - * Returns the author information. - * - * @return string - */ - public function getAuthor() { return $this->_author; } - - /** - * Sets the author information. - * - * @param string $author The author information. - */ - public function setAuthor($author) { $this->_author = $author; } - - /** - * Returns the copyright information. - * - * @return string - */ - public function getCopyright() { return $this->_copyright; } - - /** - * Sets the copyright information. - * - * @param string $copyright The copyright information. - */ - public function setCopyright($copyright) { $this->_copyright = $copyright; } - - /** - * Returns the description information. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the description information. - * - * @param string $description The description information. - */ - public function setDescription($description) - { - $this->_description = $description; - } - - /** - * Returns the rating information. - * - * @return string - */ - public function getRating() { return $this->_rating; } - - /** - * Sets the rating information. - * - * @param string $rating The rating information. - */ - public function setRating($rating) { $this->_rating = $rating; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $title = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_title ? $this->_title . "\0" : ""); - $author = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_author ? $this->_author . "\0" : ""); - $copyright = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_copyright ? $this->_copyright . "\0" : ""); - $description = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_description ? $this->_description . "\0" : ""); - $rating = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_rating ? $this->_rating . "\0" : ""); - - $data = - Transform::toUInt16LE(strlen($title)) . - Transform::toUInt16LE(strlen($author)) . - Transform::toUInt16LE(strlen($copyright)) . - Transform::toUInt16LE(strlen($description)) . - Transform::toUInt16LE(strlen($rating)) . - Transform::toString16($title) . - Transform::toString16($author) . - Transform::toString16($copyright) . - Transform::toString16($description) . - Transform::toString16($rating); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ContentEncryption.php b/src/ASF/Object/ContentEncryption.php deleted file mode 100644 index 0773ff7..0000000 --- a/src/ASF/Object/ContentEncryption.php +++ /dev/null @@ -1,198 +0,0 @@ -Content Encryption Object lets authors protect content by using - * Microsoft® Digital Rights Manager version 1. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ContentEncryption extends ASF_Object -{ - /** @var string */ - private $_secretData; - - /** @var string */ - private $_protectionType; - - /** @var string */ - private $_keyId; - - /** @var string */ - private $_licenseUrl; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $secretDataLength = $this->_reader->readUInt32LE(); - $this->_secretData = $this->_reader->read($secretDataLength); - $protectionTypeLength = $this->_reader->readUInt32LE(); - $this->_protectionType = $this->_reader->readString8($protectionTypeLength); - $keyIdLength = $this->_reader->readUInt32LE(); - $this->_keyId = $this->_reader->readString8($keyIdLength); - $licenseUrlLength = $this->_reader->readUInt32LE(); - $this->_licenseUrl = $this->_reader->readString8($licenseUrlLength); - } - - /** - * Returns the secret data. - * - * @return string - */ - public function getSecretData() { return $this->_secretData; } - - /** - * Sets the secret data. - * - * @param string $secretData The secret data. - */ - public function setSecretData($secretData) - { - $this->_secretData = $secretData; - } - - /** - * Returns the type of protection mechanism used. The value of this field - * is set to "DRM". - * - * @return string - */ - public function getProtectionType() { return $this->_protectionType; } - - /** - * Sets the type of protection mechanism used. The value of this field - * is to be set to "DRM". - * - * @param string $protectionType The protection mechanism used. - */ - public function setProtectionType($protectionType) - { - $this->_protectionType = $protectionType; - } - - /** - * Returns the key ID used. - * - * @return string - */ - public function getKeyId() { return $this->_keyId; } - - /** - * Sets the key ID used. - * - * @param string $keyId The key ID used. - */ - public function setKeyId($keyId) { $this->_keyId = $keyId; } - - /** - * Returns the URL from which a license to manipulate the content can be - * acquired. - * - * @return string - */ - public function getLicenseUrl() { return $this->_licenseUrl; } - - /** - * Returns the URL from which a license to manipulate the content can be - * acquired. - * - * @param string $licenseUrl The URL from which a license can be acquired. - */ - public function setLicenseUrl($licenseUrl) - { - $this->_licenseUrl = $licenseUrl; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toUInt32LE(strlen($this->_secretData)) . - $this->_secretData . - Transform::toUInt32LE($len = strlen($this->_protectionType) + 1) . - Transform::toString8($this->_protectionType, $len) . - Transform::toUInt32LE($len = strlen($this->_keyId) + 1) . - Transform::toString8($this->_keyId, $len) . - Transform::toUInt32LE($len = strlen($this->_licenseUrl) + 1) . - Transform::toString8($this->_licenseUrl, $len); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Data.php b/src/ASF/Object/Data.php deleted file mode 100644 index 058310f..0000000 --- a/src/ASF/Object/Data.php +++ /dev/null @@ -1,142 +0,0 @@ -Data Object contains all of the Data Packets for a file. - * These Data Packets are organized in terms of increasing send times. A Data - * Packet can contain interleaved data from several digital media streams. - * This data can consist of entire objects from one or more streams. - * Alternatively, it can consist of partial objects (fragmentation). - * - * Capabilities provided within the interleave packet definition include: - * o Single or multiple payload types per Data Packet - * o Fixed-size Data Packets - * o Error correction information (optional) - * o Clock information (optional) - * o Redundant sample information, such as presentation time stamp (optional) - * - * @todo Implement support for ASF Data Packets - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Data extends ASF_Object -{ - /** @var string */ - private $_fileId; - - /** @var integer */ - private $_totalDataPackets; - - /** @var Array */ - private $_dataPackets; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_fileId = $this->_reader->readGUID(); - $this->_totalDataPackets = $this->_reader->readInt64LE(); - $this->_reader->skip(2); - /* Support for Data Packets is not done yet - * for ($i = 0; $i < $this->_totalDataPackets; $i++) - * $this->_dataPackets[] = new ASF_Object_Data_Packet($reader); - */ - } - - /** - * Returns the unique identifier for this ASF file. The value of this field - * is changed every time the file is modified in any way. The value of this - * field is identical to the value of the File ID field of the - * Header Object. - * - * @return string - */ - public function getFileId() { return $this->_fileId; } - - /** - * Returns the number of ASF Data Packet entries that exist within the Data - * Object. It must be equal to the Data Packet Count field in the - * File Properties Object. The value of this field is invalid if the - * broadcast flag field of the File Properties Object is set to 1. - * - * @return integer - */ - public function getTotalDataPackets() { return $this->_totalDataPackets; } - - /** - * Returns an array of Data Packets. - * - * @return Array - */ - public function getDataPackets() - { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Support for Data Packets is not done yet"); - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } -} diff --git a/src/ASF/Object/DigitalSignature.php b/src/ASF/Object/DigitalSignature.php deleted file mode 100644 index 600f096..0000000 --- a/src/ASF/Object/DigitalSignature.php +++ /dev/null @@ -1,141 +0,0 @@ -Digital Signature Object lets authors sign the portion of their - * header that lies between the end of the File Properties Object and the - * beginning of the Digital Signature Object. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_DigitalSignature extends ASF_Object -{ - /** @var integer */ - private $_type; - - /** @var string */ - private $_data; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_type = $this->_reader->readUInt32LE(); - $dataLength = $this->_reader->readUInt32LE(); - $this->_data = $this->_reader->read($dataLength); - } - - /** - * Returns the type of digital signature used. This field is set to 2. - * - * @return integer - */ - public function getType() { return $this->_type; } - - /** - * Sets the type of digital signature used. This field must be set to 2. - * - * @param integer $type The type of digital signature used. - */ - public function setType($type) { $this->_type = $type; } - - /** - * Returns the digital signature data. - * - * @return string - */ - public function getData() { return $this->_data; } - - /** - * Sets the digital signature data. - * - * @return string - */ - public function setData($data) { $this->_data = $data; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toUInt32LE($this->_type) . - Transform::toUInt32LE(strlen($this->_data)) . $this->_data; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ErrorCorrection.php b/src/ASF/Object/ErrorCorrection.php deleted file mode 100644 index 6beecd9..0000000 --- a/src/ASF/Object/ErrorCorrection.php +++ /dev/null @@ -1,152 +0,0 @@ -Error Correction Object defines the error correction method. This - * enables different error correction schemes to be used during content - * creation. The Error Correction Object contains provisions for opaque - * information needed by the error correction engine for recovery. For example, - * if the error correction scheme were a simple N+1 parity scheme, then the - * value of N would have to be available in this object. - * - * Note that this does not refer to the same thing as the Error Correction - * Type field in the {@link ASF_Object_StreamProperties Stream Properties - * Object}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ErrorCorrection extends ASF_Object -{ - /** @var string */ - private $_type; - - /** @var string */ - private $_data; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_type = $this->_reader->readGUID(); - $dataLength = $this->_reader->readUInt32LE(); - $this->_data = $this->_reader->read($dataLength); - } - - /** - * Returns the type of error correction. - * - * @return string - */ - public function getType() { return $this->_type; } - - /** - * Sets the type of error correction. - * - * @param string $type The type of error correction. - */ - public function setType($type) { $this->_type = $type; } - - /** - * Returns the data specific to the error correction scheme. The structure for - * the Error Correction Data field is determined by the value stored in - * the Error Correction Type field. - * - * @return Array - */ - public function getData() { return $this->_data; } - - /** - * Sets the data specific to the error correction scheme. The structure for - * the Error Correction Data field is determined by the value stored in - * the Error Correction Type field. - * - * @param Array $data The error correction specific data. - */ - public function setData($data) { $this->_data = $data; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_type) . - Transform::toUInt32LE(strlen($this->_data)) . $this->_data; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ExtendedContentDescription.php b/src/ASF/Object/ExtendedContentDescription.php deleted file mode 100644 index c4f6253..0000000 --- a/src/ASF/Object/ExtendedContentDescription.php +++ /dev/null @@ -1,232 +0,0 @@ -ASF_Extended_Content_Description_Object object implementation. - * This object contains unlimited number of attribute fields giving more - * information about the file. - * - * @todo Implement better handling of various types of attributes - * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ExtendedContentDescription extends ASF_Object -{ - /** @var Array */ - private $_contentDescriptors = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $contentDescriptorsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $contentDescriptorsCount; $i++) { - $nameLen = $this->_reader->readUInt16LE(); - $name = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($nameLen)); - $valueDataType = $this->_reader->readUInt16LE(); - $valueLen = $this->_reader->readUInt16LE(); - - switch ($valueDataType) { - case 0: // string - $this->_contentDescriptors[$name] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($valueLen)); - break; - case 1: // byte array - $this->_contentDescriptors[$name] = $this->_reader->read($valueLen); - break; - case 2: // bool - $this->_contentDescriptors[$name] = - $this->_reader->readUInt32LE() == 1 ? true : false; - break; - case 3: // 32-bit integer - $this->_contentDescriptors[$name] = $this->_reader->readUInt32LE(); - break; - case 4: // 64-bit integer - $this->_contentDescriptors[$name] = $this->_reader->readInt64LE(); - break; - case 5: // 16-bit integer - $this->_contentDescriptors[$name] = $this->_reader->readUInt16LE(); - break; - default: - } - } - } - - /** - * Returns the value of the specified descriptor or false if there - * is no such descriptor defined. - * - * @param string $name The name of the descriptor (ie the name of the field). - * @return string|false - */ - public function getDescriptor($name) - { - if (isset($this->_contentDescriptors[$name])) - return $this->_contentDescriptors[$name]; - return false; - } - - /** - * Sets the given descriptor a new value. - * - * @param string $name The name of the descriptor. - * @param string $value The value of the field. - * @return string|false - */ - public function setDescriptor($name, $value) - { - $this->_contentDescriptors[$name] = $value; - } - - /** - * Returns an associate array of all the descriptors defined having the names - * of the descriptors as the keys. - * - * @return Array - */ - public function getDescriptors() { return $this->_contentDescriptors; } - - /** - * Sets the content descriptor associate array having the descriptor names as - * array keys and their values as associated value. The descriptor names and - * all string values must be encoded in the default character encoding given - * as an option to {@link ASF} class. - * - * @param Array $contentDescriptors The content descriptors - */ - public function setDescriptors($contentDescriptors) - { - $this->_contentDescriptors = $contentDescriptors; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE(count($this->_contentDescriptors)); - - foreach ($this->_contentDescriptors as $name => $value) { - $descriptor = iconv - ($this->getOption("encoding"), "utf-16le", $name ? $name . "\0" : ""); - $data .= Transform::toUInt16LE(strlen($descriptor)) . - Transform::toString16($descriptor); - - if (is_string($value)) { - /* There is no way to distinguish byte arrays from unicode strings and - * hence the need for a list of fields of type byte array */ - static $byteArray = array ( - "W\0M\0/\0M\0C\0D\0I\0\0\0", - "W\0M\0/\0U\0s\0e\0r\0W\0e\0b\0U\0R\0L\0\0\0", - "W\0M\0/\0L\0y\0r\0i\0c\0s\0_\0S\0y\0n\0c\0h\0r\0o\0n\0i\0s\0e\0d\0\0\0", - "W\0M\0/\0P\0i\0c\0t\0u\0r\0e\0\0\0" - ); // TODO: Add to the list if you encounter one - - if (in_array($descriptor, $byteArray)) - $data .= Transform::toUInt16LE(1) . - Transform::toUInt16LE(strlen($value)) . $value; - else { - $value = iconv - ($this->getOption("encoding"), "utf-16le", $value) . "\0\0"; - $data .= Transform::toUInt16LE(0) . - Transform::toUInt16LE(strlen($value)) . - Transform::toString16($value); - } - } - else if (is_bool($value)) - $data .= Transform::toUInt16LE(2) . Transform::toUInt16LE(4) . - Transform::toUInt32LE($value ? 1 : 0); - else if (is_int($value)) - $data .= Transform::toUInt16LE(3) . Transform::toUInt16LE(4) . - Transform::toUInt32LE($value); - else if (is_float($value)) - $data .= Transform::toUInt16LE(4) . Transform::toUInt16LE(8) . - Transform::toInt64LE($value); - else { - // Invalid value and there is nothing to be done so cause a fatal error - require_once("ASF/Exception.php"); - throw new ASF_Exception("Invalid data type"); - } - } - - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ExtendedContentEncryption.php b/src/ASF/Object/ExtendedContentEncryption.php deleted file mode 100644 index 7f7580c..0000000 --- a/src/ASF/Object/ExtendedContentEncryption.php +++ /dev/null @@ -1,121 +0,0 @@ -Extended Content Encryption Object lets authors protect content by - * using the Windows Media Rights Manager 7 Software Development Kit (SDK). - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ExtendedContentEncryption extends ASF_Object -{ - /** @var string */ - private $_data; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $dataSize = $this->_reader->readUInt32LE(); - $this->_data = $this->_reader->read($dataSize); - } - - /** - * Returns the array of bytes required by the DRM client to manipulate the - * protected content. - * - * @return string - */ - public function getData() { return $this->_data; } - - /** - * Sets the array of bytes required by the DRM client to manipulate the - * protected content. - * - * @param string $data The data. - */ - public function setData($data) { $this->_data = $data; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt32LE(strlen($this->_data)) . $this->_data; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/ExtendedStreamProperties.php b/src/ASF/Object/ExtendedStreamProperties.php deleted file mode 100644 index 065269f..0000000 --- a/src/ASF/Object/ExtendedStreamProperties.php +++ /dev/null @@ -1,697 +0,0 @@ -Extended Stream Properties Object defines additional optional - * properties and characteristics of a digital media stream that are not - * described in the Stream Properties Object. - * - * Typically, the basic Stream Properties Object is present in the - * Header Object, and the Extended Stream Properties Object is - * present in the Header Extension Object. Sometimes, however, the - * Stream Properties Object for a stream may be embedded inside the - * Extended Stream Properties Object for that stream. This approach - * facilitates the creation of backward-compatible content. - * - * This object has an optional provision to include application-specific or - * implementation-specific data attached to the payloads of each digital media - * sample stored within a Data Packet. This data can be looked at as - * digital media sample properties and is stored in the Replicated Data - * field of a payload header. The Payload Extension Systems fields of the - * Extended Stream Properties Object describes what this data is and is - * necessary for that data to be parsed, if present. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ExtendedStreamProperties extends ASF_Object -{ - /** - * Indicates, if set, that this digital media stream, if sent over a network, - * must be carried over a reliable data communications transport mechanism. - * This should be set for streams that cannot recover after a lost media - * object. - */ - const RELIABLE = 1; - - /** - * This flag should be set only if the stream is seekable, either by using an - * index object or by estimating according to bit rate (as can sometimes be - * done with audio). This flag pertains to this stream only rather than to the - * entire file. - */ - const SEEKABLE = 2; - - /** - * Indicates, if set, that the stream does not contain any cleanpoints. A - * cleanpoint is any point at which playback could begin without having seen - * the previous media objects. For streams that use key frames, the key frames - * would be the cleanpoints. - */ - const NO_CLEANPOINT = 4; - - /** - * Specifies, if set, that when a stream is joined in mid-transmission, all - * information from the most recent cleanpoint up to the current time should - * be sent before normal streaming begins at the current time. The default - * behavior (when this flag is not set) is to send only the data starting at - * the current time. This flag should only be set for streams that are coming - * from a live source. - */ - const RESEND_LIVE_CLEANPOINTS = 8; - - const AUDIO_MEDIA = "f8699e40-5b4d-11cf-a8fd-00805f5c442b"; - const VIDEO_MEDIA = "bc19efc0-5b4d-11cf-a8fd-00805f5c442b"; - const COMMAND_MEDIA = "59dacfc0-59e6-11d0-a3ac-00a0c90348f6"; - const JFIF_MEDIA = "b61be100-5b4e-11cf-a8fD-00805f5c442b"; - const DEGRADABLE_JPEG_MEDIA = "35907dE0-e415-11cf-a917-00805f5c442b"; - const FILE_TRANSFER_MEDIA = "91bd222c-f21c-497a-8b6d-5aa86bfc0185"; - const BINARY_MEDIA = "3afb65e2-47ef-40f2-ac2c-70a90d71d343"; - - const NO_ERROR_CORRECTION = "20fb5700-5b55-11cf-a8fd-00805f5c442b"; - const AUDIO_SPREAD = "bfc3cd50-618f-11cf-8bb2-00aa00b4e220"; - - const PAYLOAD_EXTENSION_SYSTEM_TIMECODE = - "399595ec-8667-4e2d-8fdb-98814ce76c1e"; - const PAYLOAD_EXTENSION_SYSTEM_FILE_NAME = - "e165ec0e-19ed-45d7-b4a7-25cbd1e28e9b"; - const PAYLOAD_EXTENSION_SYSTEM_CONTENT_TYPE = - "d590dc20-07bc-436c-9cf7-f3bbfbf1a4dc"; - const PAYLOAD_EXTENSION_SYSTEM_PIXEL_ASPECT_RATIO = - "1b1ee554-f9ea-4bc8-821a-376b74e4c4b8"; - const PAYLOAD_EXTENSION_SYSTEM_SAMPLE_DURATION = - "c6bd9450-867f-4907-83a3-c77921b733ad"; - const PAYLOAD_EXTENSION_SYSTEM_ENCRYPTION_SAMPLE_ID = - "6698b84e-0afa-4330-aeb2-1c0a98d7a44d"; - - /** @var integer */ - private $_startTime; - - /** @var integer */ - private $_endTime; - - /** @var integer */ - private $_dataBitrate; - - /** @var integer */ - private $_bufferSize; - - /** @var integer */ - private $_initialBufferFullness; - - /** @var integer */ - private $_alternateDataBitrate; - - /** @var integer */ - private $_alternateBufferSize; - - /** @var integer */ - private $_alternateInitialBufferFullness; - - /** @var integer */ - private $_maximumObjectSize; - - /** @var integer */ - private $_flags; - - /** @var integer */ - private $_streamNumber; - - /** @var integer */ - private $_streamLanguageIndex; - - /** @var integer */ - private $_averageTimePerFrame; - - /** @var Array */ - private $_streamNames = array(); - - /** @var Array */ - private $_payloadExtensionSystems = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_startTime = $this->_reader->readInt64LE(); - $this->_endTime = $this->_reader->readInt64LE(); - $this->_dataBitrate = $this->_reader->readUInt32LE(); - $this->_bufferSize = $this->_reader->readUInt32LE(); - $this->_initialBufferFullness = $this->_reader->readUInt32LE(); - $this->_alternateDataBitrate = $this->_reader->readUInt32LE(); - $this->_alternateBufferSize = $this->_reader->readUInt32LE(); - $this->_alternateInitialBufferFullness = $this->_reader->readUInt32LE(); - $this->_maximumObjectSize = $this->_reader->readUInt32LE(); - $this->_flags = $this->_reader->readUInt32LE(); - $this->_streamNumber = $this->_reader->readUInt16LE(); - $this->_streamLanguageIndex = $this->_reader->readUInt16LE(); - $this->_averageTimePerFrame = $this->_reader->readInt64LE(); - $streamNameCount = $this->_reader->readUInt16LE(); - $payloadExtensionSystemCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $streamNameCount; $i++) { - $streamName = array("languageIndex" => $this->_reader->readUInt16LE()); - $streamNameLength = $this->_reader->readUInt16LE(); - $streamName["streamName"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($streamNameLength)); - $this->_streamNames[] = $streamName; - } - for ($i = 0; $i < $payloadExtensionSystemCount; $i++) { - $payloadExtensionSystem = array - ("extensionSystemId" => $this->_reader->readGUID(), - "extensionDataSize" => $this->_reader->readUInt16LE()); - $extensionSystemInfoLength = $this->_reader->readUInt32LE(); - $payloadExtensionSystem["extensionSystemInfo"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($extensionSystemInfoLength)); - $this->_payloadExtensionSystems[] = $payloadExtensionSystem; - } - } - - /** - * Returns the presentation time of the first object, indicating where this - * digital media stream starts within the context of the timeline of the ASF - * file as a whole. This time value corresponds to presentation times as they - * appear in the data packets (adjusted by the preroll). This field is given - * in units of milliseconds and can optionally be set to 0, in which case it - * will be ignored. - * - * @return integer - */ - public function getStartTime() { return $this->_startTime; } - - /** - * Sets the presentation time of the first object, indicating where this - * digital media stream starts within the context of the timeline of the ASF - * file as a whole. This time value corresponds to presentation times as they - * appear in the data packets (adjusted by the preroll). - * - * The given value must be in units of milliseconds or optionally be set to 0, - * in which case the field will be ignored. - * - * @param integer $startTime The presentation time of the first object. - */ - public function setStartTime($startTime) { $this->_startTime = $startTime; } - - /** - * Returns the presentation time of the last object plus the duration of play, - * indicating where this digital media stream ends within the context of the - * timeline of the ASF file as a whole. This time value corresponds to - * presentation times as they appear in the data packets (adjusted by the - * preroll). This field is given in units of milliseconds and can optionally - * be set to 0, in which case it will be ignored. - * - * @return integer - */ - public function getEndTime() { return $this->_endTime; } - - /** - * Sets the presentation time of the last object plus the duration of play, - * indicating where this digital media stream ends within the context of the - * timeline of the ASF file as a whole. This time value corresponds to - * presentation times as they appear in the data packets (adjusted by the - * preroll). - * - * The given value must be given in units of milliseconds or optionally be set - * to 0, in which case the field will be ignored. - * - * @param integer $endTime The presentation time of the last object plus the - * duration of play. - */ - public function setEndTime($endTime) { $this->_endTime = $endTime; } - - /** - * Returns the leak rate R, in bits per second, of a leaky bucket that - * contains the data portion of the stream without overflowing, excluding all - * ASF Data Packet overhead. The size of the leaky bucket is specified by the - * value of the Buffer Size field. This field has a non-zero value. - * - * @return integer - */ - public function getDataBitrate() { return $this->_dataBitrate; } - - /** - * Sets the leak rate R, in bits per second, of a leaky bucket that - * contains the data portion of the stream without overflowing, excluding all - * ASF Data Packet overhead. The size of the leaky bucket is specified by the - * value of the Buffer Size field. - * - * This field must be given a non-zero value. - * - * @param integer $dataBitrate The leak rate. - */ - public function setDataBitrate($dataBitrate) - { - $this->_dataBitrate = $dataBitrate; - } - - /** - * Returns the size B, in milliseconds, of the leaky bucket used in the - * Data Bitrate definition. - * - * @return integer - */ - public function getBufferSize() { return $this->_bufferSize; } - - /** - * Sets the size B, in milliseconds, of the leaky bucket used in the - * Data Bitrate definition. - * - * @param integer $bufferSize The size. - */ - public function setBufferSize($bufferSize) - { - $this->_bufferSize = $bufferSize; - } - - /** - * Returns the initial fullness, in milliseconds, of the leaky bucket used in - * the Data Bitrate definition. This is the fullness of the buffer at - * the instant before the first bit in the stream is dumped into the bucket. - * Typically, this value is set to 0. This value shall not exceed the value in - * the Buffer Size field. - * - * @return integer - */ - public function getInitialBufferFullness() - { - return $this->_initialBufferFullness; - } - - /** - * Sets the initial fullness, in milliseconds, of the leaky bucket used in the - * Data Bitrate definition. This is the fullness of the buffer at the - * instant before the first bit in the stream is dumped into the bucket. - * Typically, this value is set to 0. This value shall not exceed the value in - * the Buffer Size field. - * - * @param integer $initialBufferFullness The initial fullness. - */ - public function setInitialBufferFullness($initialBufferFullness) - { - $this->_initialBufferFullness = $initialBufferFullness; - } - - /** - * Returns the leak rate RAlt, in bits per second, of a leaky bucket that - * contains the data portion of the stream without overflowing, excluding all - * ASF Data Packet overhead. The size of the leaky bucket is specified - * by the value of the Alternate Buffer Size field. This value is - * relevant in most scenarios where the bit rate is not exactly constant, but - * it is especially useful for streams that have highly variable bit rates. - * This field can optionally be set to the same value as the Data - * Bitrate field. - * - * @return integer - */ - public function getAlternateDataBitrate() - { - return $this->_alternateDataBitrate; - } - - /** - * Sets the leak rate RAlt, in bits per second, of a leaky bucket that - * contains the data portion of the stream without overflowing, excluding all - * ASF Data Packet overhead. The size of the leaky bucket is specified - * by the value of the Alternate Buffer Size field. This value is - * relevant in most scenarios where the bit rate is not exactly constant, but - * it is especially useful for streams that have highly variable bit rates. - * This field can optionally be set to the same value as the Data - * Bitrate field. - * - * @param integer $alternateDataBitrate The alternate leak rate. - */ - public function setAlternateDataBitrate($alternateDataBitrate) - { - $this->_alternateDataBitrate = $alternateDataBitrate; - } - - /** - * Returns the size BAlt, in milliseconds, of the leaky bucket used in the - * Alternate Data Bitrate definition. This value is relevant in most - * scenarios where the bit rate is not exactly constant, but it is especially - * useful for streams that have highly variable bit rates. This field can - * optionally be set to the same value as the Buffer Size field. - * - * @return integer - */ - public function getAlternateBufferSize() - { - return $this->_alternateBufferSize; - } - - /** - * Sets the size BAlt, in milliseconds, of the leaky bucket used in the - * Alternate Data Bitrate definition. This value is relevant in most - * scenarios where the bit rate is not exactly constant, but it is especially - * useful for streams that have highly variable bit rates. This field can - * optionally be set to the same value as the Buffer Size field. - * - * @param integer $alternateBufferSize - */ - public function setAlternateBufferSize($alternateBufferSize) - { - $this->_alternateBufferSize = $alternateBufferSize; - } - - /** - * Returns the initial fullness, in milliseconds, of the leaky bucket used in - * the Alternate Data Bitrate definition. This is the fullness of the - * buffer at the instant before the first bit in the stream is dumped into the - * bucket. Typically, this value is set to 0. This value does not exceed the - * value of the Alternate Buffer Size field. - * - * @return integer - */ - public function getAlternateInitialBufferFullness() - { - return $this->_alternateInitialBufferFullness; - } - - /** - * Sets the initial fullness, in milliseconds, of the leaky bucket used in the - * Alternate Data Bitrate definition. This is the fullness of the - * buffer at the instant before the first bit in the stream is dumped into the - * bucket. Typically, this value is set to 0. This value does not exceed the - * value of the Alternate Buffer Size field. - * - * @param integer $alternateInitialBufferFullness The alternate initial - * fullness. - */ - public function setAlternateInitialBufferFullness - ($alternateInitialBufferFullness) - { - $this->_alternateInitialBufferFullness = $alternateInitialBufferFullness; - } - - /** - * Returns the maximum size of the largest sample stored in the data packets - * for a stream. A value of 0 means unknown. - * - * @return integer - */ - public function getMaximumObjectSize() - { - return $this->_maximumObjectSize; - } - - /** - * Sets the maximum size of the largest sample stored in the data packets for - * a stream. A value of 0 means unknown. - * - * @param integer $maximumObjectSize The maximum size of the largest sample. - */ - public function setMaximumObjectSize($maximumObjectSize) - { - $this->_maximumObjectSize = $maximumObjectSize; - } - - /** - * Returns the average time duration, measured in 100-nanosecond units, of - * each frame. This number should be rounded to the nearest integer. This - * field can optionally be set to 0 if the average time per frame is unknown - * or unimportant. It is recommended that this field be set for video. - * - * @return integer - */ - public function getAverageTimePerFrame() - { - return $this->_averageTimePerFrame; - } - - /** - * Sets the average time duration, measured in 100-nanosecond units, of - * each frame. This number should be rounded to the nearest integer. This - * field can optionally be set to 0 if the average time per frame is unknown - * or unimportant. It is recommended that this field be set for video. - * - * @param integer $averageTimePerFrame The average time duration. - */ - public function setAverageTimePerFrame($averageTimePerFrame) - { - $this->_averageTimePerFrame = $averageTimePerFrame; - } - - /** - * Returns the number of this stream. 0 is an invalid stream number (that is, - * other Header Objects use stream number 0 to refer to the entire file - * as a whole rather than to a specific media stream within the file). Valid - * values are between 1 and 127. - * - * @return integer - */ - public function getStreamNumber() - { - return $this->_streamNumber; - } - - /** - * Sets the number of this stream. 0 is an invalid stream number (that is, - * other Header Objects use stream number 0 to refer to the entire file - * as a whole rather than to a specific media stream within the file). Valid - * values are between 1 and 127. - * - * @param integer $streamNumber The number of this stream. - */ - public function setStreamNumber($streamNumber) - { - $this->_streamNumber = $streamNumber; - } - - /** - * Returns the language, if any, which the content of the stream uses or - * assumes. Refer to the {@link LanguageList Language List Object} description - * for the details concerning how the Stream Language Index and - * Language Index fields should be used. Note that this is an index - * into the languages listed in the Language List Object rather than a - * language identifier. - * - * @return integer - */ - public function getStreamLanguageIndex() - { - return $this->_streamLanguageIndex; - } - - /** - * Sets the language, if any, which the content of the stream uses or assumes. - * Refer to the {@link LanguageList Language List Object} description for the - * details concerning how the Stream Language Index and Language - * Index fields should be used. Note that this is an index into the - * languages listed in the Language List Object rather than a language - * identifier. - * - * @param integer $streamLanguageIndex The language index. - */ - public function setStreamLanguageIndex($streamLanguageIndex) - { - $this->_streamLanguageIndex = $streamLanguageIndex; - } - - /** - * Returns an array of Stream Names. Each stream name instance is potentially - * localized into a specific language. The Language Index field - * indicates the language in which the Stream Name has been written. - * - * The array entry contains the following keys: - * o languageIndex -- The language index - * o streamName -- The localized stream name - * - * @return Array - */ - public function getStreamNames() - { - return $this->_streamNames; - } - - /** - * Sets the array of stream names. Each stream name instance is potentially - * localized into a specific language. The Language Index field - * indicates the language in which the Stream Name has been written. - * - * The array entries are to contain the following keys: - * o languageIndex -- The language index - * o streamName -- The localized stream name - * - * @param Array $streamNames The array of stream names - */ - public function setStreamNames($streamNames) - { - $this->_streamNames = $streamNames; - } - - /** - * Returns an array of payload extension systems. Payload extensions provide a - * way for content creators to specify kinds of data that will appear in the - * payload header for every payload from this stream. This system is used when - * stream properties must be conveyed at the media object level. The - * Replicated Data bytes in the payload header will contain these - * properties in the order in which the Payload Extension Systems - * appear in this object. A Payload Extension System must appear in the - * Extended Stream Properties Object for each type of per-media-object - * properties that will appear with the payloads for this stream. - * - * The array entry contains the following keys: - * o extensionSystemId -- Specifies a unique identifier for the extension - * system. - * o extensionDataSize -- Specifies the fixed size of the extension data for - * this system that will appear in the replicated data alongside every - * payload for this stream. If this extension system uses variable-size - * data, then this should be set to 0xffff. Note, however, that replicated - * data length is limited to 255 bytes, which limits the total size of all - * extension systems for a particular stream. - * o extensionSystemInfo -- Specifies additional information to describe - * this extension system (optional). - * - * @return Array - */ - public function getPayloadExtensionSystems() - { - return $this->_payloadExtensionSystems; - } - - /** - * Sets an array of payload extension systems. Payload extensions provide a - * way for content creators to specify kinds of data that will appear in the - * payload header for every payload from this stream. This system is used when - * stream properties must be conveyed at the media object level. The - * Replicated Data bytes in the payload header will contain these - * properties in the order in which the Payload Extension Systems - * appear in this object. A Payload Extension System must appear in the - * Extended Stream Properties Object for each type of per-media-object - * properties that will appear with the payloads for this stream. - * - * The array enties are to contain the following keys: - * o extensionSystemId -- Specifies a unique identifier for the extension - * system. - * o extensionDataSize -- Specifies the fixed size of the extension data for - * this system that will appear in the replicated data alongside every - * payload for this stream. If this extension system uses variable-size - * data, then this should be set to 0xffff. Note, however, that replicated - * data length is limited to 255 bytes, which limits the total size of all - * extension systems for a particular stream. - * o extensionSystemInfo -- Specifies additional information to describe - * this extension system (optional). - * - * @param Array $payloadExtensionSystems The array of payload extension - * systems. - */ - public function setPayloadExtensionSystems($payloadExtensionSystems) - { - $this->_payloadExtensionSystems = $payloadExtensionSystems; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toInt64LE($this->_startTime) . - Transform::toInt64LE($this->_endTime) . - Transform::toUInt32LE($this->_dataBitrate) . - Transform::toUInt32LE($this->_bufferSize) . - Transform::toUInt32LE($this->_initialBufferFullness) . - Transform::toUInt32LE($this->_alternateDataBitrate) . - Transform::toUInt32LE($this->_alternateBufferSize) . - Transform::toUInt32LE($this->_alternateInitialBufferFullness) . - Transform::toUInt32LE($this->_maximumObjectSize) . - Transform::toUInt32LE($this->_flags) . - Transform::toUInt16LE($this->_streamNumber) . - Transform::toUInt16LE($this->_streamLanguageIndex) . - Transform::toInt64LE($this->_averageTimePerFrame) . - Transform::toUInt16LE($streamNameCount = count($this->_streamNames)) . - Transform::toUInt16LE - ($payloadExtensionSystemCount = count($this->_payloadExtensionSystems)); - for ($i = 0; $i < $streamNameCount; $i++) - $data .= - Transform::toUInt16LE($this->_streamNames["languageIndex"]) . - Transform::toUInt16LE(strlen($streamName = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_streamNames["streamName"]) . "\0\0")) . - Transform::toString16($streamName); - for ($i = 0; $i < $payloadExtensionSystemCount; $i++) - $data .= - Transform::toGUID($this->_streamNames["extensionSystemId"]) . - Transform::toUInt16LE($this->_streamNames["extensionDataSize"]) . - Transform::toUInt16LE(strlen($extensionSystemInfo = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_streamNames["extensionSystemInfo"]) . "\0\0")) . - Transform::toString16($extensionSystemInfo); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/FileProperties.php b/src/ASF/Object/FileProperties.php deleted file mode 100644 index e6de8d1..0000000 --- a/src/ASF/Object/FileProperties.php +++ /dev/null @@ -1,429 +0,0 @@ -File Properties Object defines the global characteristics of the - * combined digital media streams found within the Data Object. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_FileProperties extends ASF_Object -{ - /** - * Indicates, if set, that a file is in the process of being created (for - * example, for recording applications), and thus that various values stored - * in the header objects are invalid. It is highly recommended that - * post-processing be performed to remove this condition at the earliest - * opportunity. - */ - const BROADCAST = 1; - - /** - * Indicates, if set, that a file is seekable. Note that for files containing - * a single audio stream and a Minimum Data Packet Size field equal to - * the Maximum Data Packet Size field, this flag shall always be set to - * 1. For files containing a single audio stream and a video stream or - * mutually exclusive video streams, this flag is only set to 1 if the file - * contains a matching Simple Index Object for each regular video - * stream. - */ - const SEEKABLE = 2; - - /** @var string */ - private $_fileId; - - /** @var integer */ - private $_fileSize; - - /** @var integer */ - private $_creationDate; - - /** @var integer */ - private $_dataPacketsCount; - - /** @var integer */ - private $_playDuration; - - /** @var integer */ - private $_sendDuration; - - /** @var integer */ - private $_preroll; - - /** @var integer */ - private $_flags; - - /** @var integer */ - private $_minimumDataPacketSize; - - /** @var integer */ - private $_maximumDataPacketSize; - - /** @var integer */ - private $_maximumBitrate; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_fileId = $this->_reader->readGUID(); - $this->_fileSize = $this->_reader->readInt64LE(); - $this->_creationDate = $this->_reader->readInt64LE(); - $this->_dataPacketsCount = $this->_reader->readInt64LE(); - $this->_playDuration = $this->_reader->readInt64LE(); - $this->_sendDuration = $this->_reader->readInt64LE(); - $this->_preroll = $this->_reader->readInt64LE(); - $this->_flags = $this->_reader->readUInt32LE(); - $this->_minimumDataPacketSize = $this->_reader->readUInt32LE(); - $this->_maximumDataPacketSize = $this->_reader->readUInt32LE(); - $this->_maximumBitrate = $this->_reader->readUInt32LE(); - } - - /** - * Returns the file id field. - * - * @return integer - */ - public function getFileId() { return $this->_fileId; } - - /** - * Sets the file id field. - * - * @param GUID $fileId The new file id. - */ - public function setFileId($fileId) { $this->_fileId = $fileId; } - - /** - * Returns the size, in bytes, of the entire file. The value of this field is - * invalid if the broadcast flag bit in the flags field is set to 1. - * - * @return integer - */ - public function getFileSize() { return $this->_fileSize; } - - /** - * Sets the size, in bytes, of the entire file. The value of this field is - * invalid if the broadcast flag bit in the flags field is set to 1. - * - * @param integer $fileSize The size of the entire file. - */ - public function setFileSize($fileSize) { $this->_fileSize = $fileSize; } - - /** - * Returns the date and time of the initial creation of the file. The value is - * given as the number of 100-nanosecond intervals since January 1, 1601, - * according to Coordinated Universal Time (Greenwich Mean Time). The value of - * this field may be invalid if the broadcast flag bit in the flags field is - * set to 1. - * - * @return integer - */ - public function getCreationDate() { return $this->_creationDate; } - - /** - * Sets the date and time of the initial creation of the file. The value is - * given as the number of 100-nanosecond intervals since January 1, 1601, - * according to Coordinated Universal Time (Greenwich Mean Time). The value of - * this field may be invalid if the broadcast flag bit in the flags field is - * set to 1. - * - * @param integer $creationDate The date and time of the initial creation of - * the file. - */ - public function setCreationDate($creationDate) - { - $this->_creationDate = $creationDate; - } - - /** - * Returns the number of Data Packet entries that exist within the - * {@link ASF_Object_Data Data Object}. The value of this field is invalid if - * the broadcast flag bit in the flags field is set to 1. - * - * @return integer - */ - public function getDataPacketsCount() { return $this->_dataPacketsCount; } - - /** - * Sets the number of Data Packet entries that exist within the - * {@link ASF_Object_Data Data Object}. The value of this field is invalid if - * the broadcast flag bit in the flags field is set to 1. - * - * @param integer $dataPacketsCount The number of Data Packet entries. - */ - public function setDataPacketsCount($dataPacketsCount) - { - $this->_dataPacketsCount = $dataPacketsCount; - } - - /** - * Returns the time needed to play the file in 100-nanosecond units. This - * value should include the duration (estimated, if an exact value is - * unavailable) of the the last media object in the presentation. The value of - * this field is invalid if the broadcast flag bit in the flags field is set - * to 1. - * - * @return integer - */ - public function getPlayDuration() { return $this->_playDuration; } - - /** - * Sets the time needed to play the file in 100-nanosecond units. This - * value should include the duration (estimated, if an exact value is - * unavailable) of the the last media object in the presentation. The value of - * this field is invalid if the broadcast flag bit in the flags field is set - * to 1. - * - * @param integer $playDuration The time needed to play the file. - */ - public function setPlayDuration($playDuration) - { - $this->_playDuration = $playDuration; - } - - /** - * Returns the time needed to send the file in 100-nanosecond units. This - * value should include the duration of the last packet in the content. The - * value of this field is invalid if the broadcast flag bit in the flags field - * is set to 1. - * - * @return integer - */ - public function getSendDuration() { return $this->_sendDuration; } - - /** - * Sets the time needed to send the file in 100-nanosecond units. This - * value should include the duration of the last packet in the content. The - * value of this field is invalid if the broadcast flag bit in the flags field - * is set to 1. - * - * @param integer $sendDuration The time needed to send the file. - */ - public function setSendDuration($sendDuration) - { - $this->_sendDuration = $sendDuration; - } - - /** - * Returns the amount of time to buffer data before starting to play the file, - * in millisecond units. If this value is nonzero, the Play Duration - * field and all of the payload Presentation Time fields have been - * offset by this amount. Therefore, player software must subtract the value - * in the preroll field from the play duration and presentation times to - * calculate their actual values. - * - * @return integer - */ - public function getPreroll() { return $this->_preroll; } - - /** - * Sets the amount of time to buffer data before starting to play the file, - * in millisecond units. If this value is nonzero, the Play Duration - * field and all of the payload Presentation Time fields have been - * offset by this amount. Therefore, player software must subtract the value - * in the preroll field from the play duration and presentation times to - * calculate their actual values. - * - * @param integer $preroll The amount of time to buffer data. - */ - public function setPreroll($preroll) { $this->_preroll = $preroll; } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } - - /** - * Returns the flags field. - * - * @return integer - */ - public function getFlags() { return $this->_flags; } - - /** - * Sets the flags field. - * - * @param integer $flags The flags field. - */ - public function setFlags($flags) { $this->_flags = $flags; } - - /** - * Returns the minimum Data Packet size in bytes. In general, the value - * of this field is invalid if the broadcast flag bit in the flags field is - * set to 1. However, the values for the Minimum Data Packet Size and - * Maximum Data Packet Size fields shall be set to the same value, and - * this value should be set to the packet size, even when the broadcast flag - * in the flags field is set to 1. - * - * @return integer - */ - public function getMinimumDataPacketSize() - { - return $this->_minimumDataPacketSize; - } - - /** - * Sets the minimum Data Packet size in bytes. In general, the value - * of this field is invalid if the broadcast flag bit in the flags field is - * set to 1. However, the values for the Minimum Data Packet Size and - * Maximum Data Packet Size fields shall be set to the same value, and - * this value should be set to the packet size, even when the broadcast flag - * in the flags field is set to 1. - * - * @param integer $minimumDataPacketSize The minimum Data Packet size - * in bytes. - */ - public function setMinimumDataPacketSize($minimumDataPacketSize) - { - $this->_minimumDataPacketSize = $minimumDataPacketSize; - } - - /** - * Returns the maximum Data Packet size in bytes. In general, the value - * of this field is invalid if the broadcast flag bit in the flags field is - * set to 1. However, the values for the Minimum Data Packet Size and - * Maximum Data Packet Size fields shall be set to the same value, and - * this value should be set to the packet size, even when the broadcast flag - * in the flags field is set to 1. - * - * @return integer - */ - public function getMaximumDataPacketSize() - { - return $this->_maximumDataPacketSize; - } - - /** - * Sets the maximum Data Packet size in bytes. In general, the value - * of this field is invalid if the broadcast flag bit in the flags field is - * set to 1. However, the values for the Minimum Data Packet Size and - * Maximum Data Packet Size fields shall be set to the same value, and - * this value should be set to the packet size, even when the broadcast flag - * in the flags field is set to 1. - * - * @param integer $maximumDataPacketSize The maximum Data Packet size - * in bytes - */ - public function setMaximumDataPacketSize($maximumDataPacketSize) - { - $this->_maximumDataPacketSize = $maximumDataPacketSize; - } - - /** - * Returns the maximum instantaneous bit rate in bits per second for the - * entire file. This is equal the sum of the bit rates of the individual - * digital media streams. - * - * @return integer - */ - public function getMaximumBitrate() { return $this->_maximumBitrate; } - - /** - * Sets the maximum instantaneous bit rate in bits per second for the - * entire file. This is equal the sum of the bit rates of the individual - * digital media streams. - * - * @param integer $maximumBitrate The maximum instantaneous bit rate in bits - * per second. - */ - public function setMaximumBitrate($maximumBitrate) - { - $this->_maximumBitrate = $maximumBitrate; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_fileId) . - Transform::toInt64LE($this->_fileSize) . - Transform::toInt64LE($this->_creationDate) . - Transform::toInt64LE($this->_dataPacketsCount) . - Transform::toInt64LE($this->_playDuration) . - Transform::toInt64LE($this->_sendDuration) . - Transform::toInt64LE($this->_preroll) . - Transform::toUInt32LE($this->_flags) . - Transform::toUInt32LE($this->_minimumDataPacketSize) . - Transform::toUInt32LE($this->_maximumDataPacketSize) . - Transform::toUInt32LE($this->_maximumBitrate); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/GroupMutualExclusion.php b/src/ASF/Object/GroupMutualExclusion.php deleted file mode 100644 index 7e8f1dc..0000000 --- a/src/ASF/Object/GroupMutualExclusion.php +++ /dev/null @@ -1,171 +0,0 @@ -Group Mutual Exclusion Object is used to describe mutual exclusion - * relationships between groups of streams. This object is organized in terms of - * records, each containing one or more streams, where a stream in record N - * cannot coexist with a stream in record M for N != M (however, streams in the - * same record can coexist). This mutual exclusion object would be used - * typically for the purpose of language mutual exclusion, and a record would - * consist of all streams for a particular language. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_GroupMutualExclusion extends ASF_Object -{ - const MUTEX_LANGUAGE = "d6e22a00-35da-11d1-9034-00a0c90349be"; - const MUTEX_BITRATE = "d6e22a01-35da-11d1-9034-00a0c90349be"; - const MUTEX_UNKNOWN = "d6e22a02-35da-11d1-9034-00a0c90349be"; - - /** @var string */ - private $_exclusionType; - - /** @var Array */ - private $_records = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_exclusionType = $this->_reader->readGUID(); - $recordCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $recordCount; $i++) { - $streamNumbersCount = $this->_reader->readUInt16LE(); - $streamNumbers = array(); - for ($j = 0; $j < $streamNumbersCount; $j++) - $streamNumbers[] = array - ("streamNumbers" => $this->_reader->readUInt16LE()); - $this->_records[] = $streamNumbers; - } - } - - /** - * Returns the nature of the mutual exclusion relationship. - * - * @return string - */ - public function getExclusionType() { return $this->_exclusionType; } - - /** - * Sets the nature of the mutual exclusion relationship. - * - * @param string $exclusionType The exclusion type. - */ - public function setExclusionType($exclusionType) - { - $this->_exclusionType = $exclusionType; - } - - /** - * Returns an array of records. Each record consists of the following keys. - * - * o streamNumbers -- Specifies the stream numbers for this record. Valid - * values are between 1 and 127. - * - * @return Array - */ - public function getRecords() { return $this->_records; } - - /** - * Sets an array of records. Each record is to consist of the following keys. - * - * o streamNumbers -- Specifies the stream numbers for this record. Valid - * values are between 1 and 127. - * - * @param Array $records The array of records - */ - public function setRecords($records) { $this->_records = $records; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_exclusionType) . - Transform::toUInt16LE($recordCount = count($this->_records)); - for ($i = 0; $i < $recordCount; $i++) { - $data .= - Transform::toUInt16LE($streamNumbersCount = count($this->_records[$i])); - for ($j = 0; $j < $streamNumbersCount; $j++) - $data .= Transform::toUInt16LE($this->_records[$i][$j]["streamNumbers"]); - } - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Header.php b/src/ASF/Object/Header.php deleted file mode 100644 index 9f92fdc..0000000 --- a/src/ASF/Object/Header.php +++ /dev/null @@ -1,153 +0,0 @@ - - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Header extends ASF_Object_Container -{ - /** @var integer */ - private $_reserved1; - - /** @var integer */ - private $_reserved2; - - /** - * Constructs the class with given parameters and options. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_reader->skip(4); - $this->_reserved1 = $this->_reader->readInt8(); - $this->_reserved2 = $this->_reader->readInt8(); - $this->constructObjects - (array - (self::FILE_PROPERTIES => "FileProperties", - self::STREAM_PROPERTIES => "StreamProperties", - self::HEADER_EXTENSION => "HeaderExtension", - self::CODEC_LIST => "CodecList", - self::SCRIPT_COMMAND => "ScriptCommand", - self::MARKER => "Marker", - self::BITRATE_MUTUAL_EXCLUSION => "BitrateMutualExclusion", - self::ERROR_CORRECTION => "ErrorCorrection", - self::CONTENT_DESCRIPTION => "ContentDescription", - self::EXTENDED_CONTENT_DESCRIPTION => "ExtendedContentDescription", - self::CONTENT_BRANDING => "ContentBranding", - self::STREAM_BITRATE_PROPERTIES => "StreamBitrateProperties", - self::CONTENT_ENCRYPTION => "ContentEncryption", - self::EXTENDED_CONTENT_ENCRYPTION => "ExtendedContentEncryption", - self::DIGITAL_SIGNATURE => "DigitalSignature", - self::PADDING => "Padding")); - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = ""; - foreach ($this->getObjects() as $objects) - foreach ($objects as $object) - $data .= $object->__toString(); - $this->setSize - (24 /* for header */ + 6 + strlen($data) /* for object data */); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . - Transform::toUInt32LE(count($this->getObjects())) . - Transform::toInt8($this->_reserved1) . - Transform::toInt8($this->_reserved2) . $data; - } -} diff --git a/src/ASF/Object/HeaderExtension.php b/src/ASF/Object/HeaderExtension.php deleted file mode 100644 index dbbb569..0000000 --- a/src/ASF/Object/HeaderExtension.php +++ /dev/null @@ -1,132 +0,0 @@ -Header Extension Object allows additional functionality to be - * added to an ASF file while maintaining backward compatibility. The Header - * Extension Object is a container containing zero or more additional extended - * header objects. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_HeaderExtension extends ASF_Object_Container -{ - /** @var string */ - private $_reserved1; - - /** @var integer */ - private $_reserved2; - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_reserved1 = $this->_reader->readGUID(); - $this->_reserved2 = $this->_reader->readUInt16LE(); - $this->_reader->skip(4); - $this->constructObjects - (array - (self::EXTENDED_STREAM_PROPERTIES => "ExtendedStreamProperties", - self::ADVANCED_MUTUAL_EXCLUSION => "AdvancedMutualExclusion", - self::GROUP_MUTUAL_EXCLUSION => "GroupMutualExclusion", - self::STREAM_PRIORITIZATION => "StreamPrioritization", - self::BANDWIDTH_SHARING => "BandwidthSharing", - self::LANGUAGE_LIST => "LanguageList", - self::METADATA => "Metadata", - self::METADATA_LIBRARY => "MetadataLibrary", - self::INDEX_PARAMETERS => "IndexParameters", - self::MEDIA_OBJECT_INDEX_PARAMETERS => "MediaObjectIndexParameters", - self::TIMECODE_INDEX_PARAMETERS => "TimecodeIndexParameters", - self::COMPATIBILITY => "Compatibility", - self::ADVANCED_CONTENT_ENCRYPTION => "AdvancedContentEncryption", - self::PADDING => "Padding")); - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = ""; - foreach ($this->getObjects() as $objects) - foreach ($objects as $object) - $data .= $object->__toString(); - $this->setSize - (24 /* for header */ + 22 + strlen($data) /* for object data */); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . - Transform::toGUID($this->_reserved1) . - Transform::toUInt16LE($this->_reserved2) . - Transform::toUInt32LE(strlen($data)) . $data; - } -} diff --git a/src/ASF/Object/Index.php b/src/ASF/Object/Index.php deleted file mode 100644 index 7c445b8..0000000 --- a/src/ASF/Object/Index.php +++ /dev/null @@ -1,185 +0,0 @@ -Index Object are in terms of presentation times. The - * corresponding Offset field values of the Index Entry byte - * offsets that, when combined with the Block Position value of the - * Index Block, indicate the starting location in bytes of an ASF Data - * Packet relative to the start of the first ASF Data Packet in the file. - * - * An offset value of 0xFFFFFFFF is used to indicate an invalid offset value. - * Invalid offsets signify that this particular index entry does not identify a - * valid indexible point. Invalid offsets may occur for the initial index - * entries of a digital media stream whose first ASF Data Packet has a non-zero - * send time. Invalid offsets may also occur in the case where a digital media - * stream has a large gap in the presentation time of successive objects. - * - * The Index Object is not recommended for use with files where the - * Send Time of the first Data Packet within the Data - * Object has a Send Time value significantly greater than zero - * (otherwise the index itself will be sparse and inefficient). - * - * Any ASF file containing an Index Object does also contain an Index - * Parameters Object in its {@link ASF_Object_Header ASF Header}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Index extends ASF_Object -{ - /** - * Indicates that the index type is Nearest Past Data Packet. The Nearest - * Past Data Packet indexes point to the data packet whose presentation time - * is closest to the index entry time. - */ - const NEAREST_PAST_DATA_PACKET = 1; - - /** - * Indicates that the index type is Nearest Past Media. The Nearest Past - * Object indexes point to the closest data packet containing an entire object - * or first fragment of an object. - */ - const NEAREST_PAST_MEDIA = 2; - - /** - * Indicates that the index type is Nearest Past Cleanpoint. The Nearest Past - * Cleanpoint indexes point to the closest data packet containing an entire - * object (or first fragment of an object) that has the Cleanpoint Flag set. - * - * Nearest Past Cleanpoint is the most common type of index. - */ - const NEAREST_PAST_CLEANPOINT = 3; - - /** @var integer */ - private $_indexEntryTimeInterval; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** @var Array */ - private $_indexBlocks = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_indexEntryTimeInterval = $this->_reader->readUInt32LE(); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - $indexBlocksCount = $this->_reader->readUInt32LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - for ($i = 0; $i < $indexBlocksCount; $i++) { - $indexEntryCount = $this->_reader->readUInt32LE(); - $blockPositions = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $blockPositions[] = $this->_reader->readInt64LE(); - $offsets = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $offsets[] = $this->_reader->readUInt32LE(); - $this->_indexBlocks[] = array - ("blockPositions" => $blockPositions, - "indexEntryOffsets" => $offsets); - } - } - - /** - * Returns the time interval between each index entry in ms. - * - * @return integer - */ - public function getIndexEntryTimeInterval() - { - return $this->_indexEntryTimeInterval; - } - - /** - * Returns an array of index specifiers. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index - * Specifiers refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o blockPositions -- Specifies a list of byte offsets of the beginnings of - * the blocks relative to the beginning of the first Data Packet (for - * example, the beginning of the Data Object + 50 bytes). - * - * o indexEntryOffsets -- Specifies the offset. An offset value of - * 0xffffffff indicates an invalid offset value. - * - * @return Array - */ - public function getIndexBlocks() { return $this->_indexBlocks; } -} diff --git a/src/ASF/Object/IndexParameters.php b/src/ASF/Object/IndexParameters.php deleted file mode 100644 index 7a021bb..0000000 --- a/src/ASF/Object/IndexParameters.php +++ /dev/null @@ -1,121 +0,0 @@ -Index Parameters Object supplies information about those streams - * that are actually indexed (there must be at least one stream in an index) by - * the {@link ASF_Object_Index Index Object} and how they are being indexed. - * This object shall be present in the {@link ASF_Object_Header Header Object} - * if there is an {@link ASF_Object_Index Index Object} present in the file. - * - * An Index Specifier is required for each stream that will be indexed by the - * {@link ASF_Object_Index Index Object}. These specifiers must exactly match - * those in the {@link ASF_Object_Index Index Object}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_IndexParameters extends ASF_Object -{ - /** @var string */ - private $_indexEntryTimeInterval; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_indexEntryTimeInterval = $this->_reader->readUInt32LE(); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) { - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - } - } - - /** - * Returns the time interval between index entries in milliseconds. This value - * cannot be 0. - * - * @return integer - */ - public function getIndexEntryTimeInterval() - { - return $this->_indexEntryTimeInterval; - } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index Specifiers - * refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. Values are as follows: - * 1 = Nearest Past Data Packet, - * 2 = Nearest Past Media Object, and - * 3 = Nearest Past Cleanpoint. - * The Nearest Past Data Packet indexes point to the data packet whose - * presentation time is closest to the index entry time. The Nearest Past - * Object indexes point to the closest data packet containing an entire - * object or first fragment of an object. The Nearest Past Cleanpoint - * indexes point to the closest data packet containing an entire object - * (or first fragment of an object) that has the Cleanpoint Flag set. - * Nearest Past Cleanpoint is the most common type of index. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } -} diff --git a/src/ASF/Object/LanguageList.php b/src/ASF/Object/LanguageList.php deleted file mode 100644 index 7e355b4..0000000 --- a/src/ASF/Object/LanguageList.php +++ /dev/null @@ -1,132 +0,0 @@ -Language List Object contains an array of Unicode-based language - * IDs. All other header objects refer to languages through zero-based positions - * in this array. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_LanguageList extends ASF_Object -{ - /** @var Array */ - private $_languages = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $languageIdRecordsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $languageIdRecordsCount; $i++) { - $languageIdLength = $this->_reader->readInt8(); - $languageId = $this->_reader->readString16($languageIdLength); - $this->_languages[] = iconv - ("utf-16le", $this->getOption("encoding"), $languageId); - } - } - - /** - * Returns the array of language ids. - * - * @return Array - */ - public function getLanguages() { return $this->_languages; } - - /** - * Sets the array of language ids. - * - * @param Array $languages The array of language ids. - */ - public function setLanguages($languages) { $this->_languages = $languages; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE - ($languageIdRecordsCount = count($this->_languages)); - for ($i = 0; $i < $languageIdRecordsCount; $i++) - $data .= - Transform::toInt8(strlen($languageId = iconv - ($this->getOption("encoding"), "utf-16le", $this->_languages[$i]) . - "\0\0")) . Transform::toString16($languageId); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Marker.php b/src/ASF/Object/Marker.php deleted file mode 100644 index 8bbe301..0000000 --- a/src/ASF/Object/Marker.php +++ /dev/null @@ -1,207 +0,0 @@ -Marker Object class. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Marker extends ASF_Object -{ - - /** @var string */ - private $_reserved1; - - /** @var integer */ - private $_reserved2; - - /** @var string */ - private $_name; - - /** @var Array */ - private $_markers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_reserved1 = $this->_reader->readGUID(); - $markersCount = $this->_reader->readUInt32LE(); - $this->_reserved2 = $this->_reader->readUInt16LE(); - $nameLength = $this->_reader->readUInt16LE(); - $this->_name = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($nameLength)); - for ($i = 0; $i < $markersCount; $i++) { - $marker = array - ("offset" => $this->_reader->readInt64LE(), - "presentationTime" => $this->_reader->readInt64LE()); - $this->_reader->skip(2); - $marker["sendTime"] = $this->_reader->readUInt32LE(); - $marker["flags"] = $this->_reader->readUInt32LE(); - $descriptionLength = $this->_reader->readUInt32LE(); - $marker["description"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($descriptionLength)); - $this->_markers[] = $marker; - } - } - - /** - * Returns the name of the Marker Object. - * - * @return Array - */ - public function getName() { return $this->_name; } - - /** - * Returns the name of the Marker Object. - * - * @param string $name The name. - */ - public function setName($name) { $this->_name = $name; } - - /** - * Returns an array of markers. Each entry consists of the following keys. - * - * o offset -- Specifies a byte offset into the Data Object to the - * actual position of the marker in the Data Object. ASF parsers - * must seek to this position to properly display data at the specified - * marker Presentation Time. - * - * o presentationTime -- Specifies the presentation time of the marker, in - * 100-nanosecond units. - * - * o sendTime -- Specifies the send time of the marker entry, in - * milliseconds. - * - * o flags -- Flags are reserved and should be set to 0. - * - * o description -- Specifies a description of the marker entry. - * - * @return Array - */ - public function getMarkers() { return $this->_markers; } - - /** - * Sets the array of markers. Each entry is to consist of the following keys. - * - * o offset -- Specifies a byte offset into the Data Object to the - * actual position of the marker in the Data Object. ASF parsers - * must seek to this position to properly display data at the specified - * marker Presentation Time. - * - * o presentationTime -- Specifies the presentation time of the marker, in - * 100-nanosecond units. - * - * o sendTime -- Specifies the send time of the marker entry, in - * milliseconds. - * - * o flags -- Flags are reserved and should be set to 0. - * - * o description -- Specifies a description of the marker entry. - * - * @param Array $markers The array of markers. - */ - public function setMarkers($markers) { $this->_markers = $markers; } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_reserved1) . - Transform::toUInt32LE($markersCount = count($this->_markers)) . - Transform::toUInt16LE($this->_reserved2) . - Transform::toUInt16LE - (strlen($name = iconv - ($this->getOption("encoding"), "utf-16le", $this->_name) . "\0\0")) . - Transform::toString16($name); - for ($i = 0; $i < $markersCount; $i++) - $data .= - Transform::toInt64LE($this->_markers[$i]["offset"]) . - Transform::toInt64LE($this->_markers[$i]["presentationTime"]) . - Transform::toUInt16LE - (12 + ($descriptionLength = strlen($description = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_markers[$i]["description"]) . "\0\0"))) . - Transform::toUInt32LE($this->_markers[$i]["sendTime"]) . - Transform::toUInt32LE($this->_markers[$i]["flags"]) . - Transform::toUInt32LE($descriptionLength) . - Transform::toString16($description); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/MediaObjectIndex.php b/src/ASF/Object/MediaObjectIndex.php deleted file mode 100644 index 4111982..0000000 --- a/src/ASF/Object/MediaObjectIndex.php +++ /dev/null @@ -1,176 +0,0 @@ -Media Object Index Object are in terms of media - * object numbers, with the first frame for a given stream in the ASF file - * corresponding to entry 0 in the Media Object Index Object. The - * corresponding Offset field values of the Index Entry are byte - * offsets that, when combined with the Block Position value of the - * Index Block, indicate the starting location in bytes of an ASF Data Packet - * relative to the start of the first ASF Data Packet in the file. - * - * Any ASF file containing a Media Object Index Object shall also contain - * a Media Object Index Parameters Object in its - * {@link ASF_Object_Header ASF Header}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_MediaObjectIndex extends ASF_Object -{ - /** - * Indicates that the index type is Nearest Past Data Packet. The Nearest - * Past Data Packet indexes point to the data packet whose presentation time - * is closest to the index entry time. - */ - const NEAREST_PAST_DATA_PACKET = 1; - - /** - * Indicates that the index type is Nearest Past Media. The Nearest Past - * Object indexes point to the closest data packet containing an entire object - * or first fragment of an object. - */ - const NEAREST_PAST_MEDIA = 2; - - /** - * Indicates that the index type is Nearest Past Cleanpoint. The Nearest Past - * Cleanpoint indexes point to the closest data packet containing an entire - * object (or first fragment of an object) that has the Cleanpoint Flag set. - * - * Nearest Past Cleanpoint is the most common type of index. - */ - const NEAREST_PAST_CLEANPOINT = 3; - - /** @var integer */ - private $_indexEntryCountInterval; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** @var Array */ - private $_indexBlocks = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - $indexBlocksCount = $this->_reader->readUInt32LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - for ($i = 0; $i < $indexBlocksCount; $i++) { - $indexEntryCount = $this->_reader->readUInt32LE(); - $blockPositions = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $blockPositions[] = $this->_reader->readInt64LE(); - $offsets = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $offsets[] = $this->_reader->readUInt32LE(); - $this->_indexBlocks[] = array - ("blockPositions" => $blockPositions, - "indexEntryOffsets" => $offsets); - } - } - - /** - * Returns the interval between each index entry in number of media objects. - * - * @return integer - */ - public function getIndexEntryCountInterval() - { - return $this->_indexEntryCountInterval; - } - - /** - * Returns an array of index specifiers. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index - * Specifiers refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o blockPositions -- Specifies a list of byte offsets of the beginnings of - * the blocks relative to the beginning of the first Data Packet (for - * example, the beginning of the Data Object + 50 bytes). - * - * o indexEntryOffsets -- Specifies the offset. An offset value of - * 0xffffffff indicates an invalid offset value. - * - * @return Array - */ - public function getIndexBlocks() { return $this->_indexBlocks; } -} diff --git a/src/ASF/Object/MediaObjectIndexParameters.php b/src/ASF/Object/MediaObjectIndexParameters.php deleted file mode 100644 index ccc0f92..0000000 --- a/src/ASF/Object/MediaObjectIndexParameters.php +++ /dev/null @@ -1,130 +0,0 @@ -Media Object Index Parameters Object supplies information about - * those streams that actually indexed (there must be at least one stream in an - * index) by media objects. This object shall be present in the - * {@link ASF_Object_Header Header Object} if there is a - * {@link ASF_Object_MediaObjectIndex Media Object Index Object} present in the - * file. - * - * An Index Specifier is required for each stream that will be indexed by the - * {@link ASF_Object_MediaObjectIndex Media Object Index Object}. These - * specifiers must exactly match those in the - * {@link ASF_Object_MediaObjectIndex Media Object Index Object}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_MediaObjectIndexParameters extends ASF_Object -{ - /** @var string */ - private $_indexEntryCountInterval; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) { - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - } - } - - /** - * Returns the interval between each index entry by the number of media - * objects. This value cannot be 0. - * - * @return integer - */ - public function getIndexEntryCountInterval() - { - return $this->_indexEntryCountInterval; - } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index Specifiers - * refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. Values are defined as - * follows: - * 1 = Nearest Past Data Packet, - * 2 = Nearest Past Media Object, - * 3 = Nearest Past Cleanpoint, - * 0xff = Frame Number Offset. - * For a video stream, the Nearest Past Media Object and Nearest Past Data - * Packet indexes point to the closest data packet containing an entire - * video frame or first fragment of a video frame; Nearest Past Cleanpoint - * indexes point to the closest data packet containing an entire video - * frame (or first fragment of a video frame) that is a key frame; and - * Frame Number Offset indicates how many more frames need to be read for - * the given stream, starting with the first frame in the packet pointed - * to by the index entry, in order to get to the requested frame. Nearest - * Past Media Object is the most common value. Because ASF payloads do not - * contain the full frame number, there is often a Frame Number Offset - * index alongside one of the other types of indexes to allow the user to - * identify the exact frame being seeked to. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } -} diff --git a/src/ASF/Object/Metadata.php b/src/ASF/Object/Metadata.php deleted file mode 100644 index 93286f4..0000000 --- a/src/ASF/Object/Metadata.php +++ /dev/null @@ -1,223 +0,0 @@ -Metadata Object permits authors to store stream-based metadata in - * a file. This object supports the same types of metadata information as the - * Extended Content Description Object except that it also allows a - * stream number to be specified. - * - * @todo Implement better handling of various types of attributes - * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Metadata extends ASF_Object -{ - /** @var Array */ - private $_descriptionRecords = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $descriptionRecordsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $descriptionRecordsCount; $i++) { - $this->_reader->skip(2); - $descriptionRecord = array("streamNumber" => $this->_reader->readUInt16LE()); - $nameLength = $this->_reader->readUInt16LE(); - $dataType = $this->_reader->readUInt16LE(); - $dataLength = $this->_reader->readUInt32LE(); - $descriptionRecord["name"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($nameLength)); - switch ($dataType) { - case 0: // Unicode string - $descriptionRecord["data"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($dataLength)); - break; - case 1: // BYTE array - $descriptionRecord["data"] = $this->_reader->read($dataLength); - break; - case 2: // BOOL - $descriptionRecord["data"] = $this->_reader->readUInt16LE() == 1; - break; - case 3: // DWORD - $descriptionRecord["data"] = $this->_reader->readUInt32LE(); - break; - case 4: // QWORD - $descriptionRecord["data"] = $this->_reader->readInt64LE(); - break; - case 5: // WORD - $descriptionRecord["data"] = $this->_reader->readUInt16LE(); - break; - } - $this->_descriptionRecords[] = $descriptionRecord; - } - } - - /** - * Returns the array of description records. Each record consists of the - * following keys. - * - * o streamNumber -- Specifies the stream number. Valid values are between - * 1 and 127. - * - * o name -- Specifies the name that uniquely identifies the attribute being - * described. Names are case-sensitive. - * - * o data -- Specifies the actual metadata being stored. - * - * @return Array - */ - public function getDescriptionRecords() { return $this->_descriptionRecords; } - - /** - * Sets the array of description records. Each record must consist of the - * following keys. - * - * o streamNumber -- Specifies the stream number. Valid values are between - * 1 and 127. - * - * o name -- Specifies the name that uniquely identifies the attribute being - * described. Names are case-sensitive. - * - * o data -- Specifies the actual metadata being stored. - * - * @param Array $descriptionRecords The array of description records. - */ - public function setDescriptionRecords($descriptionRecords) - { - $this->_descriptionRecords = $descriptionRecords; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE - ($descriptionRecordsCount = count($this->_descriptionRecords)); - for ($i = 0; $i < $descriptionRecordsCount; $i++) { - $data .= Transform::toUInt16LE(0) . - Transform::toUInt16LE($this->_descriptionRecords[$i]["streamNumber"]) . - Transform::toUInt16LE(strlen($name = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_descriptionRecords[$i]["name"]) . "\0\0")); - if (is_string($this->_descriptionRecords[$i]["data"])) { - /* There is no way to distinguish byte arrays from unicode strings and - * hence the need for a list of fields of type byte array */ - static $byteArray = array ( - "" - ); // TODO: Add to the list if you encounter one - - if (in_array($name, $byteArray)) - $data .= Transform::toUInt16LE(1) . Transform::toUInt32LE - (strlen($this->_descriptionRecords[$i]["data"])) . $name . - $this->_descriptionRecords[$i]["data"]; - else { - $value = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_descriptionRecords[$i]["data"]); - $value = ($value ? $value . "\0\0" : ""); - $data .= Transform::toUInt16LE(0) . - Transform::toUInt32LE(strlen($value)) . $name . - Transform::toString16($value); - } - } - else if (is_bool($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(2) . Transform::toUInt32LE(2) . $name . - Transform::toUInt16LE($this->_descriptionRecords[$i]["data"] ? 1 : 0); - } - else if (is_int($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(3) . Transform::toUInt32LE(4) . $name . - Transform::toUInt32LE($this->_descriptionRecords[$i]["data"]); - } - else if (is_float($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(4) . Transform::toUInt32LE(8) . $name . - Transform::toInt64LE($this->_descriptionRecords[$i]["data"]); - } - else { - // Invalid value and there is nothing to be done so cause a fatal error - require_once("ASF/Exception.php"); - throw new ASF_Exception("Invalid data type"); - } - } - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/MetadataLibrary.php b/src/ASF/Object/MetadataLibrary.php deleted file mode 100644 index 882fa0f..0000000 --- a/src/ASF/Object/MetadataLibrary.php +++ /dev/null @@ -1,256 +0,0 @@ -Metadata Library Object lets authors store stream-based, - * language-attributed, multiply defined, and large metadata attributes in a - * file. - * - * This object supports the same types of metadata as the - * {@link ASF_Object_Metadata Metadata Object}, as well as attributes - * with language IDs, attributes that are defined more than once, large - * attributes, and attributes with the GUID data type. - * - * @todo Implement better handling of various types of attributes - * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_MetadataLibrary extends ASF_Object -{ - /** @var Array */ - private $_descriptionRecords = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $descriptionRecordsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $descriptionRecordsCount; $i++) { - $descriptionRecord = array - ("languageIndex" => $this->_reader->readUInt16LE(), - "streamNumber" => $this->_reader->readUInt16LE()); - $nameLength = $this->_reader->readUInt16LE(); - $dataType = $this->_reader->readUInt16LE(); - $dataLength = $this->_reader->readUInt32LE(); - $descriptionRecord["name"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($nameLength)); - switch ($dataType) { - case 0: // Unicode string - $descriptionRecord["data"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($dataLength)); - break; - case 1: // BYTE array - $descriptionRecord["data"] = $this->_reader->read($dataLength); - break; - case 2: // BOOL - $descriptionRecord["data"] = $this->_reader->readUInt16LE() == 1; - break; - case 3: // DWORD - $descriptionRecord["data"] = $this->_reader->readUInt32LE(); - break; - case 4: // QWORD - $descriptionRecord["data"] = $this->_reader->readInt64LE(); - break; - case 5: // WORD - $descriptionRecord["data"] = $this->_reader->readUInt16LE(); - break; - case 6: // GUID - $descriptionRecord["data"] = $this->_reader->readGUID(); - break; - } - $this->_descriptionRecords[] = $descriptionRecord; - } - } - - /** - * Returns an array of description records. Each record consists of the - * following keys. - * - * o languageIndex -- Specifies the index into the - * {@link LanguageList Language List Object} that identifies the language - * of this attribute. If there is no Language List Object present, - * this field is zero. - * - * o streamNumber -- Specifies whether the entry applies to a specific - * digital media stream or whether it applies to the whole file. A value - * of 0 in this field indicates that it applies to the whole file; - * otherwise, the entry applies only to the indicated stream number. Valid - * values are between 1 and 127. - * - * o name -- Specifies the name that identifies the attribute being - * described. - * - * o data -- Specifies the actual metadata being stored. - * - * @return Array - */ - public function getDescriptionRecords() { return $this->_descriptionRecords; } - - /** - * Sets an array of description records. Each record must consist of the - * following keys. - * - * o languageIndex -- Specifies the index into the Language List - * Object that identifies the language of this attribute. If there is - * no Language List Object present, this field is zero. - * - * o streamNumber -- Specifies whether the entry applies to a specific - * digital media stream or whether it applies to the whole file. A value - * of 0 in this field indicates that it applies to the whole file; - * otherwise, the entry applies only to the indicated stream number. Valid - * values are between 1 and 127. - * - * o name -- Specifies the name that identifies the attribute being - * described. - * - * o data -- Specifies the actual metadata being stored. - * - * @return Array - */ - public function setDescriptionRecords($descriptionRecords) - { - $this->_descriptionRecords = $descriptionRecords; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE - ($descriptionRecordsCount = count($this->_descriptionRecords)); - for ($i = 0; $i < $descriptionRecordsCount; $i++) { - $data .= - Transform::toUInt16LE($this->_descriptionRecords[$i]["languageIndex"]) . - Transform::toUInt16LE($this->_descriptionRecords[$i]["streamNumber"]) . - Transform::toUInt16LE(strlen($name = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_descriptionRecords[$i]["name"]) . "\0\0")); - if (is_string($this->_descriptionRecords[$i]["data"])) { - $chunks = array(); - if (preg_match - ("/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/i", - $this->_descriptionRecords[$i]["data"])) - $data .= Transform::toUInt16LE(6) . Transform::toUInt32LE(16) . - $name . Transform::toGUID($this->_descriptionRecords[$i]["data"]); - else { - /* There is no way to distinguish byte arrays from unicode strings and - * hence the need for a list of fields of type byte array */ - static $byteArray = array ( - "W\0M\0/\0L\0y\0r\0i\0c\0s\0_\0S\0y\0n\0c\0h\0r\0o\0n\0i\0s\0e\0d\0\0\0", - "W\0M\0/\0P\0i\0c\0t\0u\0r\0e\0\0\0" - ); // TODO: Add to the list if you encounter one - - if (in_array($name, $byteArray)) - $data .= Transform::toUInt16LE(1) . Transform::toUInt32LE - (strlen($this->_descriptionRecords[$i]["data"])) . $name . - $this->_descriptionRecords[$i]["data"]; - else { - $value = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_descriptionRecords[$i]["data"]); - $value = ($value ? $value . "\0\0" : ""); - $data .= Transform::toUInt16LE(0) . - Transform::toUInt32LE(strlen($value)) . $name . - Transform::toString16($value); - } - } - } - else if (is_bool($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(2) . Transform::toUInt32LE(2) . $name . - Transform::toUInt16LE($this->_descriptionRecords[$i]["data"] ? 1 : 0); - } - else if (is_int($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(3) . Transform::toUInt32LE(4) . $name . - Transform::toUInt32LE($this->_descriptionRecords[$i]["data"]); - } - else if (is_float($this->_descriptionRecords[$i]["data"])) { - $data .= Transform::toUInt16LE(4) . Transform::toUInt32LE(8) . $name . - Transform::toInt64LE($this->_descriptionRecords[$i]["data"]); - } - else { - // Invalid value and there is nothing to be done so cause a fatal error - require_once("ASF/Exception.php"); - throw new ASF_Exception("Invalid data type"); - } - } - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/Padding.php b/src/ASF/Object/Padding.php deleted file mode 100644 index c068ac8..0000000 --- a/src/ASF/Object/Padding.php +++ /dev/null @@ -1,107 +0,0 @@ -Padding Object is a dummy object that is used to pad the size of - * the Header Object. This object enables the size of any object stored - * in the Header Object to grow or shrink without having to rewrite the - * entire Data Object and Index Object sections of the ASF file. - * For instance, if entries in the Content Description Object or - * Extended Content Description Object need to be removed or shortened, - * the size of the Padding Object can be increased to compensate for the - * reduction in size of the Content Description Object. The ASF file can - * then be updated by overwriting the previous Header Object with the - * edited Header Object of identical size, without having to move or - * rewrite the data contained in the Data Object. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Padding extends ASF_Object -{ - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - if ($this->getSize() == 0) - $this->setSize(24); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . - str_pad("", $this->getSize() - 24 /* header */, "\0"); - } -} diff --git a/src/ASF/Object/ScriptCommand.php b/src/ASF/Object/ScriptCommand.php deleted file mode 100644 index 91e7452..0000000 --- a/src/ASF/Object/ScriptCommand.php +++ /dev/null @@ -1,188 +0,0 @@ -Script Command Object provides a list of type/parameter pairs of - * strings that are synchronized to the ASF file's timeline. Types can include - * URL or FILENAME values. Other type values may also be freely defined and - * used. The semantics and treatment of this set of types are defined by the - * local implementations. The parameter value is specific to the type field. You - * can use this type/parameter pairing for many purposes, including sending URLs - * to be launched by a client into an HTML frame (in other words, the URL type) - * or launching another ASF file for the chained continuous play of audio or - * video presentations (in other words, the FILENAME type). This object is also - * used as a method to stream text, as well as to provide script commands that - * you can use to control elements within the client environment. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_ScriptCommand extends ASF_Object -{ - /** @var string */ - private $_reserved; - - /** @var Array */ - private $_commands = array(); - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_reserved = $this->_reader->readGUID(); - $commandsCount = $this->_reader->readUInt16LE(); - $commandTypesCount = $this->_reader->readUInt16LE(); - $commandTypes = array(); - for ($i = 0; $i < $commandTypesCount; $i++) { - $commandTypeNameLength = $this->_reader->readUInt16LE(); - $commandTypes[] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($commandTypeNameLength * 2)); - } - for ($i = 0; $i < $commandsCount; $i++) { - $command = array - ("presentationTime" => $this->_reader->readUInt32LE(), - "type" => $commandTypes[$this->_reader->readUInt16LE()]); - $commandNameLength = $this->_reader->readUInt16LE(); - $command["name"] = iconv - ("utf-16le", $this->getOption("encoding"), - $this->_reader->readString16($commandNameLength * 2)); - $this->_commands[] = $command; - } - } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o presentationTime -- Specifies the presentation time of the command, in - * milliseconds. - * - * o type -- Specifies the type of this command. - * - * o name -- Specifies the name of this command. - * - * @return Array - */ - public function getCommands() { return $this->_commands; } - - /** - * Sets the array of index entries. Each entry is to consist of the following - * keys. - * - * o presentationTime -- Specifies the presentation time of the command, in - * milliseconds. - * - * o type -- Specifies the type of this command. - * - * o name -- Specifies the name of this command. - * - * @param Array $commands The array of index entries. - */ - public function setCommands($commands) { $this->_commands = $commands; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $commandTypes = array(); - foreach ($this->_commands as $command) - if (!in_array($command["type"], $commandTypes)) - $commandTypes[] = $command["type"]; - $data = - Transform::toGUID($this->_reserved) . - Transform::toUInt16LE($commandsCount = count($this->_commands)) . - Transform::toUInt16LE($commandTypesCount = count($commandTypes)); - for ($i = 0; $i < $commandTypesCount; $i++) - $data .= - Transform::toUInt16LE - (strlen($commandType = iconv - ($this->getOption("encoding"), "utf-16le", - $commandTypes[$i])) / 2) . $commandType; - for ($i = 0; $i < $commandsCount; $i++) - $data .= - Transform::toUInt32LE($this->_commands[$i]["presentationTime"]) . - Transform::toUInt16LE - (array_search($this->_commands[$i]["type"], $commandTypes)) . - Transform::toUInt16LE - (strlen($command = iconv - ($this->getOption("encoding"), "utf-16le", - $this->_commands[$i]["name"])) / 2) . $command; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/SimpleIndex.php b/src/ASF/Object/SimpleIndex.php deleted file mode 100644 index 2118079..0000000 --- a/src/ASF/Object/SimpleIndex.php +++ /dev/null @@ -1,143 +0,0 @@ -Simple Index Object. Additionally, the instances of the Simple - * Index Object shall be ordered by stream number. - * - * Index entries in the Simple Index Object are in terms of - * Presentation Times. The corresponding Packet Number field - * values (of the Index Entry, see below) indicate the packet number of - * the ASF Data Packet with the closest past key frame. Note that for - * video streams that contain both key frames and non-key frames, the Packet - * Number field will always point to the closest past key frame. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_SimpleIndex extends ASF_Object -{ - /** @var string */ - private $_fileId; - - /** @var integer */ - private $_indexEntryTimeInterval; - - /** @var integer */ - private $_maximumPacketCount; - - /** @var Array */ - private $_indexEntries = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_fileId = $this->_reader->readGUID(); - $this->_indexEntryTimeInterval = $this->_reader->readInt64LE(); - $this->_maximumPacketCount = $this->_reader->readUInt32LE(); - $indexEntriesCount = $this->_reader->readUInt32LE(); - for ($i = 0; $i < $indexEntriesCount; $i++) { - $this->_indexEntries[] = array - ("packetNumber" => $this->_reader->readUInt32LE(), - "packetCount" => $this->_reader->readUInt16LE()); - } - } - - /** - * Returns the unique identifier for this ASF file. The value of this field - * should be changed every time the file is modified in any way. The value of - * this field may be set to 0 or set to be identical to the value of the - * File ID field of the Data Object and the Header - * Object. - * - * @return string - */ - public function getFileId() { return $this->_fileId; } - - /** - * Returns the time interval between each index entry in 100-nanosecond units. - * The most common value is 10000000, to indicate that the index entries are - * in 1-second intervals, though other values can be used as well. - * - * @return integer - */ - public function getIndexEntryTimeInterval() - { - return $this->_indexEntryTimeInterval; - } - - /** - * Returns the maximum Packet Count value of all Index Entries. - * - * @return integer - */ - public function getMaximumPacketCount() { return $this->_maximumPacketCount; } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o packetNumber -- Specifies the number of the Data Packet associated - * with this index entry. Note that for video streams that contain both - * key frames and non-key frames, this field will always point to the - * closest key frame prior to the time interval. - * - * o packetCount -- Specifies the number of Data Packets to send at - * this index entry. If a video key frame has been fragmented into two - * Data Packets, the value of this field will be equal to 2. - * - * @return Array - */ - public function getIndexEntries() { return $this->_indexEntries; } -} diff --git a/src/ASF/Object/StreamBitrateProperties.php b/src/ASF/Object/StreamBitrateProperties.php deleted file mode 100644 index e28a55d..0000000 --- a/src/ASF/Object/StreamBitrateProperties.php +++ /dev/null @@ -1,153 +0,0 @@ -Stream Bitrate Properties Object defines the average bit rate of - * each digital media stream. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_StreamBitrateProperties extends ASF_Object -{ - /** @var Array */ - private $_bitrateRecords = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $bitrateRecordsCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $bitrateRecordsCount; $i++) - $this->_bitrateRecords[] = array - ("streamNumber" => ($tmp = $this->_reader->readInt16LE()) & 0x1f, - "flags" => $tmp >> 5, - "averageBitrate" => $this->_reader->readUInt32LE()); - } - - /** - * Returns an array of bitrate records. Each record consists of the following - * keys. - * - * o streamNumber -- Specifies the number of this stream described by this - * record. 0 is an invalid stream. Valid values are between 1 and 127. - * - * o flags -- These bits are reserved and should be set to 0. - * - * o averageBitrate -- Specifies the average bit rate of the stream in bits - * per second. This value should include an estimate of ASF packet and - * payload overhead associated with this stream. - * - * @return Array - */ - public function getBitrateRecords() { return $this->_bitrateRecords; } - - /** - * Sets an array of bitrate records. Each record consists of the following - * keys. - * - * o streamNumber -- Specifies the number of this stream described by this - * record. 0 is an invalid stream. Valid values are between 1 and 127. - * - * o flags -- These bits are reserved and should be set to 0. - * - * o averageBitrate -- Specifies the average bit rate of the stream in bits - * per second. This value should include an estimate of ASF packet and - * payload overhead associated with this stream. - * - * @param Array $bitrateRecords The array of bitrate records. - */ - public function setBitrateRecords($bitrateRecords) - { - $this->_bitrateRecords = $bitrateRecords; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE - ($bitrateRecordsCount = count($this->_bitrateRecords)); - for ($i = 0; $i < $bitrateRecordsCount; $i++) - $data .= Transform::toUInt16LE - (($this->_bitrateRecords[$i]["flags"] << 5) | - ($this->_bitrateRecords[$i]["streamNumber"] & 0x1f)) . - Transform::toUInt32LE($this->_bitrateRecords[$i]["averageBitrate"]); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/StreamPrioritization.php b/src/ASF/Object/StreamPrioritization.php deleted file mode 100644 index 54c085d..0000000 --- a/src/ASF/Object/StreamPrioritization.php +++ /dev/null @@ -1,154 +0,0 @@ -Stream Prioritization Object indicates the author's intentions as - * to which streams should or should not be dropped in response to varying - * network congestion situations. There may be special cases where this - * preferential order may be ignored (for example, the user hits the "mute" - * button). Generally it is expected that implementations will try to honor the - * author's preference. - * - * The priority of each stream is indicated by how early in the list that - * stream's stream number is listed (in other words, the list is ordered in - * terms of decreasing priority). - * - * The Mandatory flag field shall be set if the author wants that stream kept - * "regardless". If this flag is not set, then that indicates that the stream - * should be dropped in response to network congestion situations. Non-mandatory - * streams must never be assigned a higher priority than mandatory streams. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_StreamPrioritization extends ASF_Object -{ - /** @var Array */ - private $_priorityRecords = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $priorityRecordCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $priorityRecordCount; $i++) - $this->_priorityRecords[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "flags" => $this->_reader->readUInt16LE()); - } - - /** - * Returns an array of records. Each record consists of the following keys. - * - * o streamNumber -- Specifies the stream number. Valid values are between - * 1 and 127. - * - * o flags -- Specifies the flags. The mandatory flag is the bit 1 (LSB). - * - * @return Array - */ - public function getPriorityRecords() { return $this->_priorityRecords; } - - /** - * Sets the array of records. Each record consists of the following keys. - * - * o streamNumber -- Specifies the stream number. Valid values are between - * 1 and 127. - * - * o flags -- Specifies the flags. The mandatory flag is the bit 1 (LSB). - * - * @param Array $priorityRecords The array of records. - */ - public function setPriorityRecords($priorityRecords) - { - $this->_priorityRecords = $priorityRecords; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = Transform::toUInt16LE - ($priorityRecordCount = count($this->_priorityRecords)); - for ($i = 0; $i < $priorityRecordCount; $i++) - $data .= - Transform::toUInt16LE($this->_priorityRecords[$i]["streamNumber"]) . - Transform::toUInt16LE($this->_priorityRecords[$i]["flags"]); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/StreamProperties.php b/src/ASF/Object/StreamProperties.php deleted file mode 100644 index 9dd4a3e..0000000 --- a/src/ASF/Object/StreamProperties.php +++ /dev/null @@ -1,516 +0,0 @@ -Stream Properties Object defines the specific properties and - * characteristics of a digital media stream. This object defines how a digital - * media stream within the Data Object is interpreted, as well as the - * specific format (of elements) of the Data Packet itself. - * - * Whereas every stream in an ASF presentation, including each stream in a - * mutual exclusion relationship, must be represented by a Stream Properties - * Object, in certain cases, this object might be found embedded in the - * Extended Stream Properties Object. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_StreamProperties extends ASF_Object -{ - /** - * Indicates, if set, that the data contained in this stream is encrypted and - * will be unreadable unless there is a way to decrypt the stream. - */ - const ENCRYPTED_CONTENT = 0x8000; - - const AUDIO_MEDIA = "f8699e40-5b4d-11cf-a8fd-00805f5c442b"; - const VIDEO_MEDIA = "bc19efc0-5b4d-11cf-a8fd-00805f5c442b"; - const COMMAND_MEDIA = "59dacfc0-59e6-11d0-a3ac-00a0c90348f6"; - const JFIF_MEDIA = "b61be100-5b4e-11cf-a8fD-00805f5c442b"; - const DEGRADABLE_JPEG_MEDIA = "35907dE0-e415-11cf-a917-00805f5c442b"; - const FILE_TRANSFER_MEDIA = "91bd222c-f21c-497a-8b6d-5aa86bfc0185"; - const BINARY_MEDIA = "3afb65e2-47ef-40f2-ac2c-70a90d71d343"; - - const NO_ERROR_CORRECTION = "20fb5700-5b55-11cf-a8fd-00805f5c442b"; - const AUDIO_SPREAD = "bfc3cd50-618f-11cf-8bb2-00aa00b4e220"; - - /** @var string */ - private $_streamType; - - /** @var string */ - private $_errorCorrectionType; - - /** @var integer */ - private $_timeOffset; - - /** @var integer */ - private $_flags; - - /** @var integer */ - private $_reserved; - - /** @var Array */ - private $_typeSpecificData = array(); - - /** @var Array */ - private $_errorCorrectionData = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_streamType = $this->_reader->readGUID(); - $this->_errorCorrectionType = $this->_reader->readGUID(); - $this->_timeOffset = $this->_reader->readInt64LE(); - $typeSpecificDataLength = $this->_reader->readUInt32LE(); - $errorCorrectionDataLength = $this->_reader->readUInt32LE(); - $this->_flags = $this->_reader->readUInt16LE(); - $this->_reserved = $this->_reader->readUInt32LE(); - - switch ($this->_streamType) { - case self::AUDIO_MEDIA: - $this->_typeSpecificData = array - ("codecId" => $this->_reader->readUInt16LE(), - "numberOfChannels" => $this->_reader->readUInt16LE(), - "samplesPerSecond" => $this->_reader->readUInt32LE(), - "avgNumBytesPerSecond" => $this->_reader->readUInt32LE(), - "blockAlignment" => $this->_reader->readUInt16LE(), - "bitsPerSample" => $this->_reader->readUInt16LE()); - $codecSpecificDataSize = $this->_reader->readUInt16LE(); - $this->_typeSpecificData["codecSpecificData"] = - $this->_reader->read($codecSpecificDataSize); - break; - case self::VIDEO_MEDIA: - $this->_typeSpecificData = array - ("encodedImageWidth" => $this->_reader->readUInt32LE(), - "encodedImageHeight" => $this->_reader->readUInt32LE(), - "reservedFlags" => $this->_reader->readInt8()); - $this->_reader->skip(2); - $formatDataSize = $this->_reader->readUInt32LE(); - $this->_typeSpecificData = array_merge - ($this->_typeSpecificData, array - ("imageWidth" => $this->_reader->readUInt32LE(), - "imageHeight" => $this->_reader->readUInt32LE(), - "reserved" => $this->_reader->readUInt16LE(), - "bitsPerPixelCount" => $this->_reader->readUInt16LE(), - "compressionId" => $this->_reader->readUInt32LE(), - "imageSize" => $this->_reader->readUInt32LE(), - "horizontalPixelsPerMeter" => $this->_reader->readUInt32LE(), - "verticalPixelsPerMeter" => $this->_reader->readUInt32LE(), - "colorsUsedCount" => $this->_reader->readUInt32LE(), - "importantColorsCount" => $this->_reader->readUInt32LE(), - "codecSpecificData" => $this->_reader->read($formatDataSize - 38))); - break; - case self::JFIF_MEDIA: - $this->_typeSpecificData = array - ("imageWidth" => $this->_reader->readUInt32LE(), - "imageHeight" => $this->_reader->readUInt32LE(), - "reserved" => $this->_reader->readUInt32LE()); - break; - case self::DEGRADABLE_JPEG_MEDIA: - $this->_typeSpecificData = array - ("imageWidth" => $this->_reader->readUInt32LE(), - "imageHeight" => $this->_reader->readUInt32LE(), - $this->_reader->readUInt16LE(), - $this->_reader->readUInt16LE(), - $this->_reader->readUInt16LE()); - $interchangeDataSize = $this->_reader->readUInt16LE(); - if ($interchangeDataSize == 0) - $interchangeDataSize++; - $this->_typeSpecificData["interchangeData"] = - $this->_reader->read($interchangeDataSize); - break; - case self::FILE_TRANSFER_MEDIA: - case self::BINARY_MEDIA: - $this->_typeSpecificData = array - ("majorMediaType" => $this->_reader->getGUID(), - "mediaSubtype" => $this->_reader->getGUID(), - "fixedSizeSamples" => $this->_reader->readUInt32LE(), - "temporalCompression" => $this->_reader->readUInt32LE(), - "sampleSize" => $this->_reader->readUInt32LE(), - "formatType" => $this->_reader->getGUID()); - $formatDataSize = $this->_reader->readUInt32LE(); - $this->_typeSpecificData["formatData"] = - $this->_reader->read($formatDataSize); - break; - case self::COMMAND_MEDIA: - default: - $this->_reader->skip($typeSpecificDataLength); - } - switch ($this->_errorCorrectionType) { - case self::AUDIO_SPREAD: - $this->_errorCorrectionData = array - ("span" => $this->_reader->readInt8(), - "virtualPacketLength" => $this->_reader->readUInt16LE(), - "virtualChunkLength" => $this->_reader->readUInt16LE()); - $silenceDataSize = $this->_reader->readUInt16LE(); - $this->_errorCorrectionData["silenceData"] = - $this->_reader->read($silenceDataSize); - break; - case self::NO_ERROR_CORRECTION: - default: - $this->_reader->skip($errorCorrectionDataLength); - } - } - - /** - * Returns the number of this stream. 0 is an invalid stream. Valid values are - * between 1 and 127. The numbers assigned to streams in an ASF presentation - * may be any combination of unique values; parsing logic must not assume that - * streams are numbered sequentially. - * - * @return integer - */ - public function getStreamNumber() { return $this->_flags & 0x3f; } - - /** - * Returns the number of this stream. 0 is an invalid stream. Valid values are - * between 1 and 127. The numbers assigned to streams in an ASF presentation - * may be any combination of unique values; parsing logic must not assume that - * streams are numbered sequentially. - * - * @param integer $streamNumber The number of this stream. - */ - public function setStreamNumber($streamNumber) - { - if ($streamNumber < 1 || $streamNumber > 127) { - require_once("ASF/Exception.php"); - throw new ASF_Exception("Invalid argument"); - } - $this->_flags = ($this->_flags & 0xffc0) | ($streamNumber & 0x3f); - } - - /** - * Returns the type of the stream (for example, audio, video, and so on). - * - * @return string - */ - public function getStreamType() { return $this->_streamType; } - - /** - * Sets the type of the stream (for example, audio, video, and so on). - * - * @param integer $streamType The type of the stream. - */ - public function setStreamType($streamType) - { - $this->_streamType = $streamType; - } - - /** - * Returns the error correction type used by this digital media stream. For - * streams other than audio, this value should be set to NO_ERROR_CORRECTION. - * For audio streams, this value should be set to AUDIO_SPREAD. - * - * @return string - */ - public function getErrorCorrectionType() - { - return $this->_errorCorrectionType; - } - - /** - * Sets the error correction type used by this digital media stream. For - * streams other than audio, this value should be set to NO_ERROR_CORRECTION. - * For audio streams, this value should be set to AUDIO_SPREAD. - * - * @param integer $errorCorrectionType The error correction type used by this - * digital media stream. - */ - public function setErrorCorrectionType($errorCorrectionType) - { - $this->_errorCorrectionType = $errorCorrectionType; - } - - /** - * Returns the presentation time offset of the stream in 100-nanosecond units. - * The value of this field is added to all of the timestamps of the samples in - * the stream. This value shall be equal to the send time of the first - * interleaved packet in the data section. The value of this field is - * typically 0. It is non-zero in the case when an ASF file is edited and it - * is not possible for the editor to change the presentation times and send - * times of ASF packets. Note that if more than one stream is present in an - * ASF file the offset values of all stream properties objects must be equal. - * - * @return integer - */ - public function getTimeOffset() { return $this->_timeOffset; } - - /** - * Sets the presentation time offset of the stream in 100-nanosecond units. - * The value of this field is added to all of the timestamps of the samples in - * the stream. This value shall be equal to the send time of the first - * interleaved packet in the data section. The value of this field is - * typically 0. It is non-zero in the case when an ASF file is edited and it - * is not possible for the editor to change the presentation times and send - * times of ASF packets. Note that if more than one stream is present in an - * ASF file the offset values of all stream properties objects must be equal. - * - * @param integer $timeOffset The presentation time offset of the stream. - */ - public function setTimeOffset($timeOffset) - { - $this->_timeOffset = $timeOffset; - } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } - - /** - * Returns the flags field. - * - * @return integer - */ - public function getFlags() { return $this->_flags; } - - /** - * Sets the flags field. - * - * @param integer $flags The flags field. - */ - public function setFlags($flags) { $this->_flags = $flags; } - - /** - * Returns type-specific format data. The structure for the Type-Specific - * Data field is determined by the value stored in the Stream Type - * field. - * - * The type-specific data is returned as key-value pairs of an associate - * array. - * - * @return Array - */ - public function getTypeSpecificData() { return $this->_typeSpecificData; } - - /** - * Sets type-specific format data. The structure for the Type-Specific - * Data field is determined by the value stored in the Stream Type - * field. - * - * @param Array $typeSpecificData The type-specific data as key-value pairs of - * an associate array. - */ - public function setTypeSpecificData($typeSpecificData) - { - $this->_typeSpecificData = $typeSpecificData; - } - - /** - * Returns data specific to the error correction type. The structure for the - * Error Correction Data field is determined by the value stored in the - * Error Correction Type field. For example, an audio data stream might - * need to know how codec chunks were redistributed, or it might need a sample - * of encoded silence. - * - * The error correction type-specific data is returned as key-value pairs of - * an associate array. - * - * @return integer - */ - public function getErrorCorrectionData() - { - return $this->_errorCorrectionData; - } - - /** - * Sets data specific to the error correction type. The structure for the - * Error Correction Data field is determined by the value stored in the - * Error Correction Type field. For example, an audio data stream might - * need to know how codec chunks were redistributed, or it might need a sample - * of encoded silence. - * - * @param Array $errorCorrectionData The error correction type-specific data - * as key-value pairs of an associate array. - */ - public function setErrorCorrectionData($errorCorrectionData) - { - $this->_errorCorrectionData = $errorCorrectionData; - } - - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return true; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return false; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $data = - Transform::toGUID($this->_streamType) . - Transform::toGUID($this->_errorCorrectionType) . - Transform::toInt64LE($this->_timeOffset); - - switch ($this->_streamType) { - case self::AUDIO_MEDIA: - $typeSpecificData = - Transform::toUInt16LE($this->_typeSpecificData["codecId"]) . - Transform::toUInt16LE($this->_typeSpecificData["numberOfChannels"]) . - Transform::toUInt32LE($this->_typeSpecificData["samplesPerSecond"]) . - Transform::toUInt32LE - ($this->_typeSpecificData["avgNumBytesPerSecond"]) . - Transform::toUInt16LE($this->_typeSpecificData["blockAlignment"]) . - Transform::toUInt16LE($this->_typeSpecificData["bitsPerSample"]) . - Transform::toUInt16LE - (strlen($this->_typeSpecificData["codecSpecificData"])) . - $this->_typeSpecificData["codecSpecificData"]; - break; - case self::VIDEO_MEDIA: - $typeSpecificData = - Transform::toUInt32LE($this->_typeSpecificData["encodedImageWidth"]) . - Transform::toUInt32LE($this->_typeSpecificData["encodedImageHeight"]) . - Transform::toInt8($this->_typeSpecificData["reservedFlags"]) . - Transform::toUInt16LE(0) . // Reserved - Transform::toUInt32LE - (38 + strlen($this->_typeSpecificData["codecSpecificData"])) . - Transform::toUInt32LE($this->_typeSpecificData["imageWidth"]) . - Transform::toUInt32LE($this->_typeSpecificData["imageHeight"]) . - Transform::toUInt16LE($this->_typeSpecificData["reserved"]) . - Transform::toUInt16LE($this->_typeSpecificData["bitsPerPixelCount"]) . - Transform::toUInt32LE($this->_typeSpecificData["compressionId"]) . - Transform::toUInt32LE($this->_typeSpecificData["imageSize"]) . - Transform::toUInt32LE - ($this->_typeSpecificData["horizontalPixelsPerMeter"]) . - Transform::toUInt32LE - ($this->_typeSpecificData["verticalPixelsPerMeter"]) . - Transform::toUInt32LE($this->_typeSpecificData["colorsUsedCount"]) . - Transform::toUInt32LE - ($this->_typeSpecificData["importantColorsCount"]) . - $this->_typeSpecificData["codecSpecificData"]; - break; - case self::JFIF_MEDIA: - $typeSpecificData = - Transform::toUInt32LE($this->_typeSpecificData["imageWidth"]) . - Transform::toUInt32LE($this->_typeSpecificData["imageHeight"]) . - Transform::toUInt32LE(0); - break; - case self::DEGRADABLE_JPEG_MEDIA: - $typeSpecificData = - Transform::toUInt32LE($this->_typeSpecificData["imageWidth"]) . - Transform::toUInt32LE($this->_typeSpecificData["imageHeight"]) . - Transform::toUInt16LE(0) . - Transform::toUInt16LE(0) . - Transform::toUInt16LE(0); - $interchangeDataSize = strlen - ($this->_typeSpecificData["interchangeData"]); - if ($interchangeDataSize == 1) - $interchangeDataSize = 0; - $typeSpecificData .= - Transform::toUInt16LE($interchangeDataSize) . - $this->_typeSpecificData["interchangeData"]; - break; - case self::FILE_TRANSFER_MEDIA: - case self::BINARY_MEDIA: - $typeSpecificData = - Transform::toGUID($this->_typeSpecificData["majorMediaType"]) . - Transform::toGUID($this->_typeSpecificData["mediaSubtype"]) . - Transform::toUInt32LE($this->_typeSpecificData["fixedSizeSamples"]) . - Transform::toUInt32LE($this->_typeSpecificData["temporalCompression"]) . - Transform::toUInt32LE($this->_typeSpecificData["sampleSize"]) . - Transform::toGUID($this->_typeSpecificData["formatType"]) . - Transform::toUInt32LE(strlen($this->_typeSpecificData["formatData"])) . - $this->_typeSpecificData["formatData"]; - break; - case self::COMMAND_MEDIA: - default: - $typeSpecificData = ""; - } - switch ($this->_errorCorrectionType) { - case self::AUDIO_SPREAD: - $errorCorrectionData = - Transform::toInt8($this->_errorCorrectionData["span"]) . - Transform::toUInt16LE - ($this->_errorCorrectionData["virtualPacketLength"]) . - Transform::toUInt16LE - ($this->_errorCorrectionData["virtualChunkLength"]) . - Transform::toUInt16LE - (strlen($this->_errorCorrectionData["silenceData"])) . - $this->_errorCorrectionData["silenceData"]; - break; - case self::NO_ERROR_CORRECTION: - default: - $errorCorrectionData = ""; - } - - $data .= - Transform::toUInt32LE(strlen($typeSpecificData)) . - Transform::toUInt32LE(strlen($errorCorrectionData)) . - Transform::toUInt16LE($this->_flags) . - Transform::toUInt32LE($this->_reserved) . - $typeSpecificData . $errorCorrectionData; - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ASF/Object/TimecodeIndex.php b/src/ASF/Object/TimecodeIndex.php deleted file mode 100644 index faae87c..0000000 --- a/src/ASF/Object/TimecodeIndex.php +++ /dev/null @@ -1,181 +0,0 @@ -Timecode Index Object - * is used, it is recommended that timecodes be stored as a Payload Extension - * System on the appropriate stream. It is also recommended that every - * timecode appearing in the ASF file have a corresponging index entry. - * - * The index is designed to be broken into blocks to facilitate storage that is - * more space-efficient by using 32-bit offsets relative to a 64-bit base. That - * is, each index block has a full 64-bit offset in the block header that is - * added to the 32-bit offsets found in each index entry. If a file is larger - * than 2^32 bytes, then multiple index blocks can be used to fully index the - * entire large file while still keeping index entry offsets at 32 bits. - * - * To locate an object with a particular timecode in an ASF file, one would - * typically look through the Timecode Index Object in blocks of the - * appropriate range and try to locate the nearest possible timecode. The - * corresponding Offset field values of the Index Entry are byte - * offsets that, when combined with the Block Position value of the Index - * Block, indicate the starting location in bytes of an ASF Data Packet relative - * to the start of the first ASF Data Packet in the file. - * - * Any ASF file containing a Timecode Index Object shall also contain a - * Timecode Index Parameters Object in its - * {@link ASF_Object_Header ASF Header}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_TimecodeIndex extends ASF_Object -{ - /** - * Indicates that the index type is Nearest Past Data Packet. The Nearest - * Past Data Packet indexes point to the data packet whose presentation time - * is closest to the index entry time. - */ - const NEAREST_PAST_DATA_PACKET = 1; - - /** - * Indicates that the index type is Nearest Past Media. The Nearest Past - * Object indexes point to the closest data packet containing an entire object - * or first fragment of an object. - */ - const NEAREST_PAST_MEDIA = 2; - - /** - * Indicates that the index type is Nearest Past Cleanpoint. The Nearest Past - * Cleanpoint indexes point to the closest data packet containing an entire - * object (or first fragment of an object) that has the Cleanpoint Flag set. - * - * Nearest Past Cleanpoint is the most common type of index. - */ - const NEAREST_PAST_CLEANPOINT = 3; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** @var Array */ - private $_indexBlocks = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_reader->skip(4); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - $indexBlocksCount = $this->_reader->readUInt32LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - for ($i = 0; $i < $indexBlocksCount; $i++) { - $indexEntryCount = $this->_reader->readUInt32LE(); - $timecodeRange = $this->_reader->readUInt16LE(); - $blockPositions = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $blockPositions[] = $this->_reader->readInt64LE(); - $indexEntries = array(); - for ($i = 0; $i < $indexEntryCount; $i++) { - $timecode = $this->_reader->readUInt32LE(); - $offsets = array(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) - $offsets[] = $this->_reader->readUInt32LE(); - $indexEntries[] = array - ("timecode" => $timecode, - "offsets" => $offsets); - } - $this->_indexBlocks[] = array - ("timecodeRange" => $timecodeRange, - "blockPositions" => $blockPositions, - "indexEntries" => $indexEntries); - } - } - - /** - * Returns an array of index specifiers. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index - * Specifiers refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o timecodeRange -- Specifies the timecode range for this block. - * Subsequent blocks must contain range numbers greater than or equal to - * this one. - * - * o blockPositions -- Specifies a list of byte offsets of the beginnings of - * the blocks relative to the beginning of the first Data Packet (for - * example, the beginning of the Data Object + 50 bytes). - * - * o indexEntries -- An array that consists of the following keys - * o timecode -- This is the 4-byte timecode for these entries. - * o offsets -- Specifies the offset. An offset value of 0xffffffff - * indicates an invalid offset value. - * - * @return Array - */ - public function getIndexBlocks() { return $this->_indexBlocks; } -} diff --git a/src/ASF/Object/TimecodeIndexParameters.php b/src/ASF/Object/TimecodeIndexParameters.php deleted file mode 100644 index ea68c7d..0000000 --- a/src/ASF/Object/TimecodeIndexParameters.php +++ /dev/null @@ -1,125 +0,0 @@ -Timecode Index Parameters Object supplies information about those - * streams that are actually indexed (there must be at least one stream in an - * index) by timecodes. All streams referred to in the - * {@link ASF_Object_TimecodeIndexParameters Timecode Index Parameters Object} - * must have timecode Payload Extension Systems associated with them in the - * {@link ASF_Object_ExtendedStreamProperties Extended Stream Properties - * Object}. This object shall be present in the {@link ASF_Object_Header Header - * Object} if there is a {@link ASF_Object_TimecodeIndex Timecode Index Object} - * present in the file. - * - * An Index Specifier is required for each stream that will be indexed by the - * {@link ASF_Object_TimecodeIndex Timecode Index Object}. These specifiers must - * exactly match those in the {@link ASF_Object_TimecodeIndex Timecode Index - * Object}. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_TimecodeIndexParameters extends ASF_Object -{ - /** @var string */ - private $_indexEntryCountInterval; - - /** @var Array */ - private $_indexSpecifiers = array(); - - /** - * Constructs the class with given parameters and reads object related data - * from the ASF file. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); - $indexSpecifiersCount = $this->_reader->readUInt16LE(); - for ($i = 0; $i < $indexSpecifiersCount; $i++) { - $this->_indexSpecifiers[] = array - ("streamNumber" => $this->_reader->readUInt16LE(), - "indexType" => $this->_reader->readUInt16LE()); - } - } - - /** - * Returns the interval between each index entry by the number of media - * objects. This value cannot be 0. - * - * @return integer - */ - public function getIndexEntryCountInterval() - { - return $this->_indexEntryCountInterval; - } - - /** - * Returns an array of index entries. Each entry consists of the following - * keys. - * - * o streamNumber -- Specifies the stream number that the Index Specifiers - * refer to. Valid values are between 1 and 127. - * - * o indexType -- Specifies the type of index. Values are defined as - * follows: - * 2 = Nearest Past Media Object, - * 3 = Nearest Past Cleanpoint (1 is not a valid value). - * For a video stream, The Nearest Past Media Object indexes point to the - * closest data packet containing an entire video frame or the first - * fragment of a video frame, and the Nearest Past Cleanpoint indexes - * point to the closest data packet containing an entire video frame (or - * first fragment of a video frame) that is a key frame. Nearest Past - * Media Object is the most common value. - * - * @return Array - */ - public function getIndexSpecifiers() { return $this->_indexSpecifiers; } -} diff --git a/src/ASF/Object/Unknown.php b/src/ASF/Object/Unknown.php deleted file mode 100644 index 73f726b..0000000 --- a/src/ASF/Object/Unknown.php +++ /dev/null @@ -1,87 +0,0 @@ -Unknown Object represents objects that are not known to the - * library. - * - * @package php-reader - * @subpackage ASF - * @author Sven Vollbehr - * @copyright Copyright (c) 2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ASF_Object_Unknown extends ASF_Object -{ - /** - * Returns the whether the object is required to be present, or whether - * minimum cardinality is 1. - * - * @return boolean - */ - public function isMandatory() { return false; } - - /** - * Returns whether multiple instances of this object can be present, or - * whether maximum cardinality is greater than 1. - * - * @return boolean - */ - public function isMultiple() { return true; } - - /** - * Returns the object data with headers. - * - * @return string - */ - public function __toString() - { - $offset = $this->_reader->getOffset(); - $this->_reader->setOffset($this->getOffset() + 24 /* for header */); - $data = $this->_reader->read($this->getSize() - 24 /* for header */); - $this->_reader->setOffset($offset); - $this->setSize(24 /* for header */ + strlen($data)); - return - Transform::toGUID($this->getIdentifier()) . - Transform::toInt64LE($this->getSize()) . $data; - } -} diff --git a/src/ID3/Encoding.php b/src/ID3/Encoding.php deleted file mode 100644 index 06fa1ae..0000000 --- a/src/ID3/Encoding.php +++ /dev/null @@ -1,79 +0,0 @@ -Encoding interface implies that the ID3v2 frame supports - * content encoding. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -interface ID3_Encoding -{ - /** The ISO-8859-1 encoding. */ - const ISO88591 = 0; - - /** The UTF-16 Unicode encoding with BOM. */ - const UTF16 = 1; - - /** The UTF-16LE Unicode encoding without BOM. */ - const UTF16LE = 4; - - /** The UTF-16BE Unicode encoding without BOM. */ - const UTF16BE = 2; - - /** The UTF-8 Unicode encoding. */ - const UTF8 = 3; - - /** - * Returns the text encoding. - * - * @return integer - */ - public function getEncoding(); - - /** - * Sets the text encoding. - * - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding); -} diff --git a/src/ID3/Exception.php b/src/ID3/Exception.php deleted file mode 100644 index 95d55d2..0000000 --- a/src/ID3/Exception.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class ID3_Exception extends Exception -{ -} diff --git a/src/ID3/ExtendedHeader.php b/src/ID3/ExtendedHeader.php deleted file mode 100644 index 35ca410..0000000 --- a/src/ID3/ExtendedHeader.php +++ /dev/null @@ -1,324 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_ExtendedHeader extends ID3_Object -{ - /** - * A flag to denote that the present tag is an update of a tag found earlier - * in the present file or stream. If frames defined as unique are found in - * the present tag, they are to override any corresponding ones found in the - * earlier tag. This flag has no corresponding data. - * - * @since ID3v2.4.0 - */ - const UPDATE = 64; - - /** - * @since ID3v2.4.0 A flag to denote that a CRC-32 data is included in the - * extended header. The CRC is calculated on all the data between the header - * and footer as indicated by the header's tag length field, minus the - * extended header. Note that this includes the padding (if there is any), but - * excludes the footer. The CRC-32 is stored as an 35 bit synchsafe integer, - * leaving the upper four bits always zeroed. - * - * @since ID3v2.3.0 The CRC is calculated before unsynchronisation on the data - * between the extended header and the padding, i.e. the frames and only the - * frames. - */ - const CRC32 = 32; - - /** - * A flag to denote whether or not the tag has restrictions applied on it. - * - * @since ID3v2.4.0 - */ - const RESTRICTED = 16; - - /** @var integer */ - private $_size; - - /** @var integer */ - private $_flags = 0; - - /** @var integer */ - private $_padding; - - /** @var integer */ - private $_crc; - - /** @var integer */ - private $_restrictions = 0; - - /** - * Constructs the class with given parameters and reads object related data - * from the ID3v2 tag. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $offset = $this->_reader->getOffset(); - $this->_size = $this->_reader->readUInt32BE(); - - /* ID3v2.3.0 ExtendedHeader */ - if ($this->getOption("version", 4) < 4) { - if ($this->_reader->readUInt16BE() == 0x8000) - $this->_flags = self::CRC32; - $this->_padding = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::CRC32)) - $this->_crc = Transform::readUInt32BE(); - } - - /* ID3v2.4.0 ExtendedHeader */ - else { - $this->_size = $this->_decodeSynchsafe32($this->_size); - $this->_reader->skip(1); - $this->_flags = $this->_reader->readInt8(); - if ($this->hasFlag(self::UPDATE)) - $this->_reader->skip(1); - if ($this->hasFlag(self::CRC32)) { - $this->_reader->skip(1); - $this->_crc = - Transform::fromInt8($this->_reader->read(1)) * (0xfffffff + 1) + - _decodeSynchsafe32(Transform::fromUInt32BE($this->_reader->read(4))); - } - if ($this->hasFlag(self::RESTRICTED)) { - $this->_reader->skip(1); - $this->_restrictions = $this->_reader->readInt8(1); - } - } - } - - /** - * Returns the extended header size in bytes. - * - * @return integer - */ - public function getSize() { return $this->_size; } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } - - /** - * Returns the flags byte. - * - * @return integer - */ - public function getFlags($flags) { return $this->_flags; } - - /** - * Sets the flags byte. - * - * @param integer $flags The flags byte. - */ - public function setFlags($flags) { $this->_flags = $flags; } - - /** - * Returns the CRC-32 data. - * - * @return integer - */ - public function getCrc() - { - if ($this->hasFlag(self::CRC32)) - return $this->_crc; - return false; - } - - /** - * Sets whether the CRC-32 should be generated upon tag write. - * - * @param boolean $useCrc Whether CRC-32 should be generated. - */ - public function useCrc($useCrc) - { - if ($useCrc) - $this->setFlags($this->getFlags() | self::CRC32); - else - $this->setFlags($this->getFlags() & ~self::CRC32); - } - - /** - * Sets the CRC-32. The CRC-32 value is calculated of all the frames in the - * tag and includes padding. - * - * @param integer $crc The 32-bit CRC value. - */ - public function setCrc($crc) - { - if (is_bool($crc)) - $this->useCrc($crc); - else - $this->_crc = $crc; - } - - /** - * Returns the restrictions. For some applications it might be desired to - * restrict a tag in more ways than imposed by the ID3v2 specification. Note - * that the presence of these restrictions does not affect how the tag is - * decoded, merely how it was restricted before encoding. If this flag is set - * the tag is restricted as follows: - * - *
-   * Restrictions %ppqrrstt
-   *
-   * p - Tag size restrictions
-   *
-   *   00   No more than 128 frames and 1 MB total tag size.
-   *   01   No more than 64 frames and 128 KB total tag size.
-   *   10   No more than 32 frames and 40 KB total tag size.
-   *   11   No more than 32 frames and 4 KB total tag size.
-   *
-   * q - Text encoding restrictions
-   *
-   *   0    No restrictions
-   *   1    Strings are only encoded with ISO-8859-1 or UTF-8.
-   *
-   * r - Text fields size restrictions
-   *
-   *   00   No restrictions
-   *   01   No string is longer than 1024 characters.
-   *   10   No string is longer than 128 characters.
-   *   11   No string is longer than 30 characters.
-   *
-   *   Note that nothing is said about how many bytes is used to represent those
-   *   characters, since it is encoding dependent. If a text frame consists of
-   *   more than one string, the sum of the strungs is restricted as stated.
-   *
-   * s - Image encoding restrictions
-   *
-   *   0   No restrictions
-   *   1   Images are encoded only with PNG [PNG] or JPEG [JFIF].
-   *
-   * t - Image size restrictions
-   *
-   *   00  No restrictions
-   *   01  All images are 256x256 pixels or smaller.
-   *   10  All images are 64x64 pixels or smaller.
-   *   11  All images are exactly 64x64 pixels, unless required otherwise.
-   * 
- * - * @return integer - */ - public function getRestrictions() { return $this->_restrictions; } - - /** - * Sets the restrictions byte. See {@link #getRestrictions} for more. - * - * @param integer $restrictions The restrictions byte. - */ - public function setRestrictions($restrictions) - { - $this->_restrictions = $restrictions; - } - - /** - * Returns the total padding size, or simply the total tag size excluding the - * frames and the headers. - * - * @return integer - * @deprecated ID3v2.3.0 - */ - public function getPadding() { return $this->_padding; } - - /** - * Sets the total padding size, or simply the total tag size excluding the - * frames and the headers. - * - * @param integer $padding The padding size. - * @deprecated ID3v2.3.0 - */ - public function setPadding($padding) { return $this->_padding = $padding; } - - /** - * Returns the header data. - * - * @return string - */ - public function __toString() - { - /* ID3v2.3.0 ExtendedHeader */ - if ($this->getOption("version", 4) < 4) { - return Transform::toUInt32BE($this->_size) . - Transform::toUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) . - Transform::toUInt32BE($this->_padding) . - ($this->hasFlag(self::CRC32) ? Transform::toUInt32BE($this->_crc) : ""); - } - - /* ID3v2.4.0 ExtendedHeader */ - else { - return Transform::toUInt32BE($this->_encodeSynchsafe32($this->_size)) . - Transform::toInt8(1) . Transform::toInt8($this->_flags) . - ($this->hasFlag(self::UPDATE) ? "\0" : "") . - ($this->hasFlag(self::CRC32) ? Transform::toInt8(5) . - Transform::toInt8($this->_crc & 0xf0000000 >> 28 & 0xf /*eq >>> 28*/) . - Transform::toUInt32BE($this->_encodeSynchsafe32($this->_crc)) : "") . - ($this->hasFlag(self::RESTRICTED) ? - Transform::toInt8(1) . Transform::toInt8($this->_restrictions) : ""); - } - } -} diff --git a/src/ID3/Frame.php b/src/ID3/Frame.php deleted file mode 100644 index 638b218..0000000 --- a/src/ID3/Frame.php +++ /dev/null @@ -1,299 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ID3_Frame extends ID3_Object -{ - /** - * This flag tells the tag parser what to do with this frame if it is unknown - * and the tag is altered in any way. This applies to all kinds of - * alterations, including adding more padding and reordering the frames. - */ - const DISCARD_ON_TAGCHANGE = 16384; - - /** - * This flag tells the tag parser what to do with this frame if it is unknown - * and the file, excluding the tag, is altered. This does not apply when the - * audio is completely replaced with other audio data. - */ - const DISCARD_ON_FILECHANGE = 8192; - - /** - * This flag, if set, tells the software that the contents of this frame are - * intended to be read only. Changing the contents might break something, - * e.g. a signature. - */ - const READ_ONLY = 4096; - - /** - * This flag indicates whether or not this frame belongs in a group with - * other frames. If set, a group identifier byte is added to the frame. Every - * frame with the same group identifier belongs to the same group. - */ - const GROUPING_IDENTITY = 32; - - /** - * This flag indicates whether or not the frame is compressed. A Data - * Length Indicator byte is included in the frame. - * - * @see DATA_LENGTH_INDICATOR - */ - const COMPRESSION = 8; - - /** - * This flag indicates whether or not the frame is encrypted. If set, one byte - * indicating with which method it was encrypted will be added to the frame. - * See description of the {@link ID3_Frame_ENCR} frame for more information - * about encryption method registration. Encryption should be done after - * compression. Whether or not setting this flag requires the presence of a - * Data Length Indicator depends on the specific algorithm used. - * - * @see DATA_LENGTH_INDICATOR - */ - const ENCRYPTION = 4; - - /** - * This flag indicates whether or not unsynchronisation was applied to this - * frame. - * - * @since ID3v2.4.0 - */ - const UNSYNCHRONISATION = 2; - - /** - * This flag indicates that a data length indicator has been added to the - * frame. - * - * @since ID3v2.4.0 - */ - const DATA_LENGTH_INDICATOR = 1; - - /** @var integer */ - private $_identifier; - - /** @var integer */ - private $_size = 0; - - /** @var integer */ - private $_flags = 0; - - /** - * Raw content of the frame. - * - * @var string - */ - protected $_data = ""; - - /** - * Constructs the class with given parameters and reads object related data - * from the ID3v2 tag. - * - * @todo Only limited subset of flags are processed. - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) { - $this->_identifier = substr(get_class($this), -4); - } else { - $this->_identifier = $this->_reader->readString8(4); - - /* ID3v2.3.0 size and flags; convert flags to 2.4.0 format */ - if ($this->getOption("version", 4) < 4) { - $this->_size = $this->_reader->readUInt32BE(); - $flags = $this->_reader->readUInt16BE(); - if (($flags & 0x8000) == 0x8000) - $this->_flags |= self::DISCARD_ON_TAGCHANGE; - if (($flags & 0x4000) == 0x4000) - $this->_flags |= self::DISCARD_ON_FILECHANGE; - if (($flags & 0x2000) == 0x2000) - $this->_flags |= self::READ_ONLY; - if (($flags & 0x80) == 0x80) - $this->_flags |= self::COMPRESSION; - if (($flags & 0x40) == 0x40) - $this->_flags |= self::ENCRYPTION; - if (($flags & 0x20) == 0x20) - $this->_flags |= self::GROUPING_IDENTITY; - } - - /* ID3v2.4.0 size and flags */ - else { - $this->_size = - $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); - $this->_flags = $this->_reader->readUInt16BE(); - } - - $dataLength = $this->_size; - if ($this->hasFlag(self::DATA_LENGTH_INDICATOR)) { - $dataLength = $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); - $this->_size -= 4; - } - $this->_data = $this->_reader->read($this->_size); - $this->_size = $dataLength; - - if ($this->hasFlag(self::UNSYNCHRONISATION) || - $this->getOption("unsynchronisation", false) === true) - $this->_data = $this->_decodeUnsynchronisation($this->_data); - } - } - - /** - * Returns the frame identifier string. - * - * @return string - */ - public final function getIdentifier() { return $this->_identifier; } - - /** - * Sets the frame identifier. - * - * @param string $identifier The identifier. - */ - public final function setIdentifier($identifier) - { - $this->_identifier = $identifier; - } - - /** - * Returns the size of the data in the final frame, after encryption, - * compression and unsynchronisation. The size is excluding the frame header. - * - * @return integer - */ - public final function getSize() { return $this->_size; } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public final function hasFlag($flag) - { - return ($this->_flags & $flag) == $flag; - } - - /** - * Returns the frame flags byte. - * - * @return integer - */ - public final function getFlags($flags) { return $this->_flags; } - - /** - * Sets the frame flags byte. - * - * @param string $flags The flags byte. - */ - public final function setFlags($flags) { $this->_flags = $flags; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - abstract protected function _getData(); - - /** - * Returns the frame data with the header. - * - * @return string - */ - public function __toString() - { - /* ID3v2.3.0 Flags; convert from 2.4.0 format */ - if ($this->getOption("version", 4) < 4) { - $flags = 0; - if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE)) - $flags = $flags | 0x8000; - if ($this->hasFlag(self::DISCARD_ON_FILECHANGE)) - $flags = $flags | 0x4000; - if ($this->hasFlag(self::READ_ONLY)) - $flags = $flags | 0x2000; - if ($this->hasFlag(self::COMPRESSION)) - $flags = $flags | 0x80; - if ($this->hasFlag(self::ENCRYPTION)) - $flags = $flags | 0x40; - if ($this->hasFlag(self::GROUPING_IDENTITY)) - $flags = $flags | 0x20; - } - - /* ID3v2.4.0 Flags */ - else - $flags = $this->_flags; - - if ($this->getOption("version", 4) < 4) { - $data = $this->_data = $this->_getData(); - $size = $this->_size = strlen($data); - } else { - $data = $this->_data = $this->_getData(); - $size = $this->_size = strlen($data); - $data = $this->_encodeUnsynchronisation($data); - if (($dataLength = strlen($data)) != $size) { - $size = 4 + $dataLength; - $data = Transform::toUInt32BE($this->_encodeSynchsafe32($this->_size)) . - $data; - $flags |= self::DATA_LENGTH_INDICATOR | self::UNSYNCHRONISATION; - $this->setOption("unsynchronisation", true); - } else - $flags &= ~(self::DATA_LENGTH_INDICATOR | self::UNSYNCHRONISATION); - } - return Transform::toString8(substr($this->_identifier, 0, 4), 4) . - Transform::toUInt32BE($this->_encodeSynchsafe32($size)) . - Transform::toUInt16BE($flags) . $data; - } -} diff --git a/src/ID3/Frame/AENC.php b/src/ID3/Frame/AENC.php deleted file mode 100644 index a454887..0000000 --- a/src/ID3/Frame/AENC.php +++ /dev/null @@ -1,171 +0,0 @@ -Audio encryption indicates if the actual audio stream is - * encrypted, and by whom. - * - * The identifier is a URL containing an email address, or a link to a location - * where an email address can be found, that belongs to the organisation - * responsible for this specific encrypted audio file. Questions regarding the - * encrypted audio should be sent to the email address specified. There may be - * more than one AENC frame in a tag, but only one with the same owner - * identifier. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_AENC extends ID3_Frame -{ - /** @var string */ - private $_owner; - - /** @var integer */ - private $_previewStart; - - /** @var integer */ - private $_previewLength; - - /** @var string */ - private $_encryptionInfo; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list($this->_owner, $this->_data) = $this->_explodeString8($this->_data, 2); - $this->_previewStart = Transform::fromUInt16BE(substr($this->_data, 0, 2)); - $this->_previewLength = Transform::fromUInt16BE(substr($this->_data, 2, 2)); - $this->_encryptionInfo = substr($this->_data, 4); - } - - /** - * Returns the owner identifier string. - * - * @return string - */ - public function getOwner() { return $this->_owner; } - - /** - * Sets the owner identifier string. - * - * @param string $owner The owner identifier string. - */ - public function setOwner($owner) { $this->_owner = $owner; } - - /** - * Returns the pointer to an unencrypted part of the audio in frames. - * - * @return integer - */ - public function getPreviewStart() { return $this->_previewStart; } - - /** - * Sets the pointer to an unencrypted part of the audio in frames. - * - * @param integer $previewStart The pointer to an unencrypted part. - */ - public function setPreviewStart($previewStart) - { - $this->_previewStart = $previewStart; - } - - /** - * Returns the length of the preview in frames. - * - * @return integer - */ - public function getPreviewLength() { return $this->_previewLength; } - - /** - * Sets the length of the preview in frames. - * - * @param integer $previewLength The length of the preview. - */ - public function setPreviewLength($previewLength) - { - $this->_previewLength = $previewLength; - } - - /** - * Returns the encryption info. - * - * @return string - */ - public function getEncryptionInfo() { return $this->_encryptionInfo; } - - /** - * Sets the encryption info binary string. - * - * @param string $encryptionInfo The data string. - */ - public function setEncryptionInfo($encryptionInfo) - { - $this->_encryptionInfo = $encryptionInfo; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - $this->_owner . "\0" . Transform::toUInt16BE($this->_previewStart) . - Transform::toUInt16BE($this->_previewLength) . $this->_encryptionInfo; - } -} diff --git a/src/ID3/Frame/APIC.php b/src/ID3/Frame/APIC.php deleted file mode 100644 index 322a8d1..0000000 --- a/src/ID3/Frame/APIC.php +++ /dev/null @@ -1,274 +0,0 @@ -Attached picture frame contains a picture directly related to the - * audio file. Image format is the MIME type and subtype for the image. - * - * There may be several pictures attached to one file, each in their individual - * APIC frame, but only one with the same content descriptor. There may only - * be one picture with the same picture type. There is the possibility to put - * only a link to the image file by using the MIME type "-->" and having a - * complete URL instead of picture data. - * - * The use of linked files should however be used sparingly since there is the - * risk of separation of files. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_APIC extends ID3_Frame - implements ID3_Encoding -{ - /** - * The list of image types. - * - * @var Array - */ - public static $types = array - ("Other", "32x32 pixels file icon (PNG only)", "Other file icon", - "Cover (front)", "Cover (back)", "Leaflet page", - "Media (e.g. label side of CD)", "Lead artist/lead performer/soloist", - "Artist/performer", "Conductor", "Band/Orchestra", "Composer", - "Lyricist/text writer", "Recording Location", "During recording", - "During performance", "Movie/video screen capture", - "A bright coloured fish", "Illustration", "Band/artist logotype", - "Publisher/Studio logotype"); - - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_mimeType = "image/unknown"; - - /** @var integer */ - private $_imageType = 0; - - /** @var string */ - private $_description; - - /** @var string */ - private $_imageData; - - /** @var integer */ - private $_imageSize = 0; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_mimeType = substr - ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); - $this->_imageType = Transform::fromUInt8($this->_data[++$pos]); - $this->_data = substr($this->_data, $pos + 1); - - switch ($encoding) { - case self::UTF16: - list ($this->_description, $this->_imageData) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - break; - case self::UTF16BE: - list ($this->_description, $this->_imageData) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - break; - case self::UTF8: - list ($this->_description, $this->_imageData) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - ($this->_description, "utf-8"); - break; - default: - list ($this->_description, $this->_imageData) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - ($this->_description, "iso-8859-1"); - } - - $this->_imageSize = strlen($this->_imageData); - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the MIME type. The MIME type is always ISO-8859-1 encoded. - * - * @return string - */ - public function getMimeType() { return $this->_mimeType; } - - /** - * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. - * - * @param string $mimeType The MIME type. - */ - public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } - - /** - * Returns the image type. - * - * @return integer - */ - public function getImageType() { return $this->_imageType; } - - /** - * Sets the image type code. - * - * @param integer $imageType The image type code. - */ - public function setImageType($imageType) { $this->_imageType = $imageType; } - - /** - * Returns the file description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. - * - * @param string $description The content description text. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $encoding = false) - { - $this->_description = $description; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the embedded image data. - * - * @return string - */ - public function getImageData() { return $this->_imageData; } - - /** - * Sets the embedded image data. Also updates the image size field to - * correspond the new data. - * - * @param string $imageData The image data. - */ - public function setImageData($imageData) - { - $this->_imageData = $imageData; - $this->_imageSize = strlen($imageData); - } - - /** - * Returns the size of the embedded image data. - * - * @return integer - */ - public function getImageSize() { return $this->_imageSize; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_mimeType . "\0" . - Transform::toUInt8($this->_imageType); - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description, false, 1); - break; - default: - $data .= $this->_description . "\0"; - } - return $data . $this->_imageData; - } -} diff --git a/src/ID3/Frame/ASPI.php b/src/ID3/Frame/ASPI.php deleted file mode 100644 index 2c141a7..0000000 --- a/src/ID3/Frame/ASPI.php +++ /dev/null @@ -1,160 +0,0 @@ -Audio seek point index or - * ASPI frame makes seeking easier by providing a list a seek points within the - * audio file. The seek points are a fractional offset within the audio data, - * providing a starting point from which to find an appropriate point to start - * decoding. The presence of an ASPI frame requires the existence of a - * {@link ID3_Frame_TLEN} frame, indicating the duration of the file in - * milliseconds. There may only be one audio seek point index frame in a tag. - * - * @todo Data parsing and write support - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_ASPI extends ID3_Frame -{ - /** @var integer */ - private $_dataStart; - - /** @var integer */ - private $_dataLength; - - /** @var integer */ - private $_size; - - /** @var Array */ - private $_fractions = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Write not supported yet"); - } - - $this->_dataStart = Transform::fromInt32BE(substr($this->_data, 0, 4)); - $this->_dataLength = Transform::fromInt32BE(substr($this->_data, 4, 4)); - $this->_size = Transform::fromInt16BE(substr($this->_data, 8, 2)); - - $bitsPerPoint = Transform::fromInt8($this->_data[10]); - /*for ($i = 0, $offset = 11; $i < $this->_size; $i++) { - if ($bitsPerPoint == 16) { - $this->_fractions[$i] = substr($this->_data, $offset, 2); - $offset += 2; - } else { - $this->_fractions[$i] = substr($this->_data, $offset, 1); - $offset ++; - } - }*/ - } - - /** - * Returns the byte offset from the beginning of the file. - * - * @return integer - */ - public function getDataStart() { return $this->_dataStart; } - - /** - * Sets the byte offset from the beginning of the file. - * - * @param integer $dataStart The offset. - */ - public function setDataStart($dataStart) { $this->_dataStart = $dataStart; } - - /** - * Returns the byte length of the audio data being indexed. - * - * @return integer - */ - public function getDataLength() { return $this->_dataLength; } - - /** - * Sets the byte length of the audio data being indexed. - * - * @param integer $dataLength The length. - */ - public function setDataLength($dataLength) - { - $this->_dataLength = $dataLength; - } - - /** - * Returns the number of index points in the frame. - * - * @return integer - */ - public function getSize() { return count($this->_fractions); } - - /** - * Returns the numerator of the fraction representing a relative position in - * the data or false if index not defined. The denominator is 2 - * to the power of b. - * - * @param integer $index The fraction numerator. - * @return integer - */ - public function getFractionAt($index) - { - if (isset($this->_fractions[$index])) - return $this->_fractions[$index]; - return false; - } -} diff --git a/src/ID3/Frame/AbstractLink.php b/src/ID3/Frame/AbstractLink.php deleted file mode 100644 index 73650ed..0000000 --- a/src/ID3/Frame/AbstractLink.php +++ /dev/null @@ -1,96 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ID3_Frame_AbstractLink extends ID3_Frame -{ - /** @var string */ - protected $_link; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader !== null) - $this->_link = implode($this->_explodeString8($this->_data, 1), ""); - } - - /** - * Returns the link associated with the frame. - * - * @return string - */ - public function getLink() { return $this->_link; } - - /** - * Sets the link. The link encoding is always ISO-8859-1. - * - * @param string $link The link. - */ - public function setLink($link) { $this->_link = $link; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return $this->_link; - } -} diff --git a/src/ID3/Frame/AbstractText.php b/src/ID3/Frame/AbstractText.php deleted file mode 100644 index cf7753f..0000000 --- a/src/ID3/Frame/AbstractText.php +++ /dev/null @@ -1,188 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ID3_Frame_AbstractText extends ID3_Frame - implements ID3_Encoding -{ - /** - * The text encoding. - * - * @var integer - */ - protected $_encoding; - - /** - * The text array. - * - * @var string - */ - protected $_text; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_data = substr($this->_data, 1); - switch ($encoding) { - case self::UTF16: - $this->_text = $this->_convertString - ($this->_explodeString16(Transform::fromString16($this->_data)), - "utf-16"); - break; - case self::UTF16BE: - $this->_text = $this->_convertString - ($this->_explodeString16(Transform::fromString16($this->_data)), - "utf-16be"); - break; - case self::UTF8: - $this->_text = $this->_convertString - ($this->_explodeString8(Transform::fromString8($this->_data)), "utf-8"); - break; - default: - $this->_text = $this->_convertString - ($this->_explodeString8(Transform::fromString8($this->_data)), - "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the first text chunk the frame contains. - * - * @return string - */ - public function getText() { return $this->_text[0]; } - - /** - * Returns an array of texts the frame contains. - * - * @return Array - */ - public function getTexts() { return $this->_text; } - - /** - * Sets the text using given encoding. - * - * @param mixed $text The test string or an array of strings. - * @param integer $encoding The text encoding. - */ - public function setText($text, $encoding = false) - { - $this->_text = is_array($text) ? $text : array($text); - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding); - switch ($this->_encoding) { - case self::UTF16LE: - $array = $this->_text; - foreach ($array as &$text) - $text = Transform::toString16($text, Transform::LITTLE_ENDIAN_ORDER); - $data .= implode("\0\0", $array); - break; - case self::UTF16: - case self::UTF16BE: - $data .= implode("\0\0", $this->_text); - break; - default: - $data .= implode("\0", $this->_text); - } - return $data; - } -} diff --git a/src/ID3/Frame/COMM.php b/src/ID3/Frame/COMM.php deleted file mode 100644 index d11e4ab..0000000 --- a/src/ID3/Frame/COMM.php +++ /dev/null @@ -1,254 +0,0 @@ -Comments frame is intended for any kind of full text information - * that does not fit in any other frame. It consists of a frame header followed - * by encoding, language and content descriptors and is ended with the actual - * comment as a text string. Newline characters are allowed in the comment text - * string. There may be more than one comment frame in each tag, but only one - * with the same language and content descriptor. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_COMM extends ID3_Frame - implements ID3_Encoding, ID3_Language -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_language = "und"; - - /** @var string */ - private $_description; - - /** @var string */ - private $_text; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_language = substr($this->_data, 1, 3); - if ($this->_language == "XXX") - $this->_language = "und"; - $this->_data = substr($this->_data, 4); - - switch ($encoding) { - case self::UTF16: - list ($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - $this->_text = $this->_convertString - (Transform::fromString16($this->_text), "utf-16"); - break; - case self::UTF16BE: - list ($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - $this->_text = $this->_convertString - (Transform::fromString16($this->_text), "utf-16be"); - break; - case self::UTF8: - list ($this->_description, $this->_text) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "utf-8"); - $this->_text = $this->_convertString - (Transform::fromString8($this->_text), "utf-8"); - break; - default: - list ($this->_description, $this->_text) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "iso-8859-1"); - $this->_text = $this->_convertString - (Transform::fromString8($this->_text), "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @return string - */ - public function getLanguage() { return $this->_language; } - - /** - * Sets the text language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @see ID3_Language - * @param string $language The language code. - */ - public function setLanguage($language) - { - if ($language == "XXX") - $language = "und"; - $this->_language = substr($language, 0, 3); - } - - /** - * Returns the short content description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. The description - * language and encoding must be that of the actual text. - * - * @param string $description The content description text. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $language = false, - $encoding = false) - { - $this->_description = $description; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the comment text. - * - * @return string - */ - public function getText() { return $this->_text; } - - /** - * Sets the text using given encoding. The text language and encoding must be - * that of the description text. - * - * @param mixed $text The test string. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setText($text, $language = false, $encoding = false) - { - $this->_text = $text; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_language; - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1) . - Transform::toString16($this->_text, Transform::LITTLE_ENDIAN_ORDER); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description, false, 1) . - Transform::toString16($this->_text); - break; - default: - $data .= $this->_description . "\0" . $this->_text; - } - return $data; - } -} diff --git a/src/ID3/Frame/COMR.php b/src/ID3/Frame/COMR.php deleted file mode 100644 index 29d54a1..0000000 --- a/src/ID3/Frame/COMR.php +++ /dev/null @@ -1,400 +0,0 @@ -Commercial frame enables several competing offers in the same tag - * by bundling all needed information. That makes this frame rather complex but - * it's an easier solution than if one tries to achieve the same result with - * several frames. - * - * There may be more than one commercial frame in a tag, but no two may be - * identical. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_COMR extends ID3_Frame - implements ID3_Encoding -{ - /** - * The delivery types. - * - * @var Array - */ - public static $types = array - ("Other", "Standard CD album with other songs", "Compressed audio on CD", - "File over the Internet", "Stream over the Internet", "As note sheets", - "As note sheets in a book with other sheets", "Music on other media", - "Non-musical merchandise"); - - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_currency = "EUR"; - - /** @var string */ - private $_price; - - /** @var string */ - private $_date; - - /** @var string */ - private $_contact; - - /** @var integer */ - private $_delivery = 0; - - /** @var string */ - private $_seller; - - /** @var string */ - private $_description; - - /** @var string */ - private $_mimeType = false; - - /** @var string */ - private $_imageData; - - /** @var integer */ - private $_imageSize = 0; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - list($pricing, $this->_data) = - $this->_explodeString8(substr($this->_data, 1), 2); - $this->_currency = substr($pricing, 0, 3); - $this->_price = substr($pricing, 3); - $this->_date = substr($this->_data, 0, 8); - list($this->_contact, $this->_data) = - $this->_explodeString8(substr($this->_data, 8), 2); - $this->_delivery = Transform::fromUInt8($this->_data[0]); - $this->_data = substr($this->_data, 1); - - switch ($encoding) { - case self::UTF16: - list ($this->_seller, $this->_description, $this->_data) = - $this->_explodeString16($this->_data, 3); - $this->_seller = $this->_convertString - (Transform::fromString16($this->_seller), "utf-16"); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - break; - case self::UTF16BE: - list ($this->_seller, $this->_description, $this->_data) = - $this->_explodeString16($this->_data, 3); - $this->_seller = $this->_convertString - (Transform::fromString16($this->_seller), "utf-16be"); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - break; - case self::UTF8: - list ($this->_seller, $this->_description, $this->_data) = - $this->_explodeString8($this->_data, 3); - $this->_seller = $this->_convertString - (Transform::fromString8($this->_seller), "utf-8"); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "utf-8"); - break; - default: - list ($this->_seller, $this->_description, $this->_data) = - $this->_explodeString8($this->_data, 3); - $this->_seller = $this->_convertString - (Transform::fromString8($this->_seller), "iso-8859-1"); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "iso-8859-1"); - } - - if (strlen($this->_data) == 0) - return; - - list($this->_mimeType, $this->_imageData) = - $this->_explodeString8($this->_data, 2); - - $this->_imageSize = strlen($this->_imageData); - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the currency code, encoded according to - * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm - * ISO 4217} alphabetic currency code. - * - * @return string - */ - public function getCurrency() { return $this->_currency; } - - /** - * Sets the currency used in transaction, encoded according to - * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm - * ISO 4217} alphabetic currency code. - * - * @param string $currency The currency code. - */ - public function setCurrency($currency) { $this->_currency = $currency; } - - /** - * Returns the price as a numerical string using "." as the decimal separator. - * - * In the price string several prices may be concatenated, separated by a "/" - * character, but there may only be one currency of each type. - * - * @return string - */ - public function getPrice() { return $this->_price; } - - /** - * Sets the price. The price must use "." as the decimal separator and have - * multiple values be separated by a "/" character. - * - * @param string $price The price. - */ - public function setPrice($price) - { - $this->_price = $price; - } - - /** - * Returns the date as an 8 character date string (YYYYMMDD), describing for - * how long the price is valid. - * - * @return string - */ - public function getDate() { return $this->_date; } - - /** - * Sets the date describing for how long the price is valid for. The date must - * be an 8 character date string (YYYYMMDD). - * - * @param string $date The date string. - */ - public function setDate($date) { $this->_date = $date; } - - /** - * Returns the contact URL, with which the user can contact the seller. - * - * @return string - */ - public function getContact() { return $this->_contact; } - - /** - * Sets the contact URL, with which the user can contact the seller. - * - * @param string $contact The contact URL. - */ - public function setContact($contact) { $this->_contact = $contact; } - - /** - * Returns the delivery type with whitch the audio was delivered when bought. - * - * @return integer - */ - public function getDelivery() { return $this->_delivery; } - - /** - * Sets the delivery type with whitch the audio was delivered when bought. - * - * @param integer $delivery The delivery type code. - */ - public function setDelivery($delivery) { $this->_delivery = $delivery; } - - /** - * Returns the name of the seller. - * - * @return string - */ - public function getSeller() { return $this->_seller; } - - /** - * Sets the name of the seller using given encoding. The seller text encoding - * must be that of the description text. - * - * @param string $seller The name of the seller. - * @param integer $encoding The text encoding. - */ - public function setSeller($seller, $encoding = false) - { - $this->_seller = $seller; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the short description of the product. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. The description - * encoding must be that of the seller text. - * - * @param string $description The content description text. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $encoding = false) - { - $this->_description = $description; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the MIME type of the seller's company logo, if attached, or - * false otherwise. Currently only "image/png" and "image/jpeg" - * are allowed. - * - * @return string - */ - public function getMimeType() { return $this->_mimeType; } - - /** - * Sets the MIME type. Currently only "image/png" and "image/jpeg" are - * allowed. The MIME type is always ISO-8859-1 encoded. - * - * @param string $mimeType The MIME type. - */ - public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } - - /** - * Returns the embedded image binary data. - * - * @return string - */ - public function getImageData() { return $this->_imageData; } - - /** - * Sets the embedded image data. Also updates the image size to correspond the - * new data. - * - * @param string $imageData The image data. - */ - public function setImageData($imageData) - { - $this->_imageData = $imageData; - $this->_imageSize = strlen($imageData); - } - - /** - * Returns the size of the embedded image data. - * - * @return integer - */ - public function getImageSize() { return $this->_imageSize; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_currency . - $this->_price . "\0" . $this->_date . $this->_contact . "\0" . - Transform::toUInt8($this->_delivery); - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_seller, Transform::LITTLE_ENDIAN_ORDER, 1) . - Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_seller, false, 1) . - Transform::toString16($this->_description, false, 1); - break; - default: - $data .= $this->_seller . "\0" . $this->_description . "\0"; - } - return - $data . ($this->_mimeType ? - $this->_mimeType . "\0" . $this->_imageData : ""); - } -} diff --git a/src/ID3/Frame/ENCR.php b/src/ID3/Frame/ENCR.php deleted file mode 100644 index b3cccc4..0000000 --- a/src/ID3/Frame/ENCR.php +++ /dev/null @@ -1,156 +0,0 @@ -Encryption method - * registration frame. - * - * The owner identifier a URL containing an email address, or a link to a - * location where an email address can be found, that belongs to the - * organisation responsible for this specific encryption method. Questions - * regarding the encryption method should be sent to the indicated email - * address. - * - * The method symbol contains a value that is associated with this method - * throughout the whole tag, in the range $80-F0. All other values are reserved. - * The method symbol may optionally be followed by encryption specific data. - * - * There may be several ENCR frames in a tag but only one containing the same - * symbol and only one containing the same owner identifier. The method must be - * used somewhere in the tag. See {@link ID3_Frame#ENCRYPTION} for more - * information. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_ENCR extends ID3_Frame -{ - /** @var string */ - private $_owner; - - /** @var integer */ - private $_method; - - /** @var string */ - private $_encryptionData; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list($this->_owner, $this->_data) = $this->_explodeString8($this->_data, 2); - $this->_method = Transform::fromInt8($this->_data[0]); - $this->_encryptionData = substr($this->_data, 1); - } - - /** - * Returns the owner identifier string. - * - * @return string - */ - public function getOwner() { return $this->_owner; } - - /** - * Sets the owner identifier string. - * - * @param string $owner The owner identifier string. - */ - public function setOwner($owner) { $this->_owner = $owner; } - - /** - * Returns the method symbol. - * - * @return integer - */ - public function getMethod() { return $this->_method; } - - /** - * Sets the method symbol. - * - * @param integer $method The method symbol byte. - */ - public function setMethod($method) { $this->_method = $method; } - - /** - * Returns the encryption data. - * - * @return string - */ - public function getEncryptionData() { return $this->_encryptionData; } - - /** - * Sets the encryption data. - * - * @param string $encryptionData The encryption data string. - */ - public function setEncryptionData($encryptionData) - { - $this->_encryptionData = $encryptionData; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - $this->_owner . "\0" . Transform::toInt8($this->_method) . - $this->_encryptionData; - } -} diff --git a/src/ID3/Frame/EQU2.php b/src/ID3/Frame/EQU2.php deleted file mode 100644 index 323064d..0000000 --- a/src/ID3/Frame/EQU2.php +++ /dev/null @@ -1,193 +0,0 @@ -Equalisation (2) is another subjective, alignment frame. It allows - * the user to predefine an equalisation curve within the audio file. There may - * be more than one EQU2 frame in each tag, but only one with the same - * identification string. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_EQU2 extends ID3_Frame -{ - /** - * Interpolation type that defines that no interpolation is made. A jump from - * one adjustment level to another occurs in the middle between two adjustment - * points. - */ - const BAND = 0; - - /** - * Interpolation type that defines that interpolation between adjustment - * points is linear. - */ - const LINEAR = 1; - - /** @var integer */ - private $_interpolation; - - /** @var string */ - private $_device; - - /** @var Array */ - private $_adjustments; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_interpolation = Transform::fromInt8($this->_data[0]); - list ($this->_device, $this->_data) = - $this->_explodeString8(substr($this->_data, 1), 2); - - for ($i = 0; $i < strlen($this->_data); $i += 4) - $this->_adjustments - [(int)(Transform::fromUInt16BE(substr($this->_data, $i, 2)) / 2)] = - Transform::fromInt16BE(substr($this->_data, $i + 2, 2)) / 512.0; - ksort($this->_adjustments); - } - - /** - * Returns the interpolation method. The interpolation method describes which - * method is preferred when an interpolation between the adjustment point that - * follows. - * - * @return integer - */ - public function getInterpolation() { return $this->_interpolation; } - - /** - * Sets the interpolation method. The interpolation method describes which - * method is preferred when an interpolation between the adjustment point that - * follows. - * - * @param integer $interpolation The interpolation method code. - */ - public function setInterpolation($interpolation) - { - $this->_interpolation = $interpolation; - } - - /** - * Returns the device where the adjustments should apply. - * - * @return string - */ - public function getDevice() { return $this->_device; } - - /** - * Sets the device where the adjustments should apply. - * - * @param string $device The device. - */ - public function setDevice($device) { $this->_device = $device; } - - /** - * Returns the array containing adjustments having frequencies as keys and - * their corresponding adjustments as values. - * - * Adjustment points are ordered by frequency. - * - * @return Array - */ - public function getAdjustments() { return $this->_adjustments; } - - /** - * Adds a volume adjustment setting for given frequency. The frequency can - * have a value from 0 to 32767 Hz, and the adjustment +/- 64 dB with a - * precision of 0.001953125 dB. - * - * @param integer $frequency The frequency, in hertz. - * @param integer $adjustment The adjustment, in dB. - */ - public function addAdjustment($frequency, $adjustment) - { - $this->_adjustments[$frequency] = $adjustment; - ksort($this->_adjustments); - } - - /** - * Sets the adjustments array. The array must have frequencies as keys and - * their corresponding adjustments as values. The frequency can have a value - * from 0 to 32767 Hz, and the adjustment +/- 64 dB with a precision of - * 0.001953125 dB. One frequency should only be described once in the frame. - * - * @param Array $adjustments The adjustments array. - */ - public function setAdjustments($adjustments) - { - $this->_adjustments = $adjustments; - ksort($this->_adjustments); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toInt8($this->_interpolation) . $this->_device . "\0"; - foreach ($this->_adjustments as $frequency => $adjustment) - $data .= Transform::toUInt16BE($frequency * 2) . - Transform::toInt16BE($adjustment * 512); - return $data; - } -} diff --git a/src/ID3/Frame/EQUA.php b/src/ID3/Frame/EQUA.php deleted file mode 100644 index 2ac5136..0000000 --- a/src/ID3/Frame/EQUA.php +++ /dev/null @@ -1,142 +0,0 @@ -Equalisation frame is another subjective, alignment frame. It - * allows the user to predefine an equalisation curve within the audio file. - * There may only be one EQUA frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_EQUA extends ID3_Frame -{ - /** @var Array */ - private $_adjustments; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $adjustmentBits = Transform::fromInt8($this->_data[0]); - if ($adjustmentBits <= 8 || $adjustmentBits > 16) { - require_once("ID3/Exception.php"); - throw new ID3_Exception - ("Unsupported adjustment bit size of: " . $adjustmentBits); - } - - for ($i = 1; $i < strlen($this->_data); $i += 4) { - $frequency = Transform::fromUInt16BE(substr($this->_data, $i, 2)); - $this->_adjustments[($frequency & 0x7fff)] = - ($frequency & 0x8000) == 0x8000 ? - Transform::fromUInt16BE(substr($this->_data, $i + 2, 2)) : - -Transform::fromUInt16BE(substr($this->_data, $i + 2, 2)); - } - ksort($this->_adjustments); - } - - /** - * Returns the array containing adjustments having frequencies as keys and - * their corresponding adjustments as values. - * - * @return Array - */ - public function getAdjustments() { return $this->_adjustments; } - - /** - * Adds a volume adjustment setting for given frequency. The frequency can - * have a value from 0 to 32767 Hz. - * - * @param integer $frequency The frequency, in hertz. - * @param integer $adjustment The adjustment, in dB. - */ - public function addAdjustment($frequency, $adjustment) - { - $this->_adjustments[$frequency] = $adjustment; - ksort($this->_adjustments); - } - - /** - * Sets the adjustments array. The array must have frequencies as keys and - * their corresponding adjustments as values. The frequency can have a value - * from 0 to 32767 Hz. One frequency should only be described once in the - * frame. - * - * @param Array $adjustments The adjustments array. - */ - public function setAdjustments($adjustments) - { - $this->_adjustments = $adjustments; - ksort($this->_adjustments); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toInt8(16); - foreach ($this->_adjustments as $frequency => $adjustment) - $data .= Transform::toUInt16BE - ($adjustment > 0 ? $frequency | 0x8000 : $frequency & ~0x8000) . - Transform::toUInt16BE(abs($adjustment)); - return $data; - } -} diff --git a/src/ID3/Frame/ETCO.php b/src/ID3/Frame/ETCO.php deleted file mode 100644 index 95a4e69..0000000 --- a/src/ID3/Frame/ETCO.php +++ /dev/null @@ -1,168 +0,0 @@ -Event timing codes allows synchronisation with key events in the - * audio. - * - * The events are an array of timestamp and type pairs. The time stamp is set to - * zero if directly at the beginning of the sound or after the previous event. - * All events are sorted in chronological order. - * - * The events $E0-EF are for user events. You might want to synchronise your - * music to something, like setting off an explosion on-stage, activating a - * screensaver etc. - * - * There may only be one ETCO frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_ETCO extends ID3_Frame - implements ID3_Timing -{ - /** - * The list of event types. - * - * @var Array - */ - public static $types = array - ("Padding", "End of initial silence", "Intro start", "Main part start", - "Outro start", "Outro end", "Verse start","Refrain start", - "Interlude start", "Theme start", "Variation start", "Key change", - "Time change", "Momentary unwanted noise", "Sustained noise", - "Sustained noise end", "Intro end", "Main part end", "Verse end", - "Refrain end", "Theme end", "Profanity", "Profanity end", - - 0xe0 => "User event", "User event", "User event", "User event", - "User event", "User event", "User event", "User event", "User event", - "User event", "User event", "User event", "User event", "User event", - - 0xfd => "Audio end (start of silence)", "Audio file ends", - "One more byte of events follows"); - - /** @var integer */ - private $_format = ID3_Timing::MPEG_FRAMES; - - /** @var Array */ - private $_events = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_format = Transform::fromUInt8($this->_data[0]); - for ($i = 1; $i < $this->getSize(); $i += 5) { - $this->_events[Transform::fromUInt32BE(substr($this->_data, $i + 1, 4))] = - $data = Transform::fromUInt8($this->_data[$i]); - if ($data == 0xff) - break; - } - ksort($this->_events); - } - - /** - * Returns the timing format. - * - * @return integer - */ - public function getFormat() { return $this->_format; } - - /** - * Sets the timing format. - * - * @see ID3_Timing - * @param integer $format The timing format. - */ - public function setFormat($format) { $this->_format = $format; } - - /** - * Returns the events as an associated array having the timestamps as keys and - * the event types as values. - * - * @return Array - */ - public function getEvents() { return $this->_events; } - - /** - * Sets the events using given format. The value must be an associated array - * having the timestamps as keys and the event types as values. - * - * @param Array $events The events array. - * @param integer $format The timing format. - */ - public function setEvents($events, $format = false) - { - $this->_events = $events; - if ($format !== false) - $this->_format = $format; - ksort($this->_events); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_format); - foreach ($this->_events as $timestamp => $type) - $data .= Transform::toUInt8($type) . Transform::toUInt32BE($timestamp); - return $data; - } -} diff --git a/src/ID3/Frame/GEOB.php b/src/ID3/Frame/GEOB.php deleted file mode 100644 index 0a3c674..0000000 --- a/src/ID3/Frame/GEOB.php +++ /dev/null @@ -1,253 +0,0 @@ -General encapsulated object frame any type of file can be - * encapsulated. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_GEOB extends ID3_Frame - implements ID3_Encoding -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_mimeType; - - /** @var string */ - private $_filename; - - /** @var string */ - private $_description; - - /** @var string */ - private $_objectData; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_mimeType = substr - ($this->_data, 1, ($pos = strpos($this->_data, "\0", 1)) - 1); - $this->_data = substr($this->_data, $pos + 1); - - switch ($encoding) { - case self::UTF16: - list ($this->_filename, $this->_description, $this->_objectData) = - $this->_explodeString16($this->_data, 3); - $this->_filename = $this->_convertString - (Transform::fromString16($this->_filename), "utf-16"); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - break; - case self::UTF16BE: - list ($this->_filename, $this->_description, $this->_objectData) = - $this->_explodeString16($this->_data, 3); - $this->_filename = $this->_convertString - (Transform::fromString16($this->_filename), "utf-16be"); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - break; - case self::UTF8: - list ($this->_filename, $this->_description, $this->_objectData) = - $this->_explodeString8($this->_data, 3); - $this->_filename = $this->_convertString - (Transform::fromString8($this->_filename), "utf-8"); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "utf-8"); - break; - default: - list ($this->_filename, $this->_description, $this->_objectData) = - $this->_explodeString8($this->_data, 3); - $this->_filename = $this->_convertString - (Transform::fromString8($this->_filename), "iso-8859-1"); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. - * - * @return string - */ - public function getMimeType() { return $this->_mimeType; } - - /** - * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. - * - * @param string $mimeType The MIME type. - */ - public function setMimeType($mimeType) { $this->_mimeType = $mimeType; } - - /** - * Returns the file name. - * - * @return string - */ - public function getFilename() { return $this->_filename; } - - /** - * Sets the file name using given encoding. The file name encoding must be - * that of the description text. - * - * @param string $description The file description text. - * @param integer $encoding The text encoding. - */ - public function setFilename($filename, $encoding = false) - { - $this->_filename = $filename; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the file description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the file description text using given encoding. The description - * encoding must be that of the file name. - * - * @param string $description The file description text. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $encoding = false) - { - $this->_description = $description; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the embedded object binary data. - * - * @return string - */ - public function getObjectData() { return $this->_objectData; } - - /** - * Sets the embedded object binary data. - * - * @param string $objectData The object data. - */ - public function setObjectData($objectData) - { - $this->_objectData = $objectData; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_mimeType . "\0"; - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_filename, Transform::LITTLE_ENDIAN_ORDER, 1) . - Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_filename, false, 1) . - Transform::toString16($this->_description, false, 1); - break; - default: - $data .= $this->_filename . "\0" . $this->_description . "\0"; - } - return $data . $this->_objectData; - } -} diff --git a/src/ID3/Frame/GRID.php b/src/ID3/Frame/GRID.php deleted file mode 100644 index faac81c..0000000 --- a/src/ID3/Frame/GRID.php +++ /dev/null @@ -1,152 +0,0 @@ -Group identification registration frame enables grouping of - * otherwise unrelated frames. This can be used when some frames are to be - * signed. To identify which frames belongs to a set of frames a group - * identifier must be registered in the tag with this frame. - * - * The owner identifier is a URL containing an email address, or a link to a - * location where an email address can be found, that belongs to the - * organisation responsible for this grouping. Questions regarding the grouping - * should be sent to the indicated email address. - * - * The group symbol contains a value that associates the frame with this group - * throughout the whole tag, in the range $80-F0. All other values are reserved. - * The group symbol may optionally be followed by some group specific data, e.g. - * a digital signature. There may be several GRID frames in a tag but only one - * containing the same symbol and only one containing the same owner identifier. - * The group symbol must be used somewhere in the tag. See - * {@link ID3_Frame#GROUPING_ownerENTITY} for more information. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_GRID extends ID3_Frame -{ - /** @var string */ - private $_owner; - - /** @var integer */ - private $_group; - - /** @var string */ - private $_groupData; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list($this->_owner, $this->_data) = $this->_explodeString8($this->_data, 2); - $this->_group = Transform::fromUInt8($this->_data[0]); - $this->_groupData = substr($this->_data, 1); - } - - /** - * Returns the owner identifier string. - * - * @return string - */ - public function getOwner() { return $this->_owner; } - - /** - * Sets the owner identifier string. - * - * @param string $owner The owner identifier string. - */ - public function setOwner($owner) { $this->_owner = $owner; } - - /** - * Returns the group symbol. - * - * @return integer - */ - public function getGroup() { return $this->_group; } - - /** - * Sets the group symbol. - * - * @param integer $group The group symbol. - */ - public function setGroup($group) { $this->_group = $group; } - - /** - * Returns the group dependent data. - * - * @return string - */ - public function getGroupData() { return $this->_groupData; } - - /** - * Sets the group dependent data. - * - * @param string $groupData The data. - */ - public function setGroupData($groupData) { $this->_groupData = $groupData; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - $this->_owner . "\0" . Transform::toUInt8($this->_group) . - $this->_groupData; - } -} diff --git a/src/ID3/Frame/IPLS.php b/src/ID3/Frame/IPLS.php deleted file mode 100644 index b789605..0000000 --- a/src/ID3/Frame/IPLS.php +++ /dev/null @@ -1,191 +0,0 @@ -Involved people list is a frame containing the names of those - * involved, and how they were involved. There may only be one IPLS frame in - * each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_IPLS extends ID3_Frame - implements ID3_Encoding -{ - /** @var integer */ - private $_encoding; - - /** @var Array */ - private $_people = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $data = substr($this->_data, 1); - $order = Transform::MACHINE_ENDIAN_ORDER; - switch ($encoding) { - case self::UTF16: - $data = $this->_explodeString16($data); - foreach ($data as &$str) - $str = $this->_convertString - (Transform::fromString16($str, $order), "utf-16"); - break; - case self::UTF16BE: - $data = $this->_explodeString16($data); - foreach ($data as &$str) - $str = $this->_convertString - (Transform::fromString16($str), "utf-16be"); - break; - case self::UTF8: - $data = $this->_convertString($this->_explodeString8($data), "utf-8"); - break; - default: - $data = $this->_convertString($this->_explodeString8($data), "iso-8859-1"); - } - - for ($i = 0; $i < count($data) - 1; $i += 2) - $this->_people[] = array($data[$i] => @$data[$i + 1]); - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the involved people list as an array. For each person, the array - * contains an entry, which too is an associate array with involvement as its - * key and involvee as its value. - * - * @return Array - */ - public function getPeople() { return $this->_people; } - - /** - * Adds a person with his involvement. - * - * @return string - */ - public function addPerson($involvement, $person) - { - $this->_people[] = array($involvement => $person); - } - - /** - * Sets the involved people list array. For each person, the array must - * contain an associate array with involvement as its key and involvee as its - * value. - * - * @param Array $people The involved people list. - */ - public function setPeople($people) { $this->_people = $people; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding); - foreach ($this->_people as $entry) { - foreach ($entry as $key => $val) { - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($key, Transform::LITTLE_ENDIAN_ORDER, 1) . - Transform::toString16($val, Transform::LITTLE_ENDIAN_ORDER, 1); - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($key, false, 1) . - Transform::toString16($val, false, 1); - break; - default: - $data .= $key . "\0" . $val . "\0"; - } - } - } - return $data; - } -} diff --git a/src/ID3/Frame/LINK.php b/src/ID3/Frame/LINK.php deleted file mode 100644 index 341eeb4..0000000 --- a/src/ID3/Frame/LINK.php +++ /dev/null @@ -1,173 +0,0 @@ -Linked information frame is used to keep information duplication - * as low as possible by linking information from another ID3v2 tag that might - * reside in another audio file or alone in a binary file. It is recommended - * that this method is only used when the files are stored on a CD-ROM or other - * circumstances when the risk of file separation is low. - * - * Data should be retrieved from the first tag found in the file to which this - * link points. There may be more than one LINK frame in a tag, but only one - * with the same contents. - * - * A linked frame is to be considered as part of the tag and has the same - * restrictions as if it was a physical part of the tag (i.e. only one - * {@link ID3_Frame_RVRB} frame allowed, whether it's linked or not). - * - * Frames that may be linked and need no additional data are - * {@link ID3_Frame_ASPI}, {@link ID3_Frame_ETCO}, {@link ID3_Frame_EQU2}, - * {@link ID3_Frame_MCDI}, {@link ID3_Frame_MLLT}, {@link ID3_Frame_OWNE}, - * {@link ID3_Frame_RVA2}, {@link ID3_Frame_RVRB}, {@link ID3_Frame_SYTC}, the - * text information frames (ie frames descendats of - * {@link ID3_Frame_AbstractText}) and the URL link frames (ie frames descendants - * of {@link ID3_Frame_AbstractLink}). - * - * The {@link ID3_Frame_AENC}, {@link ID3_Frame_APIC}, {@link ID3_Frame_GEOB} - * and {@link ID3_Frame_TXXX} frames may be linked with the content descriptor - * as additional ID data. - * - * The {@link ID3_Frame_USER} frame may be linked with the language field as - * additional ID data. - * - * The {@link ID3_Frame_PRIV} frame may be linked with the owner identifier as - * additional ID data. - * - * The {@link ID3_Frame_COMM}, {@link ID3_Frame_SYLT} and {@link ID3_Frame_USLT} - * frames may be linked with three bytes of language descriptor directly - * followed by a content descriptor as additional ID data. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_LINK extends ID3_Frame -{ - /** @var string */ - private $_target; - - /** @var string */ - private $_url; - - /** @var string */ - private $_qualifier; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_target = substr($this->_data, 0, 4); - list($this->_url, $this->_qualifier) = - $this->_explodeString8(substr($this->_data, 4), 2); - } - - /** - * Returns the target tag identifier. - * - * @return string - */ - public function getTarget() { return $this->_target; } - - /** - * Sets the target tag identifier. - * - * @param string $target The target tag identifier. - */ - public function setTarget($target) { $this->_target = $target; } - - /** - * Returns the target tag URL. - * - * @return string - */ - public function getUrl() { return $this->_url; } - - /** - * Sets the target tag URL. - * - * @param string $url The target URL. - */ - public function setUrl($url) { $this->_url = $url; } - - /** - * Returns the additional data to identify further the tag. - * - * @return string - */ - public function getQualifier() { return $this->_qualifier; } - - /** - * Sets the additional data to be used in tag identification. - * - * @param string $identifier The qualifier. - */ - public function setQualifier($qualifier) - { - $this->_qualifier = $qualifier; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - Transform::toString8(substr($this->_target, 0, 4), 4) . - $this->_url . "\0" . $this->_qualifier; - } -} diff --git a/src/ID3/Frame/MCDI.php b/src/ID3/Frame/MCDI.php deleted file mode 100644 index 625fd6f..0000000 --- a/src/ID3/Frame/MCDI.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_MCDI extends ID3_Frame -{ - /** - * Returns the CD TOC binary dump. - * - * @return string - */ - public function getData() { return $this->_data; } - - /** - * Sets the CD TOC binary dump. - * - * @param string $data The CD TOC binary dump string. - */ - public function setData($data) { $this->_data = $data; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() { return $this->_data; } -} diff --git a/src/ID3/Frame/MLLT.php b/src/ID3/Frame/MLLT.php deleted file mode 100644 index ee1218f..0000000 --- a/src/ID3/Frame/MLLT.php +++ /dev/null @@ -1,172 +0,0 @@ -MPEG location lookup table frame includes references that the - * software can use to calculate positions in the file. - * - * The MPEG frames between reference describes how much the frame counter should - * be increased for every reference. If this value is two then the first - * reference points out the second frame, the 2nd reference the 4th frame, the - * 3rd reference the 6th frame etc. In a similar way the bytes between reference - * and milliseconds between reference points out bytes and milliseconds - * respectively. - * - * Each reference consists of two parts; a certain number of bits that describes - * the difference between what is said in bytes between reference and the - * reality and a certain number of bits that describes the difference between - * what is said in milliseconds between reference and the reality. - * - * There may only be one MLLT frame in each tag. - * - * @todo Data parsing and write support - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_MLLT extends ID3_Frame -{ - /** @var integer */ - private $_frames; - - /** @var integer */ - private $_bytes; - - /** @var integer */ - private $_milliseconds; - - /** @var Array */ - private $_deviation = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Write not supported yet"); - } - - $this->_frames = Transform::fromInt16BE(substr($this->_data, 0, 2)); - $this->_bytes = Transform::fromInt32BE(substr($this->_data, 2, 3)); - $this->_milliseconds = Transform::fromInt32BE(substr($this->_data, 5, 3)); - - $byteDevBits = Transform::fromInt8($this->_data[8]); - $millisDevBits = Transform::fromInt8($this->_data[9]); - - // $data = substr($this->_data, 10); - } - - /** - * Returns the number of MPEG frames between reference. - * - * @return integer - */ - public function getFrames() { return $this->_frames; } - - /** - * Sets the number of MPEG frames between reference. - * - * @param integer $frames The number of MPEG frames. - */ - public function setFrames($frames) { $this->_frames = $frames; } - - /** - * Returns the number of bytes between reference. - * - * @return integer - */ - public function getBytes() { return $this->_bytes; } - - /** - * Sets the number of bytes between reference. - * - * @param integer $bytes The number of bytes. - */ - public function setBytes($bytes) { $this->_bytes = $bytes; } - - /** - * Returns the number of milliseconds between references. - * - * @return integer - */ - public function getMilliseconds() { return $this->_milliseconds; } - - /** - * Sets the number of milliseconds between references. - * - * @param integer $milliseconds The number of milliseconds. - */ - public function setMilliseconds($milliseconds) - { - return $this->_milliseconds; - } - - /** - * Returns the deviations as an array. Each value is an array containing two - * values, ie the deviation in bytes, and the deviation in milliseconds, - * respectively. - * - * @return Array - */ - public function getDeviation() { return $this->_deviation; } - - /** - * Sets the deviations array. The array must consist of arrays, each of which - * having two values, the deviation in bytes, and the deviation in - * milliseconds, respectively. - * - * @param Array $deviation The deviations array. - */ - public function setDeviation($deviation) { $this->_deviation = $deviation; } -} diff --git a/src/ID3/Frame/OWNE.php b/src/ID3/Frame/OWNE.php deleted file mode 100644 index 4af0048..0000000 --- a/src/ID3/Frame/OWNE.php +++ /dev/null @@ -1,238 +0,0 @@ -Ownership frame might be used as a reminder of a made transaction - * or, if signed, as proof. Note that the {@link ID3_Frame_USER} and - * {@link ID3_Frame_TOWN} frames are good to use in conjunction with this one. - * - * There may only be one OWNE frame in a tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_OWNE extends ID3_Frame - implements ID3_Encoding -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_currency = "EUR"; - - /** @var string */ - private $_price; - - /** @var string */ - private $_date; - - /** @var string */ - private $_seller; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - list($tmp, $this->_data) = - $this->_explodeString8(substr($this->_data, 1), 2); - $this->_currency = substr($tmp, 0, 3); - $this->_price = substr($tmp, 3); - $this->_date = substr($this->_data, 0, 8); - $this->_data = substr($this->_data, 8); - - switch ($encoding) { - case self::UTF16: - $this->_seller = $this->_convertString - (Transform::fromString16($this->_data), "utf-16"); - break; - case self::UTF16BE: - $this->_seller = $this->_convertString - (Transform::fromString16($this->_data), "utf-16be"); - break; - case self::UTF8: - $this->_seller = $this->_convertString - (Transform::fromString8($this->_data), "utf-8"); - break; - default: - $this->_seller = $this->_convertString - (Transform::fromString8($this->_data), "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the currency used in transaction, encoded according to - * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm - * ISO 4217} alphabetic currency code. - * - * @return string - */ - public function getCurrency() { return $this->_currency; } - - /** - * Sets the currency used in transaction, encoded according to - * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm - * ISO 4217} alphabetic currency code. - * - * @param string $currency The currency code. - */ - public function setCurrency($currency) { $this->_currency = $currency; } - - /** - * Returns the price as a numerical string using "." as the decimal separator. - * - * @return string - */ - public function getPrice() { return $this->_price; } - - /** - * Sets the price. - * - * @param integer $price The price. - */ - public function setPrice($price) - { - $this->_price = number_format($price, 2, ".", ""); - } - - /** - * Returns the date of purchase as an 8 character date string (YYYYMMDD). - * - * @return string - */ - public function getDate() { return $this->_date; } - - /** - * Sets the date of purchase. The date must be an 8 character date string - * (YYYYMMDD). - * - * @param string $date The date string. - */ - public function setDate($date) { $this->_date = $date; } - - /** - * Returns the name of the seller. - * - * @return string - */ - public function getSeller() { return $this->_seller; } - - /** - * Sets the name of the seller using given encoding. - * - * @param string $seller The name of the seller. - * @param integer $encoding The text encoding. - */ - public function setSeller($seller, $encoding = false) - { - $this->_seller = $seller; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_currency . - $this->_price . "\0" . $this->_date; - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_seller, Transform::LITTLE_ENDIAN_ORDER); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_seller); - break; - default: - $data .= Transform::toString8($this->_seller); - } - return $data; - } -} diff --git a/src/ID3/Frame/PCNT.php b/src/ID3/Frame/PCNT.php deleted file mode 100644 index 233412f..0000000 --- a/src/ID3/Frame/PCNT.php +++ /dev/null @@ -1,111 +0,0 @@ -Play counter is simply a counter of the number of times a file has - * been played. The value is increased by one every time the file begins to - * play. There may only be one PCNT frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_PCNT extends ID3_Frame -{ - /** @var integer */ - private $_counter = 0; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - if (strlen($this->_data) > 4) - $this->_counter = Transform::fromInt64BE($this->_data); // UInt64 - else - $this->_counter = Transform::fromUInt32BE($this->_data); - } - - /** - * Returns the counter. - * - * @return integer - */ - public function getCounter() { return $this->_counter; } - - /** - * Adds counter by one. - */ - public function addCounter() { $this->_counter++; } - - /** - * Sets the counter value. - * - * @param integer $counter The counter value. - */ - public function setCounter($counter) { $this->_counter = $counter; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - $this->_counter > 4294967295 ? - Transform::toInt64BE($this->_counter) : // UInt64 - Transform::toUInt32BE($this->_counter); - } -} diff --git a/src/ID3/Frame/POPM.php b/src/ID3/Frame/POPM.php deleted file mode 100644 index b182a7b..0000000 --- a/src/ID3/Frame/POPM.php +++ /dev/null @@ -1,161 +0,0 @@ -Popularimeter frame is to specify how good an audio - * file is. Many interesting applications could be found to this frame such as a - * playlist that features better audio files more often than others or it could - * be used to profile a person's taste and find other good files by comparing - * people's profiles. The frame contains the email address to the user, one - * rating byte and a four byte play counter, intended to be increased with one - * for every time the file is played. - * - * The rating is 1-255 where 1 is worst and 255 is best. 0 is unknown. If no - * personal counter is wanted it may be omitted. When the counter reaches all - * one's, one byte is inserted in front of the counter thus making the counter - * eight bits bigger in the same away as the play counter - * {@link ID3_Frame_PCNT}. There may be more than one POPM frame in each tag, - * but only one with the same email address. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_POPM extends ID3_Frame -{ - /** @var string */ - private $_owner; - - /** @var integer */ - private $_rating = 0; - - /** @var integer */ - private $_counter = 0; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list($this->_owner, $this->_data) = $this->_explodeString8($this->_data, 2); - $this->_rating = Transform::fromUInt8($this->_data[0]); - $this->_data = substr($this->_data, 1); - - if (strlen($this->_data) > 4) - $this->_counter = Transform::fromInt64BE($this->_data); // UInt64 - else if (strlen($this->_data) > 0) - $this->_counter = Transform::fromUInt32BE($this->_data); - } - - /** - * Returns the owner identifier string. - * - * @return string - */ - public function getOwner() { return $this->_owner; } - - /** - * Sets the owner identifier string. - * - * @param string $owner The owner identifier string. - */ - public function setOwner($owner) { return $this->_owner = $owner; } - - /** - * Returns the user rating. - * - * @return integer - */ - public function getRating() { return $this->_rating; } - - /** - * Sets the user rating. - * - * @param integer $rating The user rating. - */ - public function setRating($rating) { $this->_rating = $rating; } - - /** - * Returns the counter. - * - * @return integer - */ - public function getCounter() { return $this->_counter; } - - /** - * Adds counter by one. - */ - public function addCounter() { $this->_counter++; } - - /** - * Sets the counter value. - * - * @param integer $counter The counter value. - */ - public function setCounter($counter) { $this->_counter = $counter; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - $this->_owner . "\0" . Transform::toInt8($this->_rating) . - ($this->_counter > 0xffffffff ? - Transform::toInt64BE($this->_counter) : - ($this->_counter > 0 ? Transform::toUInt32BE($this->_counter) : 0)); - } -} diff --git a/src/ID3/Frame/POSS.php b/src/ID3/Frame/POSS.php deleted file mode 100644 index 5b0f67a..0000000 --- a/src/ID3/Frame/POSS.php +++ /dev/null @@ -1,132 +0,0 @@ -Position synchronisation frame delivers information to the - * listener of how far into the audio stream he picked up; in effect, it states - * the time offset from the first frame in the stream. There may only be one - * POSS frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_POSS extends ID3_Frame - implements ID3_Timing -{ - /** @var integer */ - private $_format = ID3_Timing::MPEG_FRAMES; - - /** @var integer */ - private $_position; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_format = Transform::fromUInt8($this->_data[0]); - $this->_position = Transform::fromUInt32BE(substr($this->_data, 1, 4)); - } - - /** - * Returns the timing format. - * - * @return integer - */ - public function getFormat() { return $this->_format; } - - /** - * Sets the timing format. - * - * @see ID3_Timing - * @param integer $format The timing format. - */ - public function setFormat($format) { $this->_format = $format; } - - /** - * Returns the position where in the audio the listener starts to receive, - * i.e. the beginning of the next frame. - * - * @return integer - */ - public function getPosition() { return $this->_position; } - - /** - * Sets the position where in the audio the listener starts to receive, - * i.e. the beginning of the next frame, using given format. - * - * @param integer $position The position. - * @param integer $format The timing format. - */ - public function setPosition($position, $format = false) - { - $this->_position = $position; - if ($format !== false) - $this->_format = $format; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - Transform::toUInt8($this->_format) . - Transform::toUInt32BE($this->_position); - } -} diff --git a/src/ID3/Frame/PRIV.php b/src/ID3/Frame/PRIV.php deleted file mode 100644 index e340591..0000000 --- a/src/ID3/Frame/PRIV.php +++ /dev/null @@ -1,126 +0,0 @@ -Private frame is used to contain information from a software - * producer that its program uses and does not fit into the other frames. The - * frame consists of an owner identifier string and the binary data. The owner - * identifier is URL containing an email address, or a link to a location where - * an email address can be found, that belongs to the organisation responsible - * for the frame. Questions regarding the frame should be sent to the indicated - * email address. The tag may contain more than one PRIV frame but only with - * different contents. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_PRIV extends ID3_Frame -{ - /** @var string */ - private $_owner; - - /** @var string */ - private $_privateData; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list($this->_owner, $this->_privateData) = - $this->_explodeString8($this->_data, 2); - } - - /** - * Returns the owner identifier string. - * - * @return string - */ - public function getOwner() { return $this->_owner; } - - /** - * Sets the owner identifier string. - * - * @param string $owner The owner identifier string. - */ - public function setOwner($owner) { $this->_owner = $owner; } - - /** - * Returns the private binary data associated with the frame. - * - * @return string - */ - public function getPrivateData() { return $this->_privateData; } - - /** - * Sets the private binary data associated with the frame. - * - * @param string $privateData The private binary data string. - */ - public function setPrivateData($privateData) - { - $this->_privateData = $privateData; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return $this->_owner . "\0" . $this->_privateData; - } -} diff --git a/src/ID3/Frame/RBUF.php b/src/ID3/Frame/RBUF.php deleted file mode 100644 index 87095bf..0000000 --- a/src/ID3/Frame/RBUF.php +++ /dev/null @@ -1,181 +0,0 @@ -Recommended buffer size frame. If the embedded info - * flag is set then this indicates that an ID3 tag with the maximum size - * described in buffer size may occur in the audio stream. In such case the tag - * should reside between two MPEG frames, if the audio is MPEG encoded. If the - * position of the next tag is known, offset to next tag may be used. The offset - * is calculated from the end of tag in which this frame resides to the first - * byte of the header in the next. This field may be omitted. Embedded tags are - * generally not recommended since this could render unpredictable behaviour - * from present software/hardware. - * - * For applications like streaming audio it might be an idea to embed tags into - * the audio stream though. If the clients connects to individual connections - * like HTTP and there is a possibility to begin every transmission with a tag, - * then this tag should include a recommended buffer size frame. If the client - * is connected to a arbitrary point in the stream, such as radio or multicast, - * then the recommended buffer size frame should be included in every tag. - * - * The buffer size should be kept to a minimum. There may only be one RBUF - * frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_RBUF extends ID3_Frame -{ - /** - * A flag to denote that an ID3 tag with the maximum size described in buffer - * size may occur in the audio stream. - */ - const EMBEDDED = 0x1; - - /** @var integer */ - private $_bufferSize; - - /** @var integer */ - private $_infoFlags; - - /** @var integer */ - private $_offset = 0; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_bufferSize = - Transform::fromUInt32BE("\0" . substr($this->_data, 0, 3)); - $this->_infoFlags = Transform::fromInt8($this->_data[3]); - if ($this->getSize() > 4) - $this->_offset = Transform::fromInt32BE(substr($this->_data, 4, 4)); - } - - /** - * Returns the buffer size. - * - * @return integer - */ - public function getBufferSize() { return $this->_bufferSize; } - - /** - * Sets the buffer size. - * - * @param integer $size The buffer size. - */ - public function setBufferSize($bufferSize) - { - $this->_bufferSize = $bufferSize; - } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasInfoFlag($flag) - { - return ($this->_infoFlags & $flag) == $flag; - } - - /** - * Returns the flags byte. - * - * @return integer - */ - public function getInfoFlags() { return $this->_infoFlags; } - - /** - * Sets the flags byte. - * - * @param string $flags The flags byte. - */ - public function setInfoFlags($infoFlags) { $this->_infoFlags = $infoFlags; } - - /** - * Returns the offset to next tag. - * - * @return integer - */ - public function getOffset() { return $this->_offset; } - - /** - * Sets the offset to next tag. - * - * @param integer $offset The offset. - */ - public function setOffset($offset) { $this->_offset = $offset; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - substr(Transform::toUInt32BE($this->_bufferSize), 1, 3) . - Transform::toInt8($this->_infoFlags) . - Transform::toInt32BE($this->_offset); - } -} diff --git a/src/ID3/Frame/RVA2.php b/src/ID3/Frame/RVA2.php deleted file mode 100644 index f54dda1..0000000 --- a/src/ID3/Frame/RVA2.php +++ /dev/null @@ -1,217 +0,0 @@ -Relative volume adjustment (2) frame is a more subjective frame than - * the previous ones. It allows the user to say how much he wants to - * increase/decrease the volume on each channel when the file is played. The - * purpose is to be able to align all files to a reference volume, so that you - * don't have to change the volume constantly. This frame may also be used to - * balance adjust the audio. The volume adjustment is encoded as a fixed point - * decibel value, 16 bit signed integer representing (adjustment*512), giving - * +/- 64 dB with a precision of 0.001953125 dB. E.g. +2 dB is stored as $04 00 - * and -2 dB is $FC 00. - * - * There may be more than one RVA2 frame in each tag, but only one with the same - * identification string. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_RVA2 extends ID3_Frame -{ - /** - * The channel type key. - * - * @see $types - * @var string - */ - const channelType = "channelType"; - - /** - * The volume adjustment key. Adjustments are +/- 64 dB with a precision of - * 0.001953125 dB. - * - * @var string - */ - const volumeAdjustment = "volumeAdjustment"; - - /** - * The peak volume key. - * - * @var string - */ - const peakVolume = "peakVolume"; - - /** - * The list of channel types. - * - * @var Array - */ - public static $types = array - ("Other", "Master volume", "Front right", "Front left", "Back right", - "Back left", "Front centre", "Back centre", "Subwoofer"); - - /** @var string */ - private $_device; - - /** @var Array */ - private $_adjustments; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - list ($this->_device, $this->_data) = - $this->_explodeString8($this->_data, 2); - - for ($i = $j = 0; $i < 9; $i++) { - $this->_adjustments[$i] = array - (self::channelType => Transform::fromInt8($this->_data[$j++]), - self::volumeAdjustment => - Transform::fromInt16BE(substr($this->_data, $j++, 2)) / 512.0); - $j++; - $bitsInPeak = Transform::fromInt8($this->_data[$j++]); - $bytesInPeak = $bitsInPeak > 0 ? ceil($bitsInPeak / 8) : 0; - switch ($bytesInPeak) { - case 8: - case 7: - case 6: - case 5: - $this->_adjustments[$i][self::peakVolume] = - Transform::fromInt64BE(substr($this->_data, $j, $bytesInPeak)); - break; - case 4: - case 3: - $this->_adjustments[$i][self::peakVolume] = - Transform::fromUInt32BE(substr($this->_data, $j, $bytesInPeak)); - break; - case 2: - $this->_adjustments[$i][self::peakVolume] = - Transform::fromUInt16BE(substr($this->_data, $j, $bytesInPeak)); - break; - case 1: - $this->_adjustments[$i][self::peakVolume] = - Transform::fromUInt8(substr($this->_data, $j, $bytesInPeak)); - } - $j += $bytesInPeak; - } - } - - /** - * Returns the device where the adjustments should apply. - * - * @return string - */ - public function getDevice() { return $this->_device; } - - /** - * Sets the device where the adjustments should apply. - * - * @param string $device The device. - */ - public function setDevice($device) { $this->_device = $device; } - - /** - * Returns the array containing volume adjustments for each channel. Volume - * adjustments are arrays themselves containing the following keys: - * channelType, volumeAdjustment, peakVolume. - * - * @return Array - */ - public function getAdjustments() { return $this->_adjustments; } - - /** - * Sets the array of volume adjustments for each channel. Each volume - * adjustment is an array too containing the following keys: channelType, - * volumeAdjustment, peakVolume. - * - * @param Array $adjustments The volume adjustments array. - */ - public function setAdjustments($adjustments) - { - $this->_adjustments = $adjustments; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = $this->_device . "\0"; - foreach ($this->_adjustments as $channel) { - $data .= Transform::toInt8($channel[self::channelType]) . - Transform::toInt16BE($channel[self::volumeAdjustment] * 512); - if (abs($channel[self::peakVolume]) <= 0xff) - $data .= Transform::toInt8(8) . - Transform::toUInt8($channel[self::peakVolume]); - else if (abs($channel[self::peakVolume]) <= 0xffff) - $data .= Transform::toInt8(16) . - Transform::toUInt16BE($channel[self::peakVolume]); - else if (abs($channel[self::peakVolume]) <= 0xffffffff) - $data .= Transform::toInt8(32) . - Transform::toUInt32BE($channel[self::peakVolume]); - else - $data .= Transform::toInt8(64) . - Transform::toInt64BE($channel[self::peakVolume]); // UInt64 - } - return $data; - } -} diff --git a/src/ID3/Frame/RVAD.php b/src/ID3/Frame/RVAD.php deleted file mode 100644 index 0e0d4e1..0000000 --- a/src/ID3/Frame/RVAD.php +++ /dev/null @@ -1,254 +0,0 @@ -Relative volume adjustment frame is a more subjective function - * than the previous ones. It allows the user to say how much he wants to - * increase/decrease the volume on each channel while the file is played. The - * purpose is to be able to align all files to a reference volume, so that you - * don't have to change the volume constantly. This frame may also be used to - * balance adjust the audio. - * - * There may only be one RVAD frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_RVAD extends ID3_Frame -{ - /* The required keys. */ - - /** @var string */ - const right = "right"; - - /** @var string */ - const left = "left"; - - /** @var string */ - const peakRight = "peakRight"; - - /** @var string */ - const peakLeft = "peakLeft"; - - /* The optional keys. */ - - /** @var string */ - const rightBack = "rightBack"; - - /** @var string */ - const leftBack = "leftBack"; - - /** @var string */ - const peakRightBack = "peakRightBack"; - - /** @var string */ - const peakLeftBack = "peakLeftBack"; - - /** @var string */ - const center = "center"; - - /** @var string */ - const peakCenter = "peakCenter"; - - /** @var string */ - const bass = "bass"; - - /** @var string */ - const peakBass = "peakBass"; - - /** @var Array */ - private $_adjustments; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $flags = Transform::fromInt8($this->_data[0]); - $descriptionBits = Transform::fromInt8($this->_data[1]); - if ($descriptionBits <= 8 || $descriptionBits > 16) { - require_once("ID3/Exception.php"); - throw new ID3_Exception - ("Unsupported description bit size of: " . $descriptionBits); - } - - $this->_adjustments[self::right] = - ($flags & 0x1) == 0x1 ? - Transform::fromUInt16BE(substr($this->_data, 2, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 2, 2)); - $this->_adjustments[self::left] = - ($flags & 0x2) == 0x2 ? - Transform::fromUInt16BE(substr($this->_data, 4, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 4, 2)); - $this->_adjustments[self::peakRight] = - Transform::fromUInt16BE(substr($this->_data, 6, 2)); - $this->_adjustments[self::peakLeft] = - Transform::fromUInt16BE(substr($this->_data, 8, 2)); - - if ($this->getSize() <= 10) - return; - - $this->_adjustments[self::rightBack] = - ($flags & 0x4) == 0x4 ? - Transform::fromUInt16BE(substr($this->_data, 10, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 10, 2)); - $this->_adjustments[self::leftBack] = - ($flags & 0x8) == 0x8 ? - Transform::fromUInt16BE(substr($this->_data, 12, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 12, 2)); - $this->_adjustments[self::peakRightBack] = - Transform::fromUInt16BE(substr($this->_data, 14, 2)); - $this->_adjustments[self::peakLeftBack] = - Transform::fromUInt16BE(substr($this->_data, 16, 2)); - - if ($this->getSize() <= 18) - return; - - $this->_adjustments[self::center] = - ($flags & 0x10) == 0x10 ? - Transform::fromUInt16BE(substr($this->_data, 18, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 18, 2)); - $this->_adjustments[self::peakCenter] = - Transform::fromUInt16BE(substr($this->_data, 20, 2)); - - if ($this->getSize() <= 22) - return; - - $this->_adjustments[self::bass] = - ($flags & 0x20) == 0x20 ? - Transform::fromUInt16BE(substr($this->_data, 22, 2)) : - -Transform::fromUInt16BE(substr($this->_data, 22, 2)); - $this->_adjustments[self::peakBass] = - Transform::fromUInt16BE(substr($this->_data, 24, 2)); - } - - /** - * Returns the array containing the volume adjustments. The array must contain - * the following keys: right, left, peakRight, peakLeft. It may optionally - * contain the following keys: rightBack, leftBack, peakRightBack, - * peakLeftBack, center, peakCenter, bass, and peakBass. - * - * @return Array - */ - public function getAdjustments() { return $this->_adjustments; } - - /** - * Sets the array of volume adjustments. The array must contain the following - * keys: right, left, peakRight, peakLeft. It may optionally contain the - * following keys: rightBack, leftBack, peakRightBack, peakLeftBack, center, - * peakCenter, bass, and peakBass. - * - * @param Array $adjustments The volume adjustments array. - */ - public function setAdjustments($adjustments) - { - $this->_adjustments = $adjustments; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $flags = 0; - if ($this->_adjustments[self::right] > 0) - $flags = $flags | 0x1; - if ($this->_adjustments[self::left] > 0) - $flags = $flags | 0x2; - $data = Transform::toInt8(16) . - Transform::toUInt16BE(abs($this->_adjustments[self::right])) . - Transform::toUInt16BE(abs($this->_adjustments[self::left])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakRight])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakLeft])); - - if (isset($this->_adjustments[self::rightBack]) && - isset($this->_adjustments[self::leftBack]) && - isset($this->_adjustments[self::peakRightBack]) && - isset($this->_adjustments[self::peakLeftBack])) { - if ($this->_adjustments[self::rightBack] > 0) - $flags = $flags | 0x4; - if ($this->_adjustments[self::leftBack] > 0) - $flags = $flags | 0x8; - $data .= - Transform::toUInt16BE(abs($this->_adjustments[self::rightBack])) . - Transform::toUInt16BE(abs($this->_adjustments[self::leftBack])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakRightBack])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakLeftBack])); - } - - if (isset($this->_adjustments[self::center]) && - isset($this->_adjustments[self::peakCenter])) { - if ($this->_adjustments[self::center] > 0) - $flags = $flags | 0x10; - $data .= - Transform::toUInt16BE(abs($this->_adjustments[self::center])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakCenter])); - } - - if (isset($this->_adjustments[self::bass]) && - isset($this->_adjustments[self::peakBass])) { - if ($this->_adjustments[self::bass] > 0) - $flags = $flags | 0x20; - $data .= - Transform::toUInt16BE(abs($this->_adjustments[self::bass])) . - Transform::toUInt16BE(abs($this->_adjustments[self::peakBass])); - } - return Transform::toInt8($flags) . $data; - } -} diff --git a/src/ID3/Frame/RVRB.php b/src/ID3/Frame/RVRB.php deleted file mode 100644 index 3443c6d..0000000 --- a/src/ID3/Frame/RVRB.php +++ /dev/null @@ -1,314 +0,0 @@ -Reverb is yet another subjective frame, with which you can adjust - * echoes of different kinds. Reverb left/right is the delay between every - * bounce in milliseconds. Reverb bounces left/right is the number of bounces - * that should be made. $FF equals an infinite number of bounces. Feedback is - * the amount of volume that should be returned to the next echo bounce. $00 is - * 0%, $FF is 100%. If this value were $7F, there would be 50% volume reduction - * on the first bounce, 50% of that on the second and so on. Left to left means - * the sound from the left bounce to be played in the left speaker, while left - * to right means sound from the left bounce to be played in the right speaker. - * - * Premix left to right is the amount of left sound to be mixed in the right - * before any reverb is applied, where $00 id 0% and $FF is 100%. Premix right - * to left does the same thing, but right to left. Setting both premix to $FF - * would result in a mono output (if the reverb is applied symmetric). There may - * only be one RVRB frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_RVRB extends ID3_Frame -{ - /** @var integer */ - private $_reverbLeft; - - /** @var integer */ - private $_reverbRight; - - /** @var integer */ - private $_reverbBouncesLeft; - - /** @var integer */ - private $_reverbBouncesRight; - - /** @var integer */ - private $_reverbFeedbackLtoL; - - /** @var integer */ - private $_reverbFeedbackLtoR; - - /** @var integer */ - private $_reverbFeedbackRtoR; - - /** @var integer */ - private $_reverbFeedbackRtoL; - - /** @var integer */ - private $_premixLtoR; - - /** @var integer */ - private $_premixRtoL; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_reverbLeft = Transform::fromUInt16BE(substr($this->_data, 0, 2)); - $this->_reverbRight = Transform::fromUInt16BE(substr($this->_data, 2, 2)); - $this->_reverbBouncesLeft = Transform::fromUInt8($this->_data[4]); - $this->_reverbBouncesRight = Transform::fromUInt8($this->_data[5]); - $this->_reverbFeedbackLtoL = Transform::fromUInt8($this->_data[6]); - $this->_reverbFeedbackLtoR = Transform::fromUInt8($this->_data[7]); - $this->_reverbFeedbackRtoR = Transform::fromUInt8($this->_data[8]); - $this->_reverbFeedbackRtoL = Transform::fromUInt8($this->_data[9]); - $this->_premixLtoR = Transform::fromUInt8($this->_data[10]); - $this->_premixRtoL = Transform::fromUInt8($this->_data[11]); - } - - /** - * Returns the left reverb. - * - * @return integer - */ - public function getReverbLeft() { return $this->_reverbLeft; } - - /** - * Sets the left reverb. - * - * @param integer $reverbLeft The left reverb. - */ - public function setReverbLeft($reverbLeft) - { - return $this->_reverbLeft = $reverbLeft; - } - - /** - * Returns the right reverb. - * - * @return integer - */ - public function getReverbRight() { return $this->_reverbRight; } - - /** - * Sets the right reverb. - * - * @param integer $reverbRight The right reverb. - */ - public function setReverbRight($reverbRight) - { - return $this->_reverbRight = $reverbRight; - } - - /** - * Returns the left reverb bounces. - * - * @return integer - */ - public function getReverbBouncesLeft() { return $this->_reverbBouncesLeft; } - - /** - * Sets the left reverb bounces. - * - * @param integer $reverbBouncesLeft The left reverb bounces. - */ - public function setReverbBouncesLeft($reverbBouncesLeft) - { - $this->_reverbBouncesLeft = $reverbBouncesLeft; - } - - /** - * Returns the right reverb bounces. - * - * @return integer - */ - public function getReverbBouncesRight() { return $this->_reverbBouncesRight; } - - /** - * Sets the right reverb bounces. - * - * @param integer $reverbBouncesRight The right reverb bounces. - */ - public function setReverbBouncesRight($reverbBouncesRight) - { - $this->_reverbBouncesRight = $reverbBouncesRight; - } - - /** - * Returns the left-to-left reverb feedback. - * - * @return integer - */ - public function getReverbFeedbackLtoL() { return $this->_reverbFeedbackLtoL; } - - /** - * Sets the left-to-left reverb feedback. - * - * @param integer $reverbFeedbackLtoL The left-to-left reverb feedback. - */ - public function setReverbFeedbackLtoL($reverbFeedbackLtoL) - { - $this->_reverbFeedbackLtoL = $reverbFeedbackLtoL; - } - - /** - * Returns the left-to-right reverb feedback. - * - * @return integer - */ - public function getReverbFeedbackLtoR() { return $this->_reverbFeedbackLtoR; } - - /** - * Sets the left-to-right reverb feedback. - * - * @param integer $reverbFeedbackLtoR The left-to-right reverb feedback. - */ - public function setReverbFeedbackLtoR($reverbFeedbackLtoR) - { - $this->_reverbFeedbackLtoR = $reverbFeedbackLtoR; - } - - /** - * Returns the right-to-right reverb feedback. - * - * @return integer - */ - public function getReverbFeedbackRtoR() { return $this->_reverbFeedbackRtoR; } - - /** - * Sets the right-to-right reverb feedback. - * - * @param integer $reverbFeedbackRtoR The right-to-right reverb feedback. - */ - public function setReverbFeedbackRtoR($reverbFeedbackRtoR) - { - $this->_reverbFeedbackRtoR = $reverbFeedbackRtoR; - } - - /** - * Returns the right-to-left reverb feedback. - * - * @return integer - */ - public function getReverbFeedbackRtoL() { return $this->_reverbFeedbackRtoL; } - - /** - * Sets the right-to-left reverb feedback. - * - * @param integer $reverbFeedbackRtoL The right-to-left reverb feedback. - */ - public function setReverbFeedbackRtoL($reverbFeedbackRtoL) - { - $this->_reverbFeedbackRtoL = $reverbFeedbackRtoL; - } - - /** - * Returns the left-to-right premix. - * - * @return integer - */ - public function getPremixLtoR() { return $this->_premixLtoR; } - - /** - * Sets the left-to-right premix. - * - * @param integer $premixLtoR The left-to-right premix. - */ - public function setPremixLtoR($premixLtoR) - { - $this->_premixLtoR = $premixLtoR; - } - - /** - * Returns the right-to-left premix. - * - * @return integer - */ - public function getPremixRtoL() { return $this->_premixRtoL; } - - /** - * Sets the right-to-left premix. - * - * @param integer $premixRtoL The right-to-left premix. - */ - public function setPremixRtoL($premixRtoL) - { - $this->_premixRtoL = $premixRtoL; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return - Transform::toUInt16BE($this->_reverbLeft) . - Transform::toUInt16BE($this->_reverbRight) . - Transform::toUInt8($this->_reverbBouncesLeft) . - Transform::toUInt8($this->_reverbBouncesRight) . - Transform::toUInt8($this->_reverbFeedbackLtoL) . - Transform::toUInt8($this->_reverbFeedbackLtoR) . - Transform::toUInt8($this->_reverbFeedbackRtoR) . - Transform::toUInt8($this->_reverbFeedbackRtoL) . - Transform::toUInt8($this->_premixLtoR) . - Transform::toUInt8($this->_premixRtoL); - } -} diff --git a/src/ID3/Frame/SEEK.php b/src/ID3/Frame/SEEK.php deleted file mode 100644 index 380be46..0000000 --- a/src/ID3/Frame/SEEK.php +++ /dev/null @@ -1,104 +0,0 @@ -Seek frame indicates where other tags in a file/stream can be - * found. The minimum offset to next tag is calculated from the end of this tag - * to the beginning of the next. There may only be one seek frame in a tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_SEEK extends ID3_Frame -{ - /** @var integer */ - private $_minOffset; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_minOffset = Transform::fromInt32BE($this->_data); - } - - /** - * Returns the minimum offset to next tag in bytes. - * - * @return integer - */ - public function getMinimumOffset() { return $this->_minOffset; } - - /** - * Sets the minimum offset to next tag in bytes. - * - * @param integer $minOffset The minimum offset. - */ - public function setMinimumOffset($minOffset) - { - $this->_minOffset = $minOffset; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return Transform::toInt32BE($this->_minOffset); - } -} diff --git a/src/ID3/Frame/SIGN.php b/src/ID3/Frame/SIGN.php deleted file mode 100644 index 9a14060..0000000 --- a/src/ID3/Frame/SIGN.php +++ /dev/null @@ -1,122 +0,0 @@ -Group identification registration, to be signed. Although signatures - * can reside inside the registration frame, it might be desired to store the - * signature elsewhere, e.g. in watermarks. There may be more than one signature - * frame in a tag, but no two may be identical. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_SIGN extends ID3_Frame -{ - /** @var integer */ - private $_group; - - /** @var string */ - private $_signature; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_group = Transform::fromUInt8(substr($this->_data, 0, 1)); - $this->_signature = substr($this->_data, 1); - } - - /** - * Returns the group symbol byte. - * - * @return integer - */ - public function getGroup() { return $this->_group; } - - /** - * Sets the group symbol byte. - * - * @param integer $group The group symbol byte. - */ - public function setGroup($group) { $this->_group = $group; } - - /** - * Returns the signature binary data. - * - * @return string - */ - public function getSignature() { return $this->_signature; } - - /** - * Sets the signature binary data. - * - * @param string $signature The signature binary data string. - */ - public function setSignature($signature) { $this->_signature = $signature; } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - return Transform::toUInt8($this->_group) . $this->_signature; - } -} diff --git a/src/ID3/Frame/SYLT.php b/src/ID3/Frame/SYLT.php deleted file mode 100644 index a92866c..0000000 --- a/src/ID3/Frame/SYLT.php +++ /dev/null @@ -1,340 +0,0 @@ -Synchronised lyrics/text frame is another way of incorporating the - * words, said or sung lyrics, in the audio file as text, this time, however, - * in sync with the audio. It might also be used to describing events e.g. - * occurring on a stage or on the screen in sync with the audio. - * - * There may be more than one SYLT frame in each tag, but only one with the - * same language and content descriptor. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_SYLT extends ID3_Frame - implements ID3_Encoding, ID3_Language, ID3_Timing -{ - /** - * The list of content types. - * - * @var Array - */ - public static $types = array - ("Other", "Lyrics", "Text transcription", "Movement/Part name", "Events", - "Chord", "Trivia", "URLs to webpages", "URLs to images"); - - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_language = "und"; - - /** @var integer */ - private $_format = ID3_Timing::MPEG_FRAMES; - - /** @var integer */ - private $_type = 0; - - /** @var string */ - private $_description; - - /** @var Array */ - private $_events = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_language = substr($this->_data, 1, 3); - if ($this->_language == "XXX") - $this->_language = "und"; - $this->_format = Transform::fromUInt8($this->_data[4]); - $this->_type = Transform::fromUInt8($this->_data[5]); - $this->_data = substr($this->_data, 6); - - switch ($encoding) { - case self::UTF16: - list($this->_description, $this->_data) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - break; - case self::UTF16BE: - list($this->_description, $this->_data) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - break; - case self::UTF8: - list($this->_description, $this->_data) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "utf-8"); - break; - default: - list($this->_description, $this->_data) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "iso-8859-1"); - } - - while (strlen($this->_data) > 0) { - switch ($encoding) { - case self::UTF16: - list($syllable, $this->_data) = - $this->_explodeString16($this->_data, 2); - $syllable = $this->_convertString - (Transform::fromString16($syllable), "utf-16"); - break; - case self::UTF16BE: - list($syllable, $this->_data) = - $this->_explodeString16($this->_data, 2); - $syllable = $this->_convertString - (Transform::fromString16($syllable), "utf-16be"); - break; - case self::UTF8: - list($syllable, $this->_data) = - $this->_explodeString8($this->_data, 2); - $syllable = $this->_convertString - (Transform::fromString8($syllable), "utf-8"); - break; - default: - list($syllable, $this->_data) = - $this->_explodeString8($this->_data, 2); - $syllable = $this->_convertString - (Transform::fromString8($syllable), "iso-8859-1"); - } - $this->_events[Transform::fromUInt32BE(substr($this->_data, 0, 4))] = - $syllable; - $this->_data = substr($this->_data, 4); - } - ksort($this->_events); - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @return string - */ - public function getLanguage() { return $this->_language; } - - /** - * Sets the text language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @see ID3_Language - * @param string $language The language code. - */ - public function setLanguage($language) - { - if ($language == "XXX") - $language = "und"; - $this->_language = substr($language, 0, 3); - } - - /** - * Returns the timing format. - * - * @return integer - */ - public function getFormat() { return $this->_format; } - - /** - * Sets the timing format. - * - * @see ID3_Timing - * @param integer $format The timing format. - */ - public function setFormat($format) { $this->_format = $format; } - - /** - * Returns the content type code. - * - * @return integer - */ - public function getType() { return $this->_type; } - - /** - * Sets the content type code. - * - * @param integer $type The content type code. - */ - public function setType($type) { $this->_type = $type; } - - /** - * Returns the content description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. The description - * language and encoding must be that of the actual text. - * - * @param string $description The content description text. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $language = false, - $encoding = false) - { - $this->_description = $description; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the syllable events with their timestamps. - * - * @return Array - */ - public function getEvents() { return $this->_events; } - - /** - * Sets the syllable events with their timestamps using given encoding. - * The text language and encoding must be that of the description text. - * - * @param Array $text The test string. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setEvents($events, $language = false, $encoding = false) - { - $this->_events = $events; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - ksort($this->_events); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_language . - Transform::toUInt8($this->_format) . Transform::toUInt8($this->_type); - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description, false, 1); - break; - default: - $data .= $this->_description . "\0"; - } - foreach ($this->_events as $timestamp => $syllable) { - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($syllable, Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($syllable, false, 1); - break; - default: - $data .= $syllable . "\0"; - } - $data .= Transform::toUInt32BE($timestamp); - } - return $data; - } -} diff --git a/src/ID3/Frame/SYTC.php b/src/ID3/Frame/SYTC.php deleted file mode 100644 index 1654593..0000000 --- a/src/ID3/Frame/SYTC.php +++ /dev/null @@ -1,161 +0,0 @@ -Synchronised tempo codes frame might be used. - * - * The tempo data consists of one or more tempo codes. Each tempo code consists - * of one tempo part and one time part. The tempo is in BPM described with one - * or two bytes. If the first byte has the value $FF, one more byte follows, - * which is added to the first giving a range from 2 - 510 BPM, since $00 and - * $01 is reserved. $00 is used to describe a beat-free time period, which is - * not the same as a music-free time period. $01 is used to indicate one single - * beat-stroke followed by a beat-free period. - * - * The tempo descriptor is followed by a time stamp. Every time the tempo in the - * music changes, a tempo descriptor may indicate this for the player. All tempo - * descriptors must be sorted in chronological order. The first beat-stroke in - * a time-period is at the same time as the beat description occurs. There may - * only be one SYTC frame in each tag. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_SYTC extends ID3_Frame - implements ID3_Timing -{ - /** Describes a beat-free time period. */ - const BEAT_FREE = 0x00; - - /** Indicate one single beat-stroke followed by a beat-free period. */ - const SINGLE_BEAT = 0x01; - - /** @var integer */ - private $_format = ID3_Timing::MPEG_FRAMES; - - /** @var Array */ - private $_events = array(); - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $offset = 0; - $this->_format = Transform::fromUInt8($this->_data[$offset++]); - while ($offset < strlen($this->_data)) { - $tempo = Transform::fromUInt8($this->_data[$offset++]); - if ($tempo == 0xff) - $tempo += Transform::fromUInt8($this->_data[$offset++]); - $this->_events - [Transform::fromUInt32BE(substr($this->_data, $offset, 4))] = $tempo; - $offset += 4; - } - ksort($this->_events); - } - - /** - * Returns the timing format. - * - * @return integer - */ - public function getFormat() { return $this->_format; } - - /** - * Sets the timing format. - * - * @see ID3_Timing - * @param integer $format The timing format. - */ - public function setFormat($format) { $this->_format = $format; } - - /** - * Returns the time-bpm tempo events. - * - * @return Array - */ - public function getEvents() { return $this->_events; } - - /** - * Sets the time-bpm tempo events. - * - * @param Array $events The time-bpm tempo events. - */ - public function setEvents($events) - { - $this->_events = $events; - ksort($this->_events); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_format); - foreach ($this->_events as $timestamp => $tempo) { - if ($tempo >= 0xff) - $data .= Transform::toUInt8(0xff) . Transform::toUInt8($tempo - 0xff); - else - $data .= Transform::toUInt8($tempo); - $data .= Transform::toUInt32BE($timestamp); - } - return $data; - } -} diff --git a/src/ID3/Frame/TALB.php b/src/ID3/Frame/TALB.php deleted file mode 100644 index 8a7492b..0000000 --- a/src/ID3/Frame/TALB.php +++ /dev/null @@ -1,53 +0,0 @@ -Album/Movie/Show title frame is intended for the title of the - * recording (or source of sound) from which the audio in the file is taken. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TALB extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TBPM.php b/src/ID3/Frame/TBPM.php deleted file mode 100644 index 442b680..0000000 --- a/src/ID3/Frame/TBPM.php +++ /dev/null @@ -1,53 +0,0 @@ -BPM frame contains the number of beats per minute in the main part - * of the audio. The BPM is an integer and represented as a numerical string. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TBPM extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCOM.php b/src/ID3/Frame/TCOM.php deleted file mode 100644 index c7f73ad..0000000 --- a/src/ID3/Frame/TCOM.php +++ /dev/null @@ -1,52 +0,0 @@ -Composer frame is intended for the name of the composer. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TCOM extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCON.php b/src/ID3/Frame/TCON.php deleted file mode 100644 index 28826e3..0000000 --- a/src/ID3/Frame/TCON.php +++ /dev/null @@ -1,62 +0,0 @@ -Content type, which ID3v1 was stored as a one byte numeric value - * only, is now a string. You may use one or several of the ID3v1 types as - * numerical strings, or, since the category list would be impossible to - * maintain with accurate and up to date categories, define your own. - * - * You may also use any of the following keywords: - * - *
- *  RX  Remix
- *  CR  Cover
- * 
- * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TCON extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TCOP.php b/src/ID3/Frame/TCOP.php deleted file mode 100644 index a389935..0000000 --- a/src/ID3/Frame/TCOP.php +++ /dev/null @@ -1,59 +0,0 @@ -Copyright message frame, in which the string must begin with a - * year and a space character (making five characters), is intended for the - * copyright holder of the original sound, not the audio file itself. The - * absence of this frame means only that the copyright information is - * unavailable or has been removed, and must not be interpreted to mean that the - * audio is public domain. Every time this field is displayed the field must be - * preceded with "Copyright " (C) " ", where (C) is one character showing a C in - * a circle. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TCOP extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDAT.php b/src/ID3/Frame/TDAT.php deleted file mode 100644 index 3f6be07..0000000 --- a/src/ID3/Frame/TDAT.php +++ /dev/null @@ -1,55 +0,0 @@ -Date frame is a numeric string in the DDMM format containing the - * date for the recording. This field is always four characters long. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TDAT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDEN.php b/src/ID3/Frame/TDEN.php deleted file mode 100644 index 4b21494..0000000 --- a/src/ID3/Frame/TDEN.php +++ /dev/null @@ -1,56 +0,0 @@ -Encoding time frame contains a timestamp describing when the audio - * was encoded. Timestamp format is described in the - * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TDEN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDLY.php b/src/ID3/Frame/TDLY.php deleted file mode 100644 index df52531..0000000 --- a/src/ID3/Frame/TDLY.php +++ /dev/null @@ -1,54 +0,0 @@ -Playlist delay defines the numbers of milliseconds of silence that - * should be inserted before this audio. The value zero indicates that this is a - * part of a multifile audio track that should be played continuously. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TDLY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDOR.php b/src/ID3/Frame/TDOR.php deleted file mode 100644 index 7e5a3e1..0000000 --- a/src/ID3/Frame/TDOR.php +++ /dev/null @@ -1,57 +0,0 @@ -Original release time frame contains a timestamp describing when - * the original recording of the audio was released. Timestamp format is - * described in the {@link http://www.id3.org/id3v2.4.0-structure ID3v2 - * structure document}. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TDOR extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDRC.php b/src/ID3/Frame/TDRC.php deleted file mode 100644 index 5d761e3..0000000 --- a/src/ID3/Frame/TDRC.php +++ /dev/null @@ -1,56 +0,0 @@ -Recording time frame contains a timestamp describing when the - * audio was recorded. Timestamp format is described in the - * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TDRC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDRL.php b/src/ID3/Frame/TDRL.php deleted file mode 100644 index 454490f..0000000 --- a/src/ID3/Frame/TDRL.php +++ /dev/null @@ -1,56 +0,0 @@ -Release time frame contains a timestamp describing when the audio - * was first released. Timestamp format is described in the - * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TDRL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TDTG.php b/src/ID3/Frame/TDTG.php deleted file mode 100644 index 17525fb..0000000 --- a/src/ID3/Frame/TDTG.php +++ /dev/null @@ -1,56 +0,0 @@ -Tagging time frame contains a timestamp describing then the audio - * was tagged. Timestamp format is described in the - * {@link http://www.id3.org/id3v2.4.0-structure ID3v2 structure document}. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TDTG extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TENC.php b/src/ID3/Frame/TENC.php deleted file mode 100644 index d3cbf27..0000000 --- a/src/ID3/Frame/TENC.php +++ /dev/null @@ -1,54 +0,0 @@ -Encoded by frame contains the name of the person or organisation - * that encoded the audio file. This field may contain a copyright message, if - * the audio file also is copyrighted by the encoder. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TENC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TEXT.php b/src/ID3/Frame/TEXT.php deleted file mode 100644 index bf632ab..0000000 --- a/src/ID3/Frame/TEXT.php +++ /dev/null @@ -1,53 +0,0 @@ -Lyricist/Text writer frame is intended for the writer of the text - * or lyrics in the recording. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TEXT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TFLT.php b/src/ID3/Frame/TFLT.php deleted file mode 100644 index f1e9a01..0000000 --- a/src/ID3/Frame/TFLT.php +++ /dev/null @@ -1,69 +0,0 @@ -File type frame indicates which type of audio this tag defines. - * The following types and refinements are defined: - * - *
- * MIME   MIME type follows
- *  MPG    MPEG Audio
- *    /1     MPEG 1/2 layer I
- *    /2     MPEG 1/2 layer II
- *    /3     MPEG 1/2 layer III
- *    /2.5   MPEG 2.5
- *    /AAC   Advanced audio compression
- *  VQF    Transform-domain Weighted Interleave Vector Quantisation
- *  PCM    Pulse Code Modulated audio
- * 
- * - * but other types may be used, but not for these types though. This is used in - * a similar way to the predefined types in the {@link ID3_Frame_TMED} - * frame. If this frame is not present audio type is assumed to be MPG. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TFLT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIME.php b/src/ID3/Frame/TIME.php deleted file mode 100644 index 713226c..0000000 --- a/src/ID3/Frame/TIME.php +++ /dev/null @@ -1,55 +0,0 @@ -Time frame is a numeric string in the HHMM format containing the - * time for the recording. This field is always four characters long. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TIME extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIPL.php b/src/ID3/Frame/TIPL.php deleted file mode 100644 index dfcadde..0000000 --- a/src/ID3/Frame/TIPL.php +++ /dev/null @@ -1,55 +0,0 @@ -Involved people list is very similar to the musician credits list, - * but maps between functions, like producer, and names. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TIPL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT1.php b/src/ID3/Frame/TIT1.php deleted file mode 100644 index 2f29e77..0000000 --- a/src/ID3/Frame/TIT1.php +++ /dev/null @@ -1,54 +0,0 @@ -Content group description frame is used if the sound belongs to a - * larger category of sounds/music. For example, classical music is often sorted - * in different musical sections (e.g. "Piano Concerto", "Weather - Hurricane"). - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TIT1 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT2.php b/src/ID3/Frame/TIT2.php deleted file mode 100644 index 384de2d..0000000 --- a/src/ID3/Frame/TIT2.php +++ /dev/null @@ -1,53 +0,0 @@ -Title/Songname/Content description frame is the actual name of the - * piece (e.g. "Adagio", "Hurricane Donna"). - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TIT2 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TIT3.php b/src/ID3/Frame/TIT3.php deleted file mode 100644 index c593da2..0000000 --- a/src/ID3/Frame/TIT3.php +++ /dev/null @@ -1,54 +0,0 @@ -Subtitle/Description refinement frame is used for information - * directly related to the contents title (e.g. "Op. 16" or "Performed live at - * Wembley"). - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TIT3 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TKEY.php b/src/ID3/Frame/TKEY.php deleted file mode 100644 index dd8d6c4..0000000 --- a/src/ID3/Frame/TKEY.php +++ /dev/null @@ -1,56 +0,0 @@ -Initial key frame contains the musical key in which the sound - * starts. It is represented as a string with a maximum length of three - * characters. The ground keys are represented with "A", "B", "C", "D", "E", "F" - * and "G" and halfkeys represented with "b" and "#". Minor is represented as - * "m", e.g. "Dbm" $00. Off key is represented with an "o" only. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TKEY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TLAN.php b/src/ID3/Frame/TLAN.php deleted file mode 100644 index 14fd104..0000000 --- a/src/ID3/Frame/TLAN.php +++ /dev/null @@ -1,57 +0,0 @@ -Language frame should contain the languages of the text or lyrics - * spoken or sung in the audio. The language is represented with three - * characters according to {@link http://www.loc.gov/standards/iso639-2/ - * ISO-639-2}. If more than one language is used in the text their language - * codes should follow according to the amount of their usage, e.g. - * "eng" $00 "sve" $00. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TLAN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TLEN.php b/src/ID3/Frame/TLEN.php deleted file mode 100644 index faf81c1..0000000 --- a/src/ID3/Frame/TLEN.php +++ /dev/null @@ -1,53 +0,0 @@ -Length frame contains the length of the audio file in - * milliseconds, represented as a numeric string. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TLEN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TMCL.php b/src/ID3/Frame/TMCL.php deleted file mode 100644 index ca75f48..0000000 --- a/src/ID3/Frame/TMCL.php +++ /dev/null @@ -1,56 +0,0 @@ -Musician credits list is intended as a mapping between instruments - * and the musician that played it. Every odd field is an instrument and every - * even is an artist or a comma delimited list of artists. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TMCL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TMOO.php b/src/ID3/Frame/TMOO.php deleted file mode 100644 index 72059e6..0000000 --- a/src/ID3/Frame/TMOO.php +++ /dev/null @@ -1,55 +0,0 @@ -Mood frame is intended to reflect the mood of the audio with a few - * keywords, e.g. "Romantic" or "Sad". - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TMOO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOAL.php b/src/ID3/Frame/TOAL.php deleted file mode 100644 index 144e09f..0000000 --- a/src/ID3/Frame/TOAL.php +++ /dev/null @@ -1,54 +0,0 @@ -Original album/movie/show title frame is intended for the title of - * the original recording (or source of sound), if for example the music in the - * file should be a cover of a previously released song. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TOAL extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOFN.php b/src/ID3/Frame/TOFN.php deleted file mode 100644 index 572a59d..0000000 --- a/src/ID3/Frame/TOFN.php +++ /dev/null @@ -1,54 +0,0 @@ -Original filename frame contains the preferred filename for the - * file, since some media doesn't allow the desired length of the filename. The - * filename is case sensitive and includes its suffix. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TOFN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOLY.php b/src/ID3/Frame/TOLY.php deleted file mode 100644 index a4d0eff..0000000 --- a/src/ID3/Frame/TOLY.php +++ /dev/null @@ -1,54 +0,0 @@ -Original lyricist/text writer frame is intended for the text - * writer of the original recording, if for example the music in the file should - * be a cover of a previously released song. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TOLY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOPE.php b/src/ID3/Frame/TOPE.php deleted file mode 100644 index b3d4fe6..0000000 --- a/src/ID3/Frame/TOPE.php +++ /dev/null @@ -1,54 +0,0 @@ -Original artist/performer frame is intended for the performer of - * the original recording, if for example the music in the file should be a - * cover of a previously released song. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TOPE extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TORY.php b/src/ID3/Frame/TORY.php deleted file mode 100644 index d273bd6..0000000 --- a/src/ID3/Frame/TORY.php +++ /dev/null @@ -1,57 +0,0 @@ -Original release year frame is intended for the year when the - * original recording, if for example the music in the file should be a cover of - * a previously released song, was released. The field is formatted as in the - * {@link ID3_Frame_TYER} frame. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TORY extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TOWN.php b/src/ID3/Frame/TOWN.php deleted file mode 100644 index 072f4b9..0000000 --- a/src/ID3/Frame/TOWN.php +++ /dev/null @@ -1,53 +0,0 @@ -File owner/licensee frame contains the name of the owner or - * licensee of the file and it's contents. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TOWN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE1.php b/src/ID3/Frame/TPE1.php deleted file mode 100644 index bd82147..0000000 --- a/src/ID3/Frame/TPE1.php +++ /dev/null @@ -1,53 +0,0 @@ -Lead artist/Lead performer/Soloist/Performing group is used for - * the main artist. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPE1 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE2.php b/src/ID3/Frame/TPE2.php deleted file mode 100644 index 0104db9..0000000 --- a/src/ID3/Frame/TPE2.php +++ /dev/null @@ -1,53 +0,0 @@ -Band/Orchestra/Accompaniment frame is used for additional - * information about the performers in the recording. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPE2 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE3.php b/src/ID3/Frame/TPE3.php deleted file mode 100644 index a1d172c..0000000 --- a/src/ID3/Frame/TPE3.php +++ /dev/null @@ -1,52 +0,0 @@ -Conductor frame is used for the name of the conductor. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPE3 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPE4.php b/src/ID3/Frame/TPE4.php deleted file mode 100644 index 6977164..0000000 --- a/src/ID3/Frame/TPE4.php +++ /dev/null @@ -1,54 +0,0 @@ -Interpreted, remixed, or otherwise modified by frame contains more - * information about the people behind a remix and similar interpretations of - * another existing piece. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPE4 extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPOS.php b/src/ID3/Frame/TPOS.php deleted file mode 100644 index 5fd1458..0000000 --- a/src/ID3/Frame/TPOS.php +++ /dev/null @@ -1,56 +0,0 @@ -Part of a set frame is a numeric string that describes which part - * of a set the audio came from. This frame is used if the source described in - * the {@link ID3_Frame_TALB} frame is divided into several mediums, e.g. - * a double CD. The value may be extended with a "/" character and a numeric - * string containing the total number of parts in the set. E.g. "1/2". - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPOS extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPRO.php b/src/ID3/Frame/TPRO.php deleted file mode 100644 index f4073f1..0000000 --- a/src/ID3/Frame/TPRO.php +++ /dev/null @@ -1,61 +0,0 @@ -Produced notice frame, in which the string must begin with a year - * and a space character (making five characters), is intended for the - * production copyright holder of the original sound, not the audio file itself. - * The absence of this frame means only that the production copyright - * information is unavailable or has been removed, and must not be interpreted - * to mean that the audio is public domain. Every time this field is displayed - * the field must be preceded with "Produced " (P) " ", where (P) is one - * character showing a P in a circle. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TPRO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TPUB.php b/src/ID3/Frame/TPUB.php deleted file mode 100644 index b54efdb..0000000 --- a/src/ID3/Frame/TPUB.php +++ /dev/null @@ -1,53 +0,0 @@ -Publisher frame simply contains the name of the label or - * publisher. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TPUB extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRCK.php b/src/ID3/Frame/TRCK.php deleted file mode 100644 index bffc7c6..0000000 --- a/src/ID3/Frame/TRCK.php +++ /dev/null @@ -1,55 +0,0 @@ -Track number/Position in set frame is a numeric string containing - * the order number of the audio-file on its original recording. This may be - * extended with a "/" character and a numeric string containing the total - * number of tracks/elements on the original recording. E.g. "4/9". - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TRCK extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRDA.php b/src/ID3/Frame/TRDA.php deleted file mode 100644 index 1911ed6..0000000 --- a/src/ID3/Frame/TRDA.php +++ /dev/null @@ -1,57 +0,0 @@ -Recording dates frame is intended to be used as complement to - * the {@link ID3_Frame_TYER}, {@link ID3_Frame_TDAT} and {@link ID3_Frame_TIME} - * frames. E.g. "4th-7th June, 12th June" in combination with the - * {@link ID3_Frame_TYER} frame. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TRDA extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRSN.php b/src/ID3/Frame/TRSN.php deleted file mode 100644 index e12c048..0000000 --- a/src/ID3/Frame/TRSN.php +++ /dev/null @@ -1,53 +0,0 @@ -Internet radio station name frame contains the name of the - * internet radio station from which the audio is streamed. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TRSN extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TRSO.php b/src/ID3/Frame/TRSO.php deleted file mode 100644 index 7d5a164..0000000 --- a/src/ID3/Frame/TRSO.php +++ /dev/null @@ -1,53 +0,0 @@ -Internet radio station owner frame contains the name of the owner - * of the internet radio station from which the audio is streamed. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TRSO extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSIZ.php b/src/ID3/Frame/TSIZ.php deleted file mode 100644 index d1551cd..0000000 --- a/src/ID3/Frame/TSIZ.php +++ /dev/null @@ -1,55 +0,0 @@ -Size frame contains the size of the audiofile in bytes, excluding - * the ID3v2 tag, represented as a numeric string. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TSIZ extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOA.php b/src/ID3/Frame/TSOA.php deleted file mode 100644 index 5e6942a..0000000 --- a/src/ID3/Frame/TSOA.php +++ /dev/null @@ -1,55 +0,0 @@ -Album sort order frame defines a string which should be used - * instead of the {@link ID3_Frame_TALB} album name frame for sorting purposes. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TSOA extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOP.php b/src/ID3/Frame/TSOP.php deleted file mode 100644 index 04f3523..0000000 --- a/src/ID3/Frame/TSOP.php +++ /dev/null @@ -1,55 +0,0 @@ -Performer sort order frame defines a string which should be used - * instead of the {@link ID3_Frame_TPE2} performer frame for sorting purposes. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TSOP extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSOT.php b/src/ID3/Frame/TSOT.php deleted file mode 100644 index 0fb1e82..0000000 --- a/src/ID3/Frame/TSOT.php +++ /dev/null @@ -1,55 +0,0 @@ -Title sort order frame defines a string which should be used - * instead of the {@link ID3_Frame_TIT2} title frame for sorting purposes. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TSOT extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSRC.php b/src/ID3/Frame/TSRC.php deleted file mode 100644 index 93f604a..0000000 --- a/src/ID3/Frame/TSRC.php +++ /dev/null @@ -1,53 +0,0 @@ -ISRC frame should contain the International Standard Recording - * Code (12 characters). - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_ISRC extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSSE.php b/src/ID3/Frame/TSSE.php deleted file mode 100644 index 9c1122b..0000000 --- a/src/ID3/Frame/TSSE.php +++ /dev/null @@ -1,54 +0,0 @@ -Software/Hardware and settings used for encoding frame includes - * the used audio encoder and its settings when the file was encoded. Hardware - * refers to hardware encoders, not the computer on which a program was run. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TSSE extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TSST.php b/src/ID3/Frame/TSST.php deleted file mode 100644 index c997ace..0000000 --- a/src/ID3/Frame/TSST.php +++ /dev/null @@ -1,55 +0,0 @@ -Set subtitle frame is intended for the subtitle of the part of a - * set this track belongs to. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since ID3v2.4.0 - */ -final class ID3_Frame_TSST extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/TXXX.php b/src/ID3/Frame/TXXX.php deleted file mode 100644 index 95ede88..0000000 --- a/src/ID3/Frame/TXXX.php +++ /dev/null @@ -1,159 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_TXXX extends ID3_Frame_AbstractText -{ - /** @var string */ - private $_description; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - ID3_Frame::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_data = substr($this->_data, 1); - - switch ($encoding) { - case self::UTF16: - list($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - $this->_text = $this->_convertString - (array(Transform::fromString16($this->_text)), "utf-16"); - break; - case self::UTF16BE: - list($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - $this->_text = $this->_convertString - (array(Transform::fromString16($this->_text)), "utf-16be"); - break; - case self::UTF8: - list($this->_description, $this->_text) = $this->_convertString - ($this->_explodeString8($this->_data, 2), "utf-8"); - $this->_text = array($this->_text); - break; - default: - list($this->_description, $this->_text) = $this->_convertString - ($this->_explodeString8($this->_data, 2), "iso-8859-1"); - $this->_text = array($this->_text); - } - } - - /** - * Returns the description text. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the description text using given encoding. - * - * @param string $description The content description text. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $encoding = false) - { - $this->_description = $description; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding); - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER, 1) . - Transform::toString16 - ($this->_text[0], Transform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description, false, 1) . - Transform::toString16($this->_text[0], false, 1); - break; - default: - $data .= $this->_description . "\0" . $this->_text[0]; - } - return $data; - } -} - diff --git a/src/ID3/Frame/TYER.php b/src/ID3/Frame/TYER.php deleted file mode 100644 index 350c33d..0000000 --- a/src/ID3/Frame/TYER.php +++ /dev/null @@ -1,55 +0,0 @@ -Year frame is a numeric string with a year of the recording. This - * frames is always four characters long (until the year 10000). - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @deprecated ID3v2.3.0 - */ -final class ID3_Frame_TYER extends ID3_Frame_AbstractText {} diff --git a/src/ID3/Frame/USER.php b/src/ID3/Frame/USER.php deleted file mode 100644 index ef365df..0000000 --- a/src/ID3/Frame/USER.php +++ /dev/null @@ -1,205 +0,0 @@ -Terms of use frame contains a brief description of the terms of - * use and ownership of the file. More detailed information concerning the legal - * terms might be available through the {@link ID3_Frame_WCOP} frame. Newlines - * are allowed in the text. There may be more than one Terms of use frames in a - * tag, but only one with the same language. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_USER extends ID3_Frame - implements ID3_Encoding, ID3_Language -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_language = "und"; - - /** @var string */ - private $_text; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_language = substr($this->_data, 1, 3); - if ($this->_language == "XXX") - $this->_language = "und"; - $this->_data = substr($this->_data, 4); - - switch ($encoding) { - case self::UTF16: - $this->_text = $this->_convertString - (Transform::fromString16($this->_data), "utf-16"); - break; - case self::UTF16BE: - $this->_text = $this->_convertString - (Transform::fromString16($this->_data), "utf-16be"); - break; - case self::UTF8: - $this->_text = $this->_convertString - (Transform::fromString8($this->_data), "utf-8"); - break; - default: - $this->_text = $this->_convertString - (Transform::fromString8($this->_data), "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @return string - */ - public function getLanguage() { return $this->_language; } - - /** - * Sets the text language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @see ID3_Language - * @param string $language The language code. - */ - public function setLanguage($language) - { - if ($language == "XXX") - $language = "und"; - $this->_language = substr($language, 0, 3); - } - - /** - * Returns the text. - * - * @return string - */ - public function getText() { return $this->_text; } - - /** - * Sets the text using given language and encoding. - * - * @param string $text The text. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setText($text, $language = false, $encoding = false) - { - $this->_text = $text; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_language; - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_text, Transform::MACHINE_ENDIAN_ORDER); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_text); - break; - default: - $data .= $this->_text; - } - return $data; - } -} diff --git a/src/ID3/Frame/USLT.php b/src/ID3/Frame/USLT.php deleted file mode 100644 index 33e2257..0000000 --- a/src/ID3/Frame/USLT.php +++ /dev/null @@ -1,251 +0,0 @@ -Unsynchronised lyrics/text transcription frame contains the lyrics - * of the song or a text transcription of other vocal activities. There may be - * more than one unsynchronised lyrics/text transcription frame in each tag, but - * only one with the same language and content descriptor. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_USLT extends ID3_Frame - implements ID3_Encoding, ID3_Language -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_language = "und"; - - /** @var string */ - private $_description; - - /** @var string */ - private $_text; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_language = substr($this->_data, 1, 3); - if ($this->_language == "XXX") - $this->_language = "und"; - $this->_data = substr($this->_data, 4); - - switch ($encoding) { - case self::UTF16: - list ($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - $this->_text = $this->_convertString - (Transform::fromString16($this->_text), "utf-16"); - break; - case self::UTF16BE: - list ($this->_description, $this->_text) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - $this->_text = $this->_convertString - (Transform::fromString16($this->_text), "utf-16be"); - break; - case self::UTF8: - list ($this->_description, $this->_text) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "utf-8"); - $this->_text = $this->_convertString - (Transform::fromString8($this->_text), "utf-8"); - break; - default: - list ($this->_description, $this->_text) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString8($this->_description), "iso-8859-1"); - $this->_text = $this->_convertString - (Transform::fromString8($this->_text), "iso-8859-1"); - } - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @return string - */ - public function getLanguage() { return $this->_language; } - - /** - * Sets the text language code as specified in the - * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. - * - * @see ID3_Language - * @param string $language The language code. - */ - public function setLanguage($language) - { - if ($language == "XXX") - $language = "und"; - $this->_language = substr($language, 0, 3); - } - - /** - * Returns the short content description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. The description - * language and encoding must be that of the actual text. - * - * @param string $description The content description text. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $language = false, - $encoding = false) - { - $this->_description = $description; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the lyrics/text. - * - * @return string - */ - public function getText() { return $this->_text; } - - /** - * Sets the text using given encoding. The text language and encoding must be - * that of the description text. - * - * @param mixed $text The test string. - * @param string $language The language code. - * @param integer $encoding The text encoding. - */ - public function setText($text, $language = false, $encoding = false) - { - $this->_text = $text; - if ($language !== false) - $this->setLanguage($language); - if ($encoding !== false) - $this->setEncoding($encoding); - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding) . $this->_language; - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Transform::LITTLE_ENDIAN_ORDER) . "\0\0" . - Transform::toString16($this->_text, Transform::LITTLE_ENDIAN_ORDER); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description) . "\0\0" . - Transform::toString16($this->_text); - break; - default: - $data .= $this->_description . "\0" . $this->_text; - } - return $data; - } -} diff --git a/src/ID3/Frame/Unknown.php b/src/ID3/Frame/Unknown.php deleted file mode 100644 index d3c6b27..0000000 --- a/src/ID3/Frame/Unknown.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright Copyright (c) 2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_Unknown extends ID3_Frame -{ - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() { return $this->_data; } -} diff --git a/src/ID3/Frame/WCOM.php b/src/ID3/Frame/WCOM.php deleted file mode 100644 index d976f29..0000000 --- a/src/ID3/Frame/WCOM.php +++ /dev/null @@ -1,54 +0,0 @@ -Commercial information frame is a URL pointing at a webpage with - * information such as where the album can be bought. There may be more than one - * WCOM frame in a tag, but not with the same content. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WCOM extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WCOP.php b/src/ID3/Frame/WCOP.php deleted file mode 100644 index 0115a32..0000000 --- a/src/ID3/Frame/WCOP.php +++ /dev/null @@ -1,53 +0,0 @@ -Copyright/Legal information frame is a URL pointing at a webpage - * where the terms of use and ownership of the file is described. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WCOP extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAF.php b/src/ID3/Frame/WOAF.php deleted file mode 100644 index 50df02a..0000000 --- a/src/ID3/Frame/WOAF.php +++ /dev/null @@ -1,53 +0,0 @@ -Official audio file webpage frame is a URL pointing at a file - * specific webpage. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WOAF extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAR.php b/src/ID3/Frame/WOAR.php deleted file mode 100644 index ec32302..0000000 --- a/src/ID3/Frame/WOAR.php +++ /dev/null @@ -1,54 +0,0 @@ -Official artist/performer webpage frame is a URL pointing at the - * artists official webpage. There may be more than one WOAR frame in a tag if - * the audio contains more than one performer, but not with the same content. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WOAR extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WOAS.php b/src/ID3/Frame/WOAS.php deleted file mode 100644 index 7961bea..0000000 --- a/src/ID3/Frame/WOAS.php +++ /dev/null @@ -1,53 +0,0 @@ -Official audio source webpage frame is a URL pointing at the - * official webpage for the source of the audio file, e.g. a movie. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WOAS extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WORS.php b/src/ID3/Frame/WORS.php deleted file mode 100644 index 1ea09a8..0000000 --- a/src/ID3/Frame/WORS.php +++ /dev/null @@ -1,53 +0,0 @@ -Official Internet radio station homepage contains a URL pointing - * at the homepage of the internet radio station. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WORS extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WPAY.php b/src/ID3/Frame/WPAY.php deleted file mode 100644 index 1c724da..0000000 --- a/src/ID3/Frame/WPAY.php +++ /dev/null @@ -1,53 +0,0 @@ -Payment frame is a URL pointing at a webpage that will handle the - * process of paying for this file. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WPAY extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WPUB.php b/src/ID3/Frame/WPUB.php deleted file mode 100644 index d5461b6..0000000 --- a/src/ID3/Frame/WPUB.php +++ /dev/null @@ -1,53 +0,0 @@ -Publishers official webpage frame is a URL pointing at the - * official webpage for the publisher. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WPUB extends ID3_Frame_AbstractLink {} diff --git a/src/ID3/Frame/WXXX.php b/src/ID3/Frame/WXXX.php deleted file mode 100644 index e758079..0000000 --- a/src/ID3/Frame/WXXX.php +++ /dev/null @@ -1,181 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Frame_WXXX extends ID3_Frame_AbstractLink - implements ID3_Encoding -{ - /** @var integer */ - private $_encoding; - - /** @var string */ - private $_description; - - /** - * Constructs the class with given parameters and parses object related data. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - ID3_Frame::__construct($reader, $options); - - $this->_encoding = $this->getOption("encoding", ID3_Encoding::UTF8); - - if ($reader === null) - return; - - $encoding = Transform::fromUInt8($this->_data[0]); - $this->_data = substr($this->_data, 1); - - switch ($encoding) { - case self::UTF16: - list($this->_description, $this->_link) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16"); - break; - case self::UTF16BE: - list($this->_description, $this->_link) = - $this->_explodeString16($this->_data, 2); - $this->_description = $this->_convertString - (Transform::fromString16($this->_description), "utf-16be"); - break; - case self::UTF8: - list($this->_description, $this->_link) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString($this->_description, "utf-8"); - break; - default: - list($this->_description, $this->_link) = - $this->_explodeString8($this->_data, 2); - $this->_description = $this->_convertString - ($this->_description, "iso-8859-1"); - } - $this->_link = implode($this->_explodeString8($this->_link, 1), ""); - } - - /** - * Returns the text encoding. - * - * All the strings read from a file are automatically converted to the - * character encoding specified with the encoding option. See - * {@link ID3v2} for details. This method returns the original text encoding - * used to write the frame. - * - * @return integer The encoding. - */ - public function getEncoding() { return $this->_encoding; } - - /** - * Sets the text encoding. - * - * All the string written to the frame are done so using given character - * encoding. No conversions of existing data take place upon the call to this - * method thus all texts must be given in given character encoding. - * - * The default character encoding used to write the frame is UTF-8. - * - * @see ID3_Encoding - * @param integer $encoding The text encoding. - */ - public function setEncoding($encoding) { $this->_encoding = $encoding; } - - /** - * Returns the link description. - * - * @return string - */ - public function getDescription() { return $this->_description; } - - /** - * Sets the content description text using given encoding. - * - * @param string $description The content description text. - * @param integer $encoding The text encoding. - */ - public function setDescription($description, $encoding = false) - { - $this->_description = $description; - if ($encoding !== false) - $this->_encoding = $encoding; - } - - /** - * Returns the frame raw data without the header. - * - * @return string - */ - protected function _getData() - { - $data = Transform::toUInt8($this->_encoding); - switch ($this->_encoding) { - case self::UTF16LE: - $data .= Transform::toString16 - ($this->_description, Tranform::LITTLE_ENDIAN_ORDER, 1); - break; - case self::UTF16: - case self::UTF16BE: - $data .= Transform::toString16($this->_description, false, 1); - break; - default: - $data .= Transform::toString8($this->_description, 1); - } - return $data . $this->_link; - } -} diff --git a/src/ID3/Header.php b/src/ID3/Header.php deleted file mode 100644 index cd8c5e6..0000000 --- a/src/ID3/Header.php +++ /dev/null @@ -1,174 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3_Header extends ID3_Object -{ - /** A flag to denote whether or not unsynchronisation is applied on all - frames */ - const UNSYNCHRONISATION = 128; - - /** A flag to denote whether or not the header is followed by an extended - header */ - const EXTENDEDHEADER = 64; - - /** A flag used as an experimental indicator. This flag shall always be set - when the tag is in an experimental stage. */ - const EXPERIMENTAL = 32; - - /** - * A flag to denote whether a footer is present at the very end of the tag. - * - * @since ID3v2.4.0 - */ - const FOOTER = 16; - - /** @var integer */ - private $_version = 4.0; - - /** @var integer */ - private $_flags = 0; - - /** @var integer */ - private $_size; - - /** - * Constructs the class with given parameters and reads object related data - * from the ID3v2 tag. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_version = $options["version"] = - $this->_reader->readInt8() + $this->_reader->readInt8() / 10; - $this->_flags = $this->_reader->readInt8(); - $this->_size = $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); - } - - /** - * Returns the tag version number. The version number is in the form of - * major.revision. - * - * @return integer - */ - public function getVersion() { return $this->_version; } - - /** - * Sets the tag version number. Supported version numbers are 3.0 and 4.0 - * for ID3v2.3.0 and ID3v2.4.0 standards, respectively. - * - * @param integer $version The tag version number in the form of - * major.revision. - */ - public function setVersion($version) - { - $this->setOption("version", $this->_version = $version); - } - - /** - * Checks whether or not the flag is set. Returns true if the flag - * is set, false otherwise. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } - - /** - * Returns the flags byte. - * - * @return integer - */ - public function getFlags() { return $this->_flags; } - - /** - * Sets the flags byte. - * - * @param string $flags The flags byte. - */ - public function setFlags($flags) { $this->_flags = $flags; } - - /** - * Returns the tag size, excluding the header and the footer. - * - * @return integer - */ - public function getSize() { return $this->_size; } - - /** - * Sets the tag size, excluding the header and the footer. Called - * automatically upon tag generation to adjust the tag size. - * - * @param integer $size The size of the tag, in bytes. - */ - public function setSize($size) { $this->_size = $size; } - - /** - * Returns the header/footer data without the identifier. - * - * @return string - */ - public function __toString() - { - return Transform::toInt8(floor($this->_version)) . - Transform::toInt8(($this->_version - floor($this->_version)) * 10) . - Transform::toInt8($this->_flags) . - Transform::toUInt32BE($this->_encodeSynchsafe32($this->_size)); - } -} diff --git a/src/ID3/Language.php b/src/ID3/Language.php deleted file mode 100644 index e4f6336..0000000 --- a/src/ID3/Language.php +++ /dev/null @@ -1,69 +0,0 @@ -Language interface implies that the ID3v2 frame supports - * its content to be given in multiple languages. - * - * The three byte language code is used to describe the language of the frame's - * content, according to {@link http://www.loc.gov/standards/iso639-2/ - * ISO-639-2}. The language should be represented in lower case. If the language - * is not known the string "xxx" should be used. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -interface ID3_Language -{ - /** - * Returns the text language code. - * - * @return string - */ - public function getLanguage(); - - /** - * Sets the text language code. - * - * @param string $language The text language code. - */ - public function setLanguage($language); -} diff --git a/src/ID3/Object.php b/src/ID3/Object.php deleted file mode 100644 index 58e7b30..0000000 --- a/src/ID3/Object.php +++ /dev/null @@ -1,303 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ID3_Object -{ - /** - * The reader object. - * - * @var Reader - */ - protected $_reader; - - /** - * The options array. - * - * @var Array - */ - private $_options; - - /** - * Constructs the class with given parameters. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader = null, &$options = array()) - { - $this->_reader = $reader; - $this->_options = &$options; - } - - /** - * Returns the options array. - * - * @return Array - */ - public final 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 final function getOption($option, $defaultValue = false) - { - if (isset($this->_options[$option])) - return $this->_options[$option]; - return $defaultValue; - } - - /** - * Sets the options array. See {@link ID3v2} class for available options. - * - * @param Array $options The options array. - */ - public final 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 final function setOption($option, $value) - { - $this->_options[$option] = $value; - } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst($name))) - return call_user_func(array($this, "get" . ucfirst($name))); - else { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Unknown 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 { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Unknown field: " . $name); - } - } - - /** - * Encodes the given 32-bit integer to 28-bit synchsafe integer, where the - * most significant bit of each byte is zero, making seven bits out of eight - * available. - * - * @param integer $val The integer to encode. - * @return integer - */ - protected final function _encodeSynchsafe32($val) - { - return ($val & 0x7f) | ($val & 0x3f80) << 1 | - ($val & 0x1fc000) << 2 | ($val & 0xfe00000) << 3; - } - - /** - * Decodes the given 28-bit synchsafe integer to regular 32-bit integer. - * - * @param integer $val The integer to decode - * @return integer - */ - protected final function _decodeSynchsafe32($val) - { - return ($val & 0x7f) | ($val & 0x7f00) >> 1 | - ($val & 0x7f0000) >> 2 | ($val & 0x7f000000) >> 3; - } - - /** - * Applies the unsynchronisation scheme to the given data string. - * - * Whenever a false synchronisation is found within the data, one zeroed byte - * is inserted after the first false synchronisation byte. This has the side - * effect that all 0xff00 combinations have to be altered, so they will not - * be affected by the decoding process. Therefore all the 0xff00 combinations - * have to be replaced with the 0xff0000 combination during the - * unsynchronisation. - * - * @param string $data The input data. - * @return string - */ - protected final function _encodeUnsynchronisation(&$data) - { - $result = ""; - for ($i = 0, $j = 0; $i < strlen($data) - 1; $i++) - if (ord($data[$i]) == 0xff && - ((($tmp = ord($data[$i + 1])) & 0xe0) == 0xe0 || $tmp == 0x0)) { - $result .= substr($data, $j, $i + 1 - $j) . "\0"; - $j = $i + 1; - } - return $result . substr($data, $j); - } - - /** - * Reverses the unsynchronisation scheme from the given data string. - * - * @see _encodeUnsynchronisation - * @param string $data The input data. - * @return string - */ - protected final function _decodeUnsynchronisation(&$data) - { - $result = ""; - for ($i = 0, $j = 0; $i < strlen($data) - 1; $i++) - if (ord($data[$i]) == 0xff && ord($data[$i + 1]) == 0x0) { - $result .= substr($data, $j, $i + 1 - $j); - $j = $i + 2; - } - return $result . substr($data, $j); - } - - /** - * Splits UTF-16 formatted binary data up according to null terminators - * residing in the string, up to a given limit. - * - * @param string $value The input string. - * @return Array - */ - protected final function _explodeString16($value, $limit = null) - { - $i = 0; - $array = array(); - while (count($array) < $limit - 1 || $limit === null) { - $start = $i; - do { - $i = strpos($value, "\x00\x00", $i); - if ($i === false) { - $array[] = substr($value, $start); - return $array; - } - } while ($i & 0x1 != 0 && $i++); // make sure its aligned - $array[] = substr($value, $start, $i - $start); - $i += 2; - } - $array[] = substr($value, $i); - return $array; - } - - /** - * Splits UTF-8 or ISO-8859-1 formatted binary data according to null - * terminators residing in the string, up to a given limit. - * - * @param string $value The input string. - * @return Array - */ - protected final function _explodeString8($value, $limit = null) - { - return preg_split("/\\x00/", $value, $limit); - } - - /** - * Converts string to requested character encoding and returns it. See the - * documentation of iconv for accepted values for encoding. - * - * @param string|Array $string - * @param string $encoding - */ - protected final function _convertString($string, $encoding) - { - $target = $this->getOption("encoding", ID3_Encoding::UTF8); - switch ($target) { - case ID3_Encoding::UTF16: - $target = "utf-16"; - break; - case ID3_Encoding::UTF16LE: - $target = "utf-16le"; - break; - case ID3_Encoding::UTF16BE: - $target = "utf-16be"; - break; - case ID3_Encoding::UTF8: - $target = "utf-8"; - break; - default: - $target = "iso-8859-1"; - } - - if (strtolower($target) == strtolower($encoding)) - return $string; - - if (is_array($string)) - foreach ($string as $key => $value) - $string[$key] = iconv($encoding, $target, $value); - else - $string = iconv($encoding, $target, $string); - return $string; - } - - /** - * Returns the object data. - * - * @return string - */ - abstract public function __toString(); -} diff --git a/src/ID3/Timing.php b/src/ID3/Timing.php deleted file mode 100644 index 7eafee2..0000000 --- a/src/ID3/Timing.php +++ /dev/null @@ -1,73 +0,0 @@ -Timing interface implies that the ID3v2 frame contains - * one or more 32-bit timestamps. - * - * The timestamps are absolute times, meaning that every stamp contains the time - * from the beginning of the file. - * - * @package php-reader - * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -interface ID3_Timing -{ - /** The timestamp is an absolute time, using MPEG frames as unit. */ - const MPEG_FRAMES = 1; - - /** The timestamp is an absolute time, using milliseconds as unit. */ - const MILLISECONDS = 2; - - /** - * Returns the timing format. - * - * @return integer - */ - public function getFormat(); - - /** - * Sets the timing format. - * - * @param integer $format The timing format. - */ - public function setFormat($format); -} diff --git a/src/ID3v1.php b/src/ID3v1.php deleted file mode 100644 index b2263cd..0000000 --- a/src/ID3v1.php +++ /dev/null @@ -1,361 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3v1 -{ - /** @var string */ - private $_title; - - /** @var string */ - private $_artist; - - /** @var string */ - private $_album; - - /** @var string */ - private $_year; - - /** @var string */ - private $_comment; - - /** @var integer */ - private $_track; - - /** @var integer */ - private $_genre = 255; - - /** - * The genre list. - * - * @var Array - */ - public static $genres = array - ("Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", - "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", - "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", - "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", - "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", - "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", - "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", - "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", - "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", - "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", - "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", - "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", - "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", - "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", - "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", - "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", - "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", - "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", - "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", - "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", - "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House", - "Dance Hall", 255 => "Unknown"); - - /** @var Reader */ - private $_reader; - - /** @var string */ - private $_filename = false; - - /** - * Constructs the ID3v1 class with given file. The file is not mandatory - * argument and may be omitted. A new tag can be written to a file also by - * giving the filename to the {@link #write} method of this class. - * - * @param string|Reader $filename The path to the file, file descriptor of an - * opened file, or {@link Reader} instance. - */ - public function __construct($filename = false) - { - if ($filename instanceof Reader) - $this->_reader = &$filename; - else if ((is_string($filename) && ($this->_filename = $filename) !== false && - file_exists($filename) !== false) || - (is_resource($filename) && - in_array(get_resource_type($filename), array("file", "stream")))) - $this->_reader = new Reader($filename); - else - return; - - if ($this->_reader->getSize() < 128) - throw new ID3_Exception("File does not contain ID3v1 tag"); - $this->_reader->setOffset(-128); - if ($this->_reader->read(3) != "TAG") { - $this->_reader = false; // reset reader, see write - throw new ID3_Exception("File does not contain ID3v1 tag"); - } - - $this->_title = rtrim($this->_reader->readString8(30), " \0"); - $this->_artist = rtrim($this->_reader->readString8(30), " \0"); - $this->_album = rtrim($this->_reader->readString8(30), " \0"); - $this->_year = $this->_reader->readString8(4); - $this->_comment = rtrim($this->_reader->readString8(28), " \0"); - - /* ID3v1.1 support for tracks */ - $v11_null = $this->_reader->read(1); - $v11_track = $this->_reader->read(1); - if (ord($v11_null) == 0 && ord($v11_track) != 0) - $this->_track = ord($v11_track); - else - $this->_comment = rtrim($this->_comment . $v11_null . $v11_track, " \0"); - - $this->_genre = $this->_reader->readInt8(); - } - - /** - * Returns the title field. - * - * @return string - */ - public function getTitle() { return $this->_title; } - - /** - * Sets a new value for the title field. The field cannot exceed 30 - * characters in length. - * - * @param string $title The title. - */ - public function setTitle($title) { $this->_title = $title; } - - /** - * Returns the artist field. - * - * @return string - */ - public function getArtist() { return $this->_artist; } - - /** - * Sets a new value for the artist field. The field cannot exceed 30 - * characters in length. - * - * @param string $artist The artist. - */ - public function setArtist($artist) { $this->_artist = $artist; } - - /** - * Returns the album field. - * - * @return string - */ - public function getAlbum() { return $this->_album; } - - /** - * Sets a new value for the album field. The field cannot exceed 30 - * characters in length. - * - * @param string $album The album. - */ - public function setAlbum($album) { $this->_album = $album; } - - /** - * Returns the year field. - * - * @return string - */ - public function getYear() { return $this->_year; } - - /** - * Sets a new value for the year field. The field cannot exceed 4 - * characters in length. - * - * @param string $year The year. - */ - public function setYear($year) { $this->_year = $year; } - - /** - * Returns the comment field. - * - * @return string - */ - public function getComment() { return $this->_comment; } - - /** - * Sets a new value for the comment field. The field cannot exceed 30 - * characters in length. - * - * @param string $comment The comment. - */ - public function setComment($comment) { $this->_comment = $comment; } - - /** - * Returns the track field. - * - * @since ID3v1.1 - * @return integer - */ - public function getTrack() { return $this->_track; } - - /** - * Sets a new value for the track field. By setting this field you enforce the - * 1.1 version to be used. - * - * @since ID3v1.1 - * @param integer $track The track number. - */ - public function setTrack($track) { $this->_track = $track; } - - /** - * Returns the genre. - * - * @return string - */ - public function getGenre() - { - if (isset(self::$genres[$this->_genre])) - return self::$genres[$this->_genre]; - else - return self::$genres[255]; // unknown - } - - /** - * Sets a new value for the genre field. The value may either be a numerical - * code representing one of the genres, or its string variant. - * - * The genre is set to unknown (code 255) in case the string is not found from - * the static {@link $genres} array of this class. - * - * @param integer $genre The genre. - */ - public function setGenre($genre) - { - if ((is_numeric($genre) && $genre >= 0 && $genre <= 255) || - ($genre = array_search($genre, self::$genres)) !== false) - $this->_genre = $genre; - else - $this->_genre = 255; // unknown - } - - /** - * Writes the possibly altered ID3v1 tag back to the file where it was read. - * If the class was constructed without a file name, one can be provided here - * as an argument. Regardless, the write operation will override previous - * tag information, if found. - * - * @param string $filename The optional path to the file. - */ - public function write($filename = false) - { - if ($filename === false && ($filename = $this->_filename) === false) - throw new ID3_Exception("No file given to write the tag to"); - - if (($fd = fopen - ($filename, file_exists($filename) ? "r+b" : "wb")) === false) - throw new ID3_Exception("Unable to open file for writing: " . $filename); - - fseek($fd, $this->_reader !== false ? -128 : 0, SEEK_END); - fwrite($fd, $this->__toString(), 128); - - $this->_filename = $filename; - } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - // To keep compatibility with PHP 5.0.0 we use a static array instead of - // method_exists to check if a method can be called. - static $names = array( - "title", "artist", "album", "year", "comment", "track", "genre" - ); - if (in_array($name, $names)) - return call_user_func(array($this, "get" . ucfirst(strtolower($name)))); - else throw new ID3_Exception("Unknown 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) - { - // To keep compatibility with PHP 5.0.0 we use a static array instead of - // method_exists to check if a method can be called. - static $names = array( - "title", "artist", "album", "year", "comment", "track", "genre" - ); - if (in_array($name, $names)) - call_user_func - (array($this, "set" . ucfirst(strtolower($name))), $value); - else throw new ID3_Exception("Unknown field: " . $name); - } - - /** - * Returns the tag raw data. - * - * @return string - */ - private function __toString() - { - return "TAG" . - Transform::toString8(substr($this->_title, 0, 30), 30) . - Transform::toString8(substr($this->_artist, 0, 30), 30) . - Transform::toString8(substr($this->_album, 0, 30), 30) . - Transform::toString8(substr($this->_year, 0, 4), 4) . - ($this->_track ? - Transform::toString8(substr($this->_comment, 0, 28), 28) . - "\0" . Transform::toInt8($this->_track) : - Transform::toString8(substr($this->_comment, 0, 30), 30)) . - Transform::toInt8($this->_genre); - } -} diff --git a/src/ID3v2.php b/src/ID3v2.php deleted file mode 100644 index 0905c38..0000000 --- a/src/ID3v2.php +++ /dev/null @@ -1,555 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ID3v2 -{ - /** @var Reader */ - private $_reader; - - /** @var ID3_Header */ - private $_header; - - /** @var ID3_ExtendedHeader */ - private $_extendedHeader; - - /** @var ID3_Header */ - private $_footer; - - /** @var Array */ - private $_frames = array(); - - /** @var string */ - private $_filename = false; - - /** @var Array */ - private $_options; - - /** - * Constructs the ID3v2 class with given file and options. The options array - * may also be given as the only parameter. - * - * The following options are currently recognized: - * o encoding -- Indicates the encoding that all the texts are presented - * with. By default this is set to ID3_Encoding::UTF8. See the - * documentation of the {@link ID3_Encoding} interface for accepted - * values. Conversions are carried out using iconv. - * o version -- The ID3v2 tag version to use in write operation. This option - * is automatically set when a tag is read from a file and defaults to - * version 4.0 for tag write. - * o readonly -- Indicates that the tag is read from a temporary file or - * another source it cannot be written back to. The tag can, however, - * still be written to another file. - * - * @todo Only limited subset of flags are processed. - * @todo Utilize the SEEK frame and search for a footer to find the tag - * @todo Utilize the LINK frame to fetch frames from other sources - * @param string|Reader $filename The path to the file, file descriptor of an - * opened file, or {@link Reader} instance. - * @param Array $options The options array. - */ - public function __construct($filename = false, $options = array()) - { - if (is_array($filename)) { - $options = $filename; - $filename = false; - } - - $this->_options = &$options; - if ($filename === false || - (is_string($filename) && file_exists($filename) === false) || - (is_resource($filename) && - in_array(get_resource_type($filename), array("file", "stream")))) { - $this->_header = new ID3_Header(null, $options); - } else { - if (is_string($filename) && !isset($options["readonly"])) - $this->_filename = $filename; - if ($filename instanceof Reader) - $this->_reader = &$filename; - else - $this->_reader = new Reader($filename); - - $startOffset = $this->_reader->getOffset(); - - if ($this->_reader->readString8(3) != "ID3") { - require_once("ID3/Exception.php"); - throw new ID3_Exception("File does not contain ID3v2 tag"); - } - - $this->_header = new ID3_Header($this->_reader, $options); - if ($this->_header->getVersion() < 3 || - $this->_header->getVersion() > 4) { - require_once("ID3/Exception.php"); - throw new ID3_Exception - ("File does not contain ID3v2 tag of supported version"); - } - if ($this->_header->getVersion() < 4 && - $this->_header->hasFlag(ID3_Header::UNSYNCHRONISATION)) { - require_once("ID3/Exception.php"); - throw new ID3_Exception - ("Unsynchronisation not supported for this version of ID3v2 tag"); - } - unset($this->_options["unsyncronisation"]); - if ($this->_header->hasFlag(ID3_Header::UNSYNCHRONISATION)) - $this->_options["unsyncronisation"] = true; - if ($this->_header->hasFlag(ID3_Header::EXTENDEDHEADER)) { - require_once("ID3/ExtendedHeader.php"); - $this->_extendedHeader = - new ID3_ExtendedHeader($this->_reader, $options); - } - if ($this->_header->hasFlag(ID3_Header::FOOTER)) - $this->_footer = &$this->_header; // skip footer, and rather copy header - - while (true) { - $offset = $this->_reader->getOffset(); - - // Jump off the loop if we reached the end of the tag - if ($offset - $startOffset - 10 >= $this->_header->getSize() - - ($this->hasFooter() ? 10 : 0) - /* Min bytes for a header */ 10) - break; - - // Jump off the loop if we reached padding - if (Transform::fromUInt8($identifier = $this->_reader->read(1)) == 0) - break; - - $identifier .= $this->_reader->read(3); - - // Jump off the loop if we reached invalid entities. This fix is just to - // make things work. Utility called MP3ext does not seem to know what it - // is doing as it uses padding to write its version information there. - if ($identifier == "MP3e") - break; - - $this->_reader->setOffset($offset); - if (@fopen($filename = "ID3/Frame/" . - strtoupper($identifier) . ".php", "r", true) !== false) - require_once($filename); - if (class_exists($classname = "ID3_Frame_" . $identifier)) - $frame = new $classname($this->_reader, $options); - else { - require_once("ID3/Frame/Unknown.php"); - $frame = new ID3_Frame_Unknown($this->_reader, $options); - } - - if (!isset($this->_frames[$frame->getIdentifier()])) - $this->_frames[$frame->getIdentifier()] = array(); - $this->_frames[$frame->getIdentifier()][] = $frame; - } - } - } - - /** - * Returns the header object. - * - * @return ID3_Header - */ - public function getHeader() { return $this->_header; } - - /** - * Checks whether there is an extended header present in the tag. Returns - * true if the header is present, false otherwise. - * - * @return boolean - */ - public function hasExtendedHeader() - { - if ($this->_header) - return $this->_header->hasFlag(ID3_Header::EXTENDEDHEADER); - } - - /** - * Returns the extended header object if present, or false - * otherwise. - * - * @return ID3_ExtendedHeader|false - */ - public function getExtendedHeader() - { - if ($this->hasExtendedHeader()) - return $this->_extendedHeader; - return false; - } - - /** - * Sets the extended header object. - * - * @param ID3_ExtendedHeader $extendedHeader The header object - */ - public function setExtendedHeader($extendedHeader) - { - if (is_subclass_of($extendedHeader, "ID3_ExtendedHeader")) { - $this->_header->flags = - $this->_header->flags | ID3_Header::EXTENDEDHEADER; - $this->_extendedHeader->setOptions($this->_options); - $this->_extendedHeader = $extendedHeader; - } else { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Invalid argument"); - } - } - - /** - * Checks whether there is a frame given as an argument defined in the tag. - * Returns true if one ore more frames are present, - * false otherwise. - * - * @param string $identifier The frame name. - * @return boolean - */ - public function hasFrame($identifier) - { - return isset($this->_frames[$identifier]); - } - - /** - * Returns all the frames the tag contains as an associate array. The frame - * identifiers work as keys having an array of frames as associated value. - * - * @return Array - */ - public function getFrames() { return $this->_frames; } - - /** - * Returns an array of frames matching the given identifier or an empty array - * if no frames matched the identifier. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * Please note that one may also use the shorthand $obj->identifier to access - * the first frame with the identifier given. Wildcards cannot be used with - * the shorthand method. - * - * @param string $identifier The frame name. - * @return Array - */ - public function getFramesByIdentifier($identifier) - { - $matches = array(); - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_frames as $identifier => $frames) - if (preg_match($searchPattern, $identifier)) - foreach ($frames as $frame) - $matches[] = $frame; - return $matches; - } - - /** - * Removes any frames matching the given object identifier. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * One may also use the shorthand unset($obj->identifier) to achieve the same - * result. Wildcards cannot be used with the shorthand method. - * - * @param string $identifier The frame name. - */ - public final function removeFramesByIdentifier($identifier) - { - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_frames as $identifier => $frames) - if (preg_match($searchPattern, $identifier)) - unset($this->_frames[$identifier]); - } - - /** - * Adds a new frame to the tag and returns it. - * - * @param ID3_Frame $frame The frame to add. - * @return ID3_Frame - */ - public function addFrame($frame) - { - $frame->setOptions($this->_options); - if (!$this->hasFrame($frame->getIdentifier())) - $this->_frames[$frame->getIdentifier()] = array(); - return $this->_frames[$frame->getIdentifier()][] = $frame; - } - - /** - * Remove the given frame from the tag. - * - * @param ID3_Frame $frame The frame to remove. - */ - public function removeFrame($frame) - { - if (!$this->hasFrame($frame->getIdentifier())) - foreach ($this->_frames[$frame->getIdentifier()] as $key => $value) - if ($frame === $value) - unset($this->_frames[$frame->getIdentifier()][$key]); - } - - /** - * Checks whether there is a footer present in the tag. Returns - * true if the footer is present, false otherwise. - * - * @return boolean - */ - public function hasFooter() - { - return $this->_header->hasFlag(ID3_Header::FOOTER); - } - - /** - * Returns the footer object if present, or false otherwise. - * - * @return ID3_Header|false - */ - public function getFooter() - { - if ($this->hasFooter()) - return $this->_footer; - return false; - } - - /** - * Sets whether the tag should have a footer defined. - * - * @param boolean $useFooter Whether the tag should have a footer - */ - public function setFooter($useFooter) - { - if ($useFooter) { - $this->_header->setFlags - ($this->_header->getFlags() | ID3_Header::FOOTER); - $this->_footer = &$this->_header; - } else { - /* Count footer bytes towards the tag size, so it gets removed or - overridden upon re-write */ - if ($this->hasFooter()) - $this->_header->setSize($this->_header->getSize() + 10); - - $this->_header->setFlags - ($this->_header->getFlags() & ~ID3_Header::FOOTER); - $this->_footer = null; - } - } - - /** - * Writes the possibly altered ID3v2 tag back to the file where it was read. - * If the class was constructed without a file name, one can be provided here - * as an argument. Regardless, the write operation will override previous - * tag information, if found. - * - * If write is called without setting any frames to the tag, the tag is - * removed from the file. - * - * @param string $filename The optional path to the file. - */ - public function write($filename = false) - { - if ($filename === false && ($filename = $this->_filename) === false) { - require_once("ID3/Exception.php"); - throw new ID3_Exception("No file given to write the tag to"); - } - else if ($filename !== false && $this->_filename !== false && - realpath($filename) != realpath($this->_filename) && - !copy($this->_filename, $filename)) { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Unable to copy source to destination: " . - realpath($this->_filename) . "->" . realpath($filename)); - } - - if (($fd = fopen - ($filename, file_exists($filename) ? "r+b" : "wb")) === false) { - require_once("ID3/Exception.php"); - throw new ID3_Exception("Unable to open file for writing: " . $filename); - } - - $oldTagSize = $this->_header->getSize(); - $tag = $this->__toString(); - $tagSize = empty($this->_frames) ? 0 : strlen($tag); - - if ($this->_reader === null || - $tagSize - 10 > $oldTagSize || $tagSize == 0) { - fseek($fd, 0, SEEK_END); - $oldFileSize = ftell($fd); - ftruncate($fd, $newFileSize = $tagSize - $oldTagSize + $oldFileSize); - for ($i = 1, $cur = $oldFileSize; $cur > 0; $cur -= 1024, $i++) { - fseek($fd, -(($i * 1024) + ($newFileSize - $oldFileSize)), SEEK_END); - $buffer = fread($fd, 1024); - fseek($fd, -($i * 1024), SEEK_END); - fwrite($fd, $buffer, 1024); - } - } - fseek($fd, 0); - fwrite($fd, $tag, $tagSize); - fclose($fd); - - $this->_filename = $filename; - } - - /** - * Magic function so that $obj->value will work. The method will attempt to - * return the first frame that matches the identifier. - * - * If there is no frame or field with given name, the method will attempt to - * create a frame with given identifier. - * - * If none of these work, an exception is thrown. - * - * @param string $name The frame or field name. - * @return mixed - */ - public function __get($name) { - if (isset($this->_frames[strtoupper($name)])) - return $this->_frames[strtoupper($name)][0]; - if (method_exists($this, "get" . ucfirst($name))) - return call_user_func(array($this, "get" . ucfirst($name))); - if (@fopen($filename = - "ID3/Frame/" . strtoupper($name) . ".php", "r", true) !== false) - require_once($filename); - if (class_exists($classname = "ID3_Frame_" . strtoupper($name))) - return $this->addFrame(new $classname()); - require_once("ID3/Exception.php"); - throw new ID3_Exception("Unknown frame/field: " . $name); - } - - /** - * Magic function so that isset($obj->value) will work. This method checks - * whether the frame matching the identifier exists. - * - * @param string $name The frame identifier. - * @return boolean - */ - public function __isset($name) - { - return isset($this->_frames[strtoupper($name)]); - } - - /** - * Magic function so that unset($obj->value) will work. This method removes - * all the frames matching the identifier. - * - * @param string $name The frame identifier. - */ - public function __unset($name) { unset($this->_frames[strtoupper($name)]); } - - /** - * Returns the tag raw data. - * - * @return string - */ - public function __toString() - { - unset($this->_options["unsyncronisation"]); - - $data = ""; - foreach ($this->_frames as $frames) - foreach ($frames as $frame) - $data .= $frame->__toString(); - - $datalen = strlen($data); - $padlen = 0; - - if (isset($this->_options["unsyncronisation"]) && - $this->_options["unsyncronisation"] === true) - $this->_header->setFlags - ($this->_header->getFlags() | ID3_Header::UNSYNCHRONISATION); - - /* The tag padding is calculated as follows. If the tag can be written in - the space of the previous tag, the remaining space is used for padding. - If there is no previous tag or the new tag is bigger than the space taken - by the previous tag, the padding is a constant 4096 bytes. */ - if ($this->hasFooter() === false) { - if ($this->_reader !== null && $datalen < $this->_header->getSize()) - $padlen = $this->_header->getSize() - $datalen; - else - $padlen = 4096; - } - - /* ID3v2.4.0 CRC calculated w/ padding */ - if (!isset($this->_options["version"]) || $this->_options["version"] >= 4) - $data = str_pad($data, $datalen + $padlen, "\0"); - - if ($this->hasExtendedHeader()) { - $this->_extendedHeader->setPadding($padlen); - if ($this->_extendedHeader->hasFlag(ID3_ExtendedHeader::CRC32)) { - $crc = crc32($data); - if ($crc & 0x80000000) - $crc = -(($crc ^ 0xffffffff) + 1); - $this->_extendedHeader->setCrc($crc); - } - $data = $this->getExtendedHeader()->__toString() . $data; - } - - /* ID3v2.3.0 CRC calculated w/o padding */ - if (isset($this->_options["version"]) && $this->_options["version"] < 4) - $data = str_pad($data, $datalen + $padlen, "\0"); - - $this->_header->setSize(strlen($data)); - - return "ID3" . $this->_header->__toString() . $data . - ($this->hasFooter() ? "3DI" . $this->getFooter()->__toString() : ""); - } -} diff --git a/src/ISO14496.php b/src/ISO14496.php deleted file mode 100644 index 31c1213..0000000 --- a/src/ISO14496.php +++ /dev/null @@ -1,380 +0,0 @@ -Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - *
  • Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - *
  • Neither the name of the project workgroup nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * @package php-reader - * @subpackage ISO 14496 - * @copyright Copyright (c) 2008 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Id$ - */ - -/**#@+ @ignore */ -require_once("Reader.php"); -require_once("ISO14496/Box.php"); -/**#@-*/ - -/** - * This class represents a file in ISO base media file format as described in - * ISO/IEC 14496 Part 12 standard. - * - * 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. - * - * - * 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 {@link ISO14496_Box_TKHD Track Header Box} is found in a - * {@link ISO14496_Box_TRAK Track Box}, which is found in a - * {@link ISO14496_Box_MOOV Movie Box}. 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 {@link ISO14496_Box_MOOV Movie} or - * {@link ISO14496_Box_TRAK Track Boxes}, and objects using an extended type may - * 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 - *
        - *
      • 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 - *
        • tref -- {@link ISO14496_Box_TREF Track Reference Box} - *
        • edts -- {@link ISO14496_Box_EDTS Edit Box} - *
            - *
          • elst -- {@link ISO14496_Box_ELST Edit List Box} - *
          - *
        • 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} - *
              - *
            • 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} - *
              - *
            • 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} - *
              • 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 - *
              • stss -- {@link ISO14496_Box_STSS 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} - *
              • 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} - *
              - *
            - *
          - *
        - *
      • mvex -- {@link ISO14496_Box_MVEX Movie Extends Box} - *
          - *
        • mehd -- {@link ISO14496_Box_MEHD Movie Extends Header Box} - *
        • trex -- {@link ISO14496_Box_TREX Track Extends Box} - *
        - *
      • ipmc -- {@link ISO14496_Box_IPMC IPMP Control Box} - *
      - *
    • moof -- {@link ISO14496_Box_MOOF Movie Fragment 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} - *
        • trun -- {@link ISO14496_Box_TRUN Track Fragment Run} - *
        • 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} - *
      - *
    • mdat -- {@link ISO14496_Box_MDAT Media Data Box} - *
    • free -- {@link ISO14496_Box_FREE Free Space Box} - *
    • skip -- {@link ISO14496_Box_SKIP Free Space Box} - *
        - *
      • udta -- {@link ISO14496_Box_UDTA User Data Box} - *
          - *
        • cprt -- {@link ISO14496_Box_CPRT Copyright Box} - *
        - *
      - *
    • meta -- {@link ISO14496_Box_META The Meta Box} - *
        - *
      • 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 - *
        - *
      • 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} - *
            - *
          • frma -- {@link ISO14496_Box_FRMA Original Format Box} - *
          • imif -- {@link ISO14496_Box_IMIF IPMP Information Box} - *
          • schm -- {@link ISO14496_Box_SCHM Scheme Type Box} - *
          • schi -- {@link ISO14496_Box_SCHI Scheme Information Box} - *
          - *
        - *
      • iinf -- {@link ISO14496_Box_IINF Item Information Box} - *
          - *
        • infe -- {@link ISO14496_Box_INFE Item Information Entry Box} - *
        - *
      • xml -- {@link ISO14496_Box_XML XML Box} - *
      • bxml -- {@link ISO14496_Box_BXML Binary XML Box} - *
      • pitm -- {@link ISO14496_Box_PITM Primary Item Reference Box} - *
      - *
    - * - * 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 -- {@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} - *
      • id32 -- {@link ISO14496_Box_ID32 The ID3v2 Box} - *
      - *
    - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496 extends ISO14496_Box -{ - /** @var string */ - private $_filename; - - /** - * 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, $options = array()) - { - $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 deleted file mode 100644 index 38155ef..0000000 --- a/src/ISO14496/Box.php +++ /dev/null @@ -1,497 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class ISO14496_Box -{ - /** - * The reader object. - * - * @var Reader - */ - protected $_reader; - - /** @var Array */ - private $_options; - - /** @var integer */ - private $_offset = -1; - - /** @var integer */ - private $_size = -1; - - /** @var string */ - private $_type; - - - /** @var ISO14496_Box */ - private $_parent = null; - - - /** @var boolean */ - private $_container = false; - - /** @var Array */ - private $_boxes = array(); - - /** @var Array */ - private static $_path = array(); - - /** - * Constructs the class with given parameters and options. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - 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() - $this->_offset; - - if ($this->_type == "uuid") - $this->_type = $this->_reader->readGUID(); - } - $this->_options = &$options; - } - - /** - * Returns the options array. - * - * @return Array - */ - public final 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 final 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 final 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 final 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 final function getOffset() { return $this->_offset; } - - /** - * Sets the file offset where the box starts. - * - * @param integer $offset The file offset to box start. - */ - public final 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 final 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. - * - * @param integer $size The box size. - */ - public final 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 final function getType() { return $this->_type; } - - /** - * Sets the box type. - * - * @param string $type The box type. - */ - public final function setType($type) { $this->_type = $type; } - - /** - * Returns the parent box containing this box. - * - * @return ISO14496_Box - */ - public final 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. - * - * @return boolean - */ - public final function isContainer() { return $this->_container; } - - /** - * Returns a boolean value corresponding to whether the box is a container. - * - * @return boolean - */ - public final function getContainer() { return $this->_container; } - - /** - * Sets whether the box is a container. - * - * @param boolean $container Whether the box is a container. - */ - protected final function setContainer($container) - { - $this->_container = $container; - } - - /** - * Reads and constructs the boxes found within this box. - * - * @todo Does not parse iTunes internal ---- boxes. - */ - protected final 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 = rtrim($this->_reader->read(4), " "); - if ($size == 1) - $size = $this->_reader->readInt64BE(); - if ($size == 0) - $size = $this->_reader->getSize() - $offset; - - if (preg_match("/^\xa9?[a-z0-9]{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); - } - - /** - * Checks whether the box given as an argument is present in the file. Returns - * true if one or more boxes are present, false - * otherwise. - * - * @param string $identifier The box identifier. - * @return boolean - * @throws ISO14496_Exception if called on a non-container box - */ - public final function hasBox($identifier) - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - return isset($this->_boxes[$identifier]); - } - - /** - * Returns all the boxes the file contains as an associate array. The box - * identifiers work as keys having an array of boxes as associated value. - * - * @return Array - * @throws ISO14496_Exception if called on a non-container box - */ - public final function getBoxes() - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - return $this->_boxes; - } - - /** - * Returns an array of boxes matching the given identifier or an empty array - * if no boxes matched the identifier. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * Please note that one may also use the shorthand $obj->identifier to access - * the first box with the identifier given. Wildcards cannot be used with - * the shorthand and they will not work with user defined uuid types. - * - * @param string $identifier The box identifier. - * @return Array - * @throws ISO14496_Exception if called on a non-container box - */ - public final function getBoxesByIdentifier($identifier) - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - $matches = array(); - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_boxes as $identifier => $boxes) - if (preg_match($searchPattern, $identifier)) - foreach ($boxes as $box) - $matches[] = $box; - return $matches; - } - - /** - * Removes any boxes matching the given box identifier. - * - * The identifier may contain wildcard characters "*" and "?". The asterisk - * matches against zero or more characters, and the question mark matches any - * single character. - * - * One may also use the shorthand unset($obj->identifier) to achieve the same - * result. Wildcards cannot be used with the shorthand method. - * - * @param string $identifier The box identifier. - * @throws ISO14496_Exception if called on a non-container box - */ - public final function removeBoxesByIdentifier($identifier) - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - $searchPattern = "/^" . - str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; - foreach ($this->_objects as $identifier => $objects) - if (preg_match($searchPattern, $identifier)) - unset($this->_objects[$identifier]); - } - - /** - * Adds a new box into the current box and returns it. - * - * @param ISO14496_Box $box The box to add - * @return ISO14496_Box - * @throws ISO14496_Exception if called on a non-container box - */ - public final function addBox($box) - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - $box->setParent($this); - $box->setOptions($this->_options); - if (!$this->hasBox($box->getType())) - $this->_boxes[$box->getType()] = array(); - return $this->_boxes[$box->getType()][] = $box; - } - - /** - * Removes the given box. - * - * @param ISO14496_Box $box The box to remove - * @throws ISO14496_Exception if called on a non-container box - */ - public final function removeBox($box) - { - if (!$this->isContainer()) - throw new ISO14496_Exception("Box not a container"); - if ($this->hasBox($box->getType())) - foreach ($this->_boxes[$box->getType()] as $key => $value) - if ($box === $value) - unset($this->_boxes[$box->getType()][$key]); - } - - /** - * Magic function so that $obj->value will work. If called on a container box, - * the method will first attempt to return the first contained box that - * matches the identifier, and if not found, invoke a getter method. - * - * If there are no boxes or getter methods with given name, the method - * 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 - */ - public function __get($name) - { - if ($this->isContainer() && isset($this->_boxes[$name])) - 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 - * identifier. - * - * @param string $name The box name. - * @return boolean - */ - public function __isset($name) - { - 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 deleted file mode 100644 index 3fd5c1c..0000000 --- a/src/ISO14496/Box/BXML.php +++ /dev/null @@ -1,86 +0,0 @@ -XML Box forms may be used. - * The Binary XML Box may only be used when there is a single well-defined - * binarization of the XML for that defined format as identified by the handler. - * - * Within an XML box the data is in UTF-8 format unless the data starts with a - * byte-order-mark (BOM), which indicates that the data is in UTF-16 format. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_BXML extends ISO14496_Box_Full -{ - /** @var string */ - private $_data; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_data = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - } - - /** - * Returns the binary data. - * - * @return string - */ - public function getData() - { - return $this->_data; - } -} diff --git a/src/ISO14496/Box/CDSC.php b/src/ISO14496/Box/CDSC.php deleted file mode 100644 index 0effe2b..0000000 --- a/src/ISO14496/Box/CDSC.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_CDSC extends ISO14496_Box -{ - /** @var Array */ - private $_trackId = 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, &$options = array()) - { - parent::__construct($reader, $options); - - while ($this->_reader->getOffset <= $this->getSize()) - $this->_trackId[] = $this->_reader->readUInt32BE(); - } - - /** - * Returns an array of integer references from the containing track to another - * track in the presentation. Track IDs are never re-used and cannot be equal - * to zero. - * - * @return integer - */ - public function getTrackId() { return $this->_trackId; } -} diff --git a/src/ISO14496/Box/CO64.php b/src/ISO14496/Box/CO64.php deleted file mode 100644 index 8aa5c59..0000000 --- a/src/ISO14496/Box/CO64.php +++ /dev/null @@ -1,122 +0,0 @@ -Chunk Offset Box table gives the index of each chunk into the - * containing file. There are two variants, permitting the use of 32-bit or - * 64-bit offsets. The latter is useful when managing very large presentations. - * At most one of these variants will occur in any single instance of a sample - * table. - * - * Offsets are file offsets, not the offset into any box within the file (e.g. - * {@link ISO14496_Box_MDAT Media Data Box}). This permits referring to media - * data in files without any box structure. It does also mean that care must be - * taken when constructing a self-contained ISO file with its metadata - * ({@link ISO14496_Box_MOOV Movie Box}) at the front, as the size of the - * {@link ISO14496_Box_MOOV Movie Box} will affect the chunk offsets to the - * media data. - * - * This box variant contains 64-bit offsets. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_CO64 extends ISO14496_Box_Full -{ - /** @var Array */ - private $_chunkOffsetTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - $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)); - } - - /** - * Returns an array of values. Each entry has 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. - * - * @return Array - */ - 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) - { - $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 deleted file mode 100644 index be1d9b7..0000000 --- a/src/ISO14496/Box/CPRT.php +++ /dev/null @@ -1,96 +0,0 @@ -Copyright Box contains a copyright declaration which applies to - * the entire presentation, when contained within the {@link ISO14496_Box_MOOV - * Movie Box}, or, when contained in a track, to that entire track. There may be - * multiple copyright boxes using different language codes. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_CPRT extends ISO14496_Box_Full -{ - /** @var string */ - private $_language; - - /** @var string */ - private $_notice; - - /** - * Constructs the class with given parameters and reads box related data from - * the ISO Base Media file. - * - * @param Reader $reader The reader object. - * @todo Distinguish UTF-16? - */ - public function __construct($reader, &$options = array()) - { - 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->getOffset() + $this->getSize() - $this->_reader->getOffset()); - } - - /** - * Returns the three byte language code to describe the language of the - * notice, according to {@link http://www.loc.gov/standards/iso639-2/ - * ISO 639-2/T}. - * - * @return string - */ - public function getLanguage() { return $this->_language; } - - /** - * Returns the copyright notice. - * - * @return string - */ - public function getNotice() { return $this->_notice; } -} diff --git a/src/ISO14496/Box/CTTS.php b/src/ISO14496/Box/CTTS.php deleted file mode 100644 index ec539a4..0000000 --- a/src/ISO14496/Box/CTTS.php +++ /dev/null @@ -1,99 +0,0 @@ -Composition Time to Sample Box provides the offset between - * decoding time and composition time. Since decoding time must be less than the - * composition time, the offsets are expressed as unsigned numbers such that - * CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for - * sample n. - * - * The composition time to sample table is optional and must only be present if - * DT and CT differ for any samples. Hint tracks do not use this box. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_CTTS extends ISO14496_Box_Full -{ - /** @var Array */ - private $_compositionOffsetTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - $data = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - for ($i = 1; $i <= $entryCount; $i++) - $this->_compositionOffsetTable[$i] = array - ("sampleCount" => - Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)), - "sampleOffset" => - Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4))); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o sampleCount -- an integer that counts the number of consecutive samples - * that have the given offset. - * o sampleOffset -- a non-negative integer that gives the offset between CT - * and DT, such that CT(n) = DT(n) + CTTS(n). - * - * @return Array - */ - public function getCompositionOffsetTable() - { - return $this->_compositionOffsetTable; - } -} diff --git a/src/ISO14496/Box/DINF.php b/src/ISO14496/Box/DINF.php deleted file mode 100644 index a8dfbbe..0000000 --- a/src/ISO14496/Box/DINF.php +++ /dev/null @@ -1,71 +0,0 @@ -Data Information Box contains objects that declare the location - * of the media information in a track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_DINF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index ced6db9..0000000 --- a/src/ISO14496/Box/DREF.php +++ /dev/null @@ -1,88 +0,0 @@ -Data Reference Box contains a table of data references (normally - * URLs) that declare the location(s) of the media data used within the - * presentation. The data reference index in the sample description ties entries - * in this table to the samples in the track. A track may be split over several - * sources in this way. - * - * This box may either contain {@link ISO14496_Box_URN urn} or - * {@link ISO14496_Box_URL url} boxes. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_DREF extends ISO14496_Box_Full -{ - /** - * 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 = null, &$options = array()) - { - parent::__construct($reader, $options); - $this->setContainer(true); - - 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 deleted file mode 100644 index 0e24e13..0000000 --- a/src/ISO14496/Box/EDTS.php +++ /dev/null @@ -1,76 +0,0 @@ -Edit Box maps the presentation time-line to the media time-line as - * it is stored in the file. The Edit Box is a container for the edit lists. - * - * The Edit Box is optional. In the absence of this box, there is an implicit - * one-to-one mapping of these time-lines, and the presentation of a track - * starts at the beginning of the presentation. An empty edit is used to offset - * the start time of a track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_EDTS extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index e424f2e..0000000 --- a/src/ISO14496/Box/ELST.php +++ /dev/null @@ -1,108 +0,0 @@ -Edit List Box contains an explicit timeline map. Each entry - * defines part of the track time-line: by mapping part of the media time-line, - * or by indicating empty time, or by defining a dwell, where a single - * time-point in the media is held for a period. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_ELST extends ISO14496_Box_Full -{ - /** @var Array */ - private $_entries = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - for ($i = 1; $i <= $entryCount; $i++) { - $entry = array(); - if ($this->getVersion() == 1) { - $entry["segmentDuration"] = $this->_reader->readInt64BE(); - $entry["mediaTime"] = $this->_reader->readInt64BE(); - } else { - $entry["segmentDuration"] = $this->_reader->readUInt32BE(); - $entry["mediaTime"] = $this->_reader->readInt32BE(); - } - $entry["mediaRate"] = $this->_reader->readInt16BE() + - $this->_reader->readInt16BE() / 10; - $this->_entries[] = $entry; - } - } - - /** - * Returns an array of entries. Each entry is an array containing the - * following keys. - * o segmentDuration: specifies the duration of this edit segment in units - * of the timescale in the {@link ISO14496_Box_MVHD Movie Header Box}. - * o mediaTime: the starting time within the media of this edit segment (in - * media time scale units, in composition time). If this field is set to - * –1, it is an empty edit. The last edit in a track shall never be an - * empty edit. Any difference between the duration in the - * {@link ISO14496_Box_MVHD Movie Header Box}, and the track's duration is - * expressed as an implicit empty edit at the end. - * o mediaRate: the relative rate at which to play the media corresponding - * to this edit segment. If this value is 0, then the edit is specifying - * a dwell: the media at media-time is presented for the segment-duration. - * Otherwise this field shall contain the value 1. - * - * @return Array - */ - public function getEntries() - { - return $this->_entries; - } -} diff --git a/src/ISO14496/Box/FREE.php b/src/ISO14496/Box/FREE.php deleted file mode 100644 index f239e5f..0000000 --- a/src/ISO14496/Box/FREE.php +++ /dev/null @@ -1,76 +0,0 @@ -Free Space Box are irrelevant and may be ignored, or - * the object deleted, without affecting the presentation. (Care should be - * exercised when deleting the object, as this may invalidate the offsets used - * in the sample table, unless this object is after all the media data). - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -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 deleted file mode 100644 index bb180e8..0000000 --- a/src/ISO14496/Box/FRMA.php +++ /dev/null @@ -1,78 +0,0 @@ -Original Format Box contains the four-character-code of the - * original un-transformed sample description. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_FRMA extends ISO14496_Box -{ - /** @var string */ - private $_dataFormat; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_dataFormat = $this->_reader->read(4); - } - - /** - * Returns the four-character-code of the original un-transformed sample entry - * (e.g. mp4v if the stream contains protected MPEG-4 visual material). - * - * @return string - */ - public function getDataFormat() { return $this->_dataFormat; } -} diff --git a/src/ISO14496/Box/FTYP.php b/src/ISO14496/Box/FTYP.php deleted file mode 100644 index 550e583..0000000 --- a/src/ISO14496/Box/FTYP.php +++ /dev/null @@ -1,142 +0,0 @@ -File Type Box is placed as early as possible in the file (e.g. - * after any obligatory signature, but before any significant variable-size - * boxes such as a {@link ISO14496_Box_MOOV Movie Box}, {@link ISO14496_Box_MDAT - * Media Data Box}, or {@link ISO14496_Box_FREE Free Space}). It identifies - * which specification is the best use of the file, and a minor version - * of that specification; and also a set of others specifications to which the - * file complies. - * - * The minor version is informative only. It does not appear for - * compatible-brands, and must not be used to determine the conformance of a - * file to a standard. It may allow more precise identification of the major - * specification, for inspection, debugging, or improved decoding. - * - * The type isom (ISO Base Media file) is defined as identifying files - * that conform to the first version of the ISO Base Media File Format. More - * specific identifiers can be used to identify precise versions of - * specifications providing more detail. This brand is not be used as the major - * brand; this base file format should be derived into another specification to - * be used. There is therefore no defined normal file extension, or mime type - * assigned to this brand, nor definition of the minor version when isom - * is the major brand. - * - * Files would normally be externally identified (e.g. with a file extension or - * mime type) that identifies the best use (major brand), or the brand - * that the author believes will provide the greatest compatibility. - * - * The brand iso2 shall be used to indicate compatibility with the - * amended version of the ISO Base Media File Format; it may be used in addition - * to or instead of the isom brand and the same usage rules apply. If - * used without the brand isom identifying the first version of the - * specification, it indicates that support for some or all of the technology - * introduced by the amended version of the ISO Base Media File Format is - * required. - * - * The brand avc1 shall be used to indicate that the file is conformant - * with the AVC Extensions. If used without other brands, this implies - * that support for those extensions is required. The use of avc1 as a - * major-brand may be permitted by specifications; in that case, that - * specification defines the file extension and required behavior. - * - * If a Meta-box with an MPEG-7 handler type is used at the file level, then the - * brand mp71 is a member of the compatible-brands list in the file-type - * box. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_FTYP extends ISO14496_Box -{ - /** @var integer */ - private $_majorBrand; - - /** @var integer */ - private $_minorVersion; - - /** @var integer */ - private $_compatibleBrands = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_majorBrand = $this->_reader->readString8(4); - $this->_minorVersion = $this->_reader->readUInt32BE(); - while ($this->_reader->getOffset() < $this->getSize()) - if (($brand = $this->_reader->readString8(4)) != "") - $this->_compatibleBrands[] = $brand; - } - - /** - * Returns the major version brand. - * - * @return string - */ - public function getMajorBrand() { return $this->_majorBrand; } - - /** - * Returns the minor version number. - * - * @return integer - */ - public function getMinorVersion() { return $this->_minorVersion; } - - /** - * Returns the array of compatible version brands. - * - * @return Array - */ - public function getCompatibleBrands() { return $this->_compatibleBrands; } -} diff --git a/src/ISO14496/Box/Full.php b/src/ISO14496/Box/Full.php deleted file mode 100644 index 06e7ab9..0000000 --- a/src/ISO14496/Box/Full.php +++ /dev/null @@ -1,124 +0,0 @@ - - * @copyright Copyright (c) 2008 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class ISO14496_Box_Full extends ISO14496_Box -{ - /** @var integer */ - protected $_version = 0; - - /** @var integer */ - protected $_flags = 0; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_version = (($field = $this->_reader->readUInt32BE()) >> 24) & 0xff; - $this->_flags = $field & 0xffffff; - } - - /** - * Returns the version of this format of the box. - * - * @return integer - */ - 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. - * - * @param integer $flag The flag to query. - * @return boolean - */ - public function hasFlag($flag) { return ($this->_flags & $flag) == $flag; } - - /** - * Returns the map of flags. - * - * @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 deleted file mode 100644 index 61b88d3..0000000 --- a/src/ISO14496/Box/HDLR.php +++ /dev/null @@ -1,150 +0,0 @@ -Handler Reference Box is within a {@link ISO14496_Box_MDIA Media - * Box} declares the process by which the media-data in the track is presented, - * and thus, the nature of the media in a track. For example, a video track - * would be handled by a video handler. - * - * This box when present within a {@link ISO14496_Box_META Meta Box}, declares - * the structure or format of the meta box contents. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_HDLR extends ISO14496_Box_Full -{ - /** @var string */ - private $_handlerType; - - /** @var string */ - private $_name; - - /** - * 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 = null, &$options = array()) - { - 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->getOffset() + $this->getSize() - $this->_reader->getOffset()); - } - - /** - * Returns the handler type. - * - * When present in a media box, the returned value contains 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 returned value contains an appropriate - * value to indicate the format of the meta box contents. - * - * @return integer - */ - 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 - * purposes). - * - * @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 deleted file mode 100644 index 286f3e5..0000000 --- a/src/ISO14496/Box/HINT.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_HINT extends ISO14496_Box -{ - /** @var Array */ - private $_trackId = 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, &$options = array()) - { - parent::__construct($reader, $options); - - while ($this->_reader->getOffset <= $this->getSize()) - $this->_trackId[] = $this->_reader->readUInt32BE(); - } - - /** - * Returns an array of integer references from the containing track to another - * track in the presentation. Track IDs are never re-used and cannot be equal - * to zero. - * - * @return integer - */ - public function getTrackId() { return $this->_trackId; } -} diff --git a/src/ISO14496/Box/HMHD.php b/src/ISO14496/Box/HMHD.php deleted file mode 100644 index 3c39f2c..0000000 --- a/src/ISO14496/Box/HMHD.php +++ /dev/null @@ -1,110 +0,0 @@ -Hint Media Header Box header contains general information, - * independent of the protocol, for hint tracks. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_HMHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_maxPDUSize; - - /** @var integer */ - private $_avgPDUSize; - - /** @var integer */ - private $_maxBitrate; - - /** @var integer */ - private $_avgBitrate; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_maxPDUSize = $this->_reader->readUInt16BE(); - $this->_avgPDUSize = $this->_reader->readUInt16BE(); - $this->_maxBitrate = $this->_reader->readUInt32BE(); - $this->_avgBitrate = $this->_reader->readUInt32BE(); - } - - /** - * Returns the size in bytes of the largest PDU in this (hint) stream. - * - * @return integer - */ - public function getMaxPDUSize() { return $this->_maxPDUSize; } - - /** - * Returns the average size of a PDU over the entire presentation. - * - * @return integer - */ - public function getAvgPDUSize() { return $this->_avgPDUSize; } - - /** - * Returns the maximum rate in bits/second over any window of one second. - * - * @return integer - */ - public function getMaxBitrate() { return $this->_maxbitrate; } - - /** - * Returns the average rate in bits/second over the entire presentation. - * - * @return integer - */ - public function getAvgBitrate() { return $this->_maxbitrate; } -} diff --git a/src/ISO14496/Box/ID32.php b/src/ISO14496/Box/ID32.php deleted file mode 100644 index 7c17394..0000000 --- a/src/ISO14496/Box/ID32.php +++ /dev/null @@ -1,131 +0,0 @@ -ID3v2 Box resides under the {@link ISO14496_Box_META Meta Box} and - * stores ID3 version 2 meta-data. There may be more than one ID3v2 Box present - * each with a different language code. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_ID32 extends ISO14496_Box_Full -{ - /** @var string */ - private $_language = "und"; - - /** @var ID3v2 */ - private $_tag; - - /** - * 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 = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_language = - chr(((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) . - chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60); - $this->_tag = new ID3v2($this->_reader, array("readonly" => true)); - } - - /** - * Returns the three byte language code to describe the language of this - * media, according to {@link http://www.loc.gov/standards/iso639-2/ - * ISO 639-2/T}. - * - * @return string - */ - 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($this->_language[0]) - 0x60) << 10) | - ((ord($this->_language[1]) - 0x60) << 5) | - ord($this->_language[2]) - 0x60) . $this->_tag); - } -} diff --git a/src/ISO14496/Box/IINF.php b/src/ISO14496/Box/IINF.php deleted file mode 100644 index a45270b..0000000 --- a/src/ISO14496/Box/IINF.php +++ /dev/null @@ -1,87 +0,0 @@ -Item Information Box provides extra information about selected - * items, including symbolic (file) names. It may optionally occur, but - * if it does, it must be interpreted, as item protection or content encoding - * may have changed the format of the data in the item. If both content encoding - * and protection are indicated for an item, a reader should first un-protect - * the item, and then decode the item's content encoding. If more control is - * needed, an IPMP sequence code may be used. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_IINF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 315e7e9..0000000 --- a/src/ISO14496/Box/ILOC.php +++ /dev/null @@ -1,134 +0,0 @@ -The Item Location Box provides a directory of resources in this or - * other files, by locating their containing file, their offset within that - * file, and their length. Placing this in binary format enables common handling - * of this data, even by systems which do not understand the particular metadata - * system (handler) used. For example, a system might integrate all the - * externally referenced metadata resources into one file, re-adjusting file - * offsets and file references accordingly. - * - * Items may be stored fragmented into extents, e.g. to enable interleaving. An - * extent is a contiguous subset of the bytes of the resource; the resource is - * formed by concatenating the extents. If only one extent is used then either - * or both of the offset and length may be implied: - * - * o If the offset is not identified (the field has a length of zero), then - * the beginning of the file (offset 0) is implied. - * o If the length is not specified, or specified as zero, then the entire - * file length is implied. References into the same file as this metadata, - * or items divided into more than one extent, should have an explicit - * offset and length, or use a MIME type requiring a different - * interpretation of the file, to avoid infinite recursion. - * - * The size of the item is the sum of the extentLengths. Note: extents may be - * interleaved with the chunks defined by the sample tables of tracks. - * - * The dataReferenceIndex may take the value 0, indicating a reference into the - * same file as this metadata, or an index into the dataReference table. - * - * Some referenced data may itself use offset/length techniques to address - * resources within it (e.g. an MP4 file might be included in this way). - * Normally such offsets are relative to the beginning of the containing file. - * The field base offset provides an additional offset for offset calculations - * within that contained data. For example, if an MP4 file is included within a - * file formatted to this specification, then normally data-offsets within that - * MP4 section are relative to the beginning of file; baseOffset adds to those - * offsets. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_ILOC extends ISO14496_Box -{ - /** @var Array */ - private $_items = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $offsetSize = (($tmp = $this->_reader->readUInt32BE()) >> 28) & 0xf; - $lengthSize = ($tmp >> 24) & 0xf; - $baseOffsetSize = ($tmp >> 20) & 0xf; - $itemCount = $this->_reader->readUInt16BE(); - for ($i = 0; $i < $itemCount; $i++) { - $item = array(); - $item["itemId"] = $this->_reader->readUInt16BE(); - $item["dataReferenceIndex"] = $this->_reader->readUInt16BE(); - $item["baseOffset"] = - ($baseOffsetSize == 4 ? $this->_reader->readUInt32BE() : - ($baseOffsetSize == 8 ? $this->_reader->readInt64BE() : 0)); - $item["extents"] = array(); - for ($j = 0; $j < $extentCount; $j++) { - $extent = array(); - $extent["offset"] = - ($offsetSize == 4 ? $this->_reader->readUInt32BE() : - ($offsetSize == 8 ? $this->_reader->readInt64BE() : 0)); - $extent["length"] = - ($lengthSize == 4 ? $this->_reader->readUInt32BE() : - ($lengthSize == 8 ? $this->_reader->readInt64BE() : 0)); - $item["extents"][] = $extent; - } - $this->_items[] = $item; - } - } - - /** - * Returns the array of items. Each entry has the following keys set: itemId, - * dataReferenceIndex, baseOffset, and extents. - * - * @return Array - */ - public function getItems() { return $this->_items; } -} diff --git a/src/ISO14496/Box/ILST.php b/src/ISO14496/Box/ILST.php deleted file mode 100644 index a54ac8a..0000000 --- a/src/ISO14496/Box/ILST.php +++ /dev/null @@ -1,281 +0,0 @@ - - *
  • _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
  • - * - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since iTunes/iPod specific - */ -final class ISO14496_Box_ILST extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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; - } -} - -/** - * Generic iTunes/iPod DATA Box container. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since iTunes/iPod specific - * @ignore - */ -final class ISO14496_Box_ILST_Container extends ISO14496_Box -{ - public function __construct($reader = null, &$options = array()) - { - parent::__construct(is_string($reader) ? null : $reader, $options); - $this->setContainer(true); - - if (is_string($reader)) { - $this->setType($reader); - $this->addBox(new ISO14496_Box_DATA()); - } else - $this->constructBoxes(); - } -} - -/**#@+ @ignore */ -require_once("ISO14496/Box/Full.php"); -/**#@-*/ - -/** - * A box that contains data for iTunes/iPod specific boxes. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @since iTunes/iPod specific - */ -final class ISO14496_Box_DATA extends ISO14496_Box_Full -{ - /** @var mixed */ - private $_value; - - /** A flag to indicate that the data is an unsigned 8-bit integer. */ - const INTEGER = 0x0; - - /** - * A flag to indicate that the data is an unsigned 8-bit integer. Different - * value used in old versions of iTunes. - */ - const INTEGER_OLD_STYLE = 0x15; - - /** A flag to indicate that the data is a string. */ - const STRING = 0x1; - - /** A flag to indicate that the data is the contents of an JPEG image. */ - const JPEG = 0xd; - - /** A flag to indicate that the data is the contents of a PNG image. */ - const PNG = 0xe; - - /** - * 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 = null, &$options = array()) - { - parent::__construct($reader, $options); - - if ($reader === null) - return; - - $this->_reader->skip(4); - $data = $this->_reader->read - ($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 .= Transform::fromInt8($data[$i]); - break; - case self::STRING: - default: - $this->_value = $data; - } - } - - /** - * Returns the value this box contains. - * - * @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))); - require_once("ISO14496/Exception.php"); - 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/INFE.php b/src/ISO14496/Box/INFE.php deleted file mode 100644 index 28740bb..0000000 --- a/src/ISO14496/Box/INFE.php +++ /dev/null @@ -1,131 +0,0 @@ -Item Information Entry Box contains the entry information. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_INFE extends ISO14496_Box_Full -{ - /** @var integer */ - private $_itemId; - - /** @var integer */ - private $_itemProtectionIndex; - - /** @var string */ - private $_itemName; - - /** @var string */ - private $_contentType; - - /** @var string */ - private $_contentEncoding; - - /** - * 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, &$options = array()) - { - 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->getOffset() + $this->getSize() - $this->_reader->getOffset())); - } - - /** - * Returns the item identifier. The value is either 0 for the primary resource - * (e.g. the XML contained in an {@link ISO14496_Box_XML XML Box}) or the ID - * of the item for which the following information is defined. - * - * @return integer - */ - public function getItemId() { return $this->_itemId; } - - /** - * Returns the item protection index. The value is either 0 for an unprotected - * item, or the one-based index into the {@link ISO14496_Box_IPRO Item - * Protection Box} defining the protection applied to this item (the first box - * in the item protection box has the index 1). - * - * @return integer - */ - public function getItemProtectionIndex() - { - return $this->_itemProtectionIndex; - } - - /** - * Returns the symbolic name of the item. - * - * @return string - */ - public function getItemName() { return $this->_itemName; } - - /** - * Returns the MIME type for the item. - * - * @return string - */ - public function getContentType() { return $this->_contentType; } - - /** - * Returns the optional content encoding type as defined for Content-Encoding - * for HTTP /1.1. Some possible values are gzip, compress and - * deflate. An empty string indicates no content encoding. - * - * @return string - */ - public function getContentEncoding() { return $this->_contentEncoding; } -} diff --git a/src/ISO14496/Box/IPMC.php b/src/ISO14496/Box/IPMC.php deleted file mode 100644 index 1d86051..0000000 --- a/src/ISO14496/Box/IPMC.php +++ /dev/null @@ -1,56 +0,0 @@ -IPMP Control Box may contain IPMP descriptors which may be - * referenced by any stream in the file. - * - * @todo Data parsing - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_IPMC extends ISO14496_Box_Full -{ -} diff --git a/src/ISO14496/Box/IPRO.php b/src/ISO14496/Box/IPRO.php deleted file mode 100644 index 658fd0c..0000000 --- a/src/ISO14496/Box/IPRO.php +++ /dev/null @@ -1,82 +0,0 @@ -Item Protection Box provides an array of item protection - * information, for use by the {@link ISO14496_Box_IINF Item Information Box}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_IPRO extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 84441c7..0000000 --- a/src/ISO14496/Box/MDAT.php +++ /dev/null @@ -1,66 +0,0 @@ -Media Data Box contains the media data. In video tracks, this box - * would contain video frames. There may be any number of these boxes in the - * file (including zero, if all the media data is in other files). - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MDAT extends ISO14496_Box -{ - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - } -} diff --git a/src/ISO14496/Box/MDHD.php b/src/ISO14496/Box/MDHD.php deleted file mode 100644 index e0211eb..0000000 --- a/src/ISO14496/Box/MDHD.php +++ /dev/null @@ -1,136 +0,0 @@ -Media Header Box declares overall information that is - * media-independent, and relevant to characteristics of the media in a track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MDHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_creationTime; - - /** @var integer */ - private $_modificationTime; - - /** @var integer */ - private $_timescale; - - /** @var integer */ - private $_duration; - - /** @var string */ - private $_language; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - if ($this->getVersion() == 1) { - $this->_creationTime = $this->_reader->readInt64BE(); - $this->_modificationTime = $this->_reader->readInt64BE(); - $this->_timescale = $this->_reader->readUInt32BE(); - $this->_duration = $this->_reader->readInt64BE(); - } else { - $this->_creationTime = $this->_reader->readUInt32BE(); - $this->_modificationTime = $this->_reader->readUInt32BE(); - $this->_timescale = $this->_reader->readUInt32BE(); - $this->_duration = $this->_reader->readUInt32BE(); - } - $this->_language = - chr(((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) . - chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60); - } - - /** - * Returns the creation time of the media in this track, in seconds since - * midnight, Jan. 1, 1904, in UTC time. - * - * @return integer - */ - public function getCreationTime() { return $this->_creationTime; } - - /** - * Returns the most recent time the media in this track was modified in - * seconds since midnight, Jan. 1, 1904, in UTC time. - * - * @return integer - */ - public function getModificationTime() { return $this->_modificationTime; } - - /** - * Returns the time-scale for this media. This is the number of time units - * that pass in one second. For example, a time coordinate system that - * measures time in sixtieths of a second has a time scale of 60. - * - * @return integer - */ - public function getTimescale() { return $this->_timescale; } - - /** - * Returns the duration of this media (in the scale of the timescale). - * - * @return integer - */ - public function getDuration() { return $this->_duration; } - - /** - * Returns the three byte language code to describe the language of this - * media, according to {@link http://www.loc.gov/standards/iso639-2/ - * ISO 639-2/T}. - * - * @return string - */ - public function getLanguage() { return $this->_language; } -} diff --git a/src/ISO14496/Box/MDIA.php b/src/ISO14496/Box/MDIA.php deleted file mode 100644 index 70f399a..0000000 --- a/src/ISO14496/Box/MDIA.php +++ /dev/null @@ -1,71 +0,0 @@ -Media Box contains all the objects that declare information about - * the media data within a track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MDIA extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 8d25d95..0000000 --- a/src/ISO14496/Box/MEHD.php +++ /dev/null @@ -1,84 +0,0 @@ -Movie Extends Header Box is optional, and provides the overall - * duration, including fragments, of a fragmented movie. If this box is not - * present, the overall duration must be computed by examining each fragment. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MEHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_fragmentDuration; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - if ($this->getVersion() == 1) - $this->_fragmentDuration = $this->_reader->readInt64BE(); - else - $this->_fragmentDuration = $this->_reader->readUInt32BE(); - } - - /** - * Returns the length of the presentation of the whole movie including - * fragments (in the timescale indicated in the {@link ISO14496_Box_MVHD - * Movie Header Box}). The value of this field corresponds to the duration of - * the longest track, including movie fragments. - * - * @return integer - */ - public function getFragmentDuration() { return $this->_fragmentDuration; } -} diff --git a/src/ISO14496/Box/META.php b/src/ISO14496/Box/META.php deleted file mode 100644 index 0e7e532..0000000 --- a/src/ISO14496/Box/META.php +++ /dev/null @@ -1,90 +0,0 @@ -Meta Box contains descriptive or annotative metadata. The - * meta box is required to contain a {@link ISO14496_Box_HDLR hdlr} box - * indicating the structure or format of the meta box contents. That - * metadata is located either within a box within this box (e.g. an XML box), or - * is located by the item identified by a primary item box. - * - * All other contained boxes are specific to the format specified by the handler - * box. - * - * The other boxes defined here may be defined as optional or mandatory for a - * given format. If they are used, then they must take the form specified here. - * These optional boxes include a data-information box, which documents other - * files in which metadata values (e.g. pictures) are placed, and a item - * location box, which documents where in those files each item is located (e.g. - * in the common case of multiple pictures stored in the same file). At most one - * meta box may occur at each of the file level, movie level, or track level. - * - * If an {@link ISO14496_Box_IPRO Item Protection Box} occurs, then some or all - * of the meta-data, including possibly the primary resource, may have been - * protected and be un-readable unless the protection system is taken into - * account. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_META extends ISO14496_Box_Full -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index eb64359..0000000 --- a/src/ISO14496/Box/MFHD.php +++ /dev/null @@ -1,80 +0,0 @@ -Movie Fragment Header Box contains a sequence number, as a safety - * check. The sequence number usually starts at 1 and must increase for each - * movie fragment in the file, in the order in which they occur. This allows - * readers to verify integrity of the sequence; it is an error to construct a - * file where the fragments are out of sequence. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MFHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_sequenceNumber; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_sequenceNumber = $this->_reader->readUInt32BE(); - } - - /** - * Returns the ordinal number of this fragment, in increasing order. - * - * @return integer - */ - public function getSequenceNumber() { return $this->_sequenceNumber; } -} diff --git a/src/ISO14496/Box/MFRO.php b/src/ISO14496/Box/MFRO.php deleted file mode 100644 index 08008e2..0000000 --- a/src/ISO14496/Box/MFRO.php +++ /dev/null @@ -1,85 +0,0 @@ -Movie Fragment Random Access Offset Box provides a copy of the - * length field from the enclosing {@link ISO14496_Box_MFRA Movie Fragment - * Random Access Box}. It is placed last within that box, so that the size field - * is also last in the enclosing Movie Fragment Random Access Box. When the - * Movie Fragment Random Access Box is also last in the file this permits its - * easy location. The size field here must be correct. However, neither the - * presence of the Movie Fragment Random Access Box, nor its placement last in - * the file, are assured. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MFRO extends ISO14496_Box_Full -{ - /** @var integer */ - private $_parentSize; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_parentSize = $this->_reader->readUInt32BE(); - } - - /** - * Returns the number of bytes of the enclosing {@link ISO14496_Box_MFRA} box. - * This field is placed at the last of the enclosing box to assist readers - * scanning from the end of the file in finding the mfra box. - * - * @return integer - */ - public function getParentSize() { return $this->_parentSize; } -} diff --git a/src/ISO14496/Box/MINF.php b/src/ISO14496/Box/MINF.php deleted file mode 100644 index cf5dd1b..0000000 --- a/src/ISO14496/Box/MINF.php +++ /dev/null @@ -1,71 +0,0 @@ -Media Information Box contains all the objects that declare - * characteristic information of the media in the track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MINF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 55e3c1c..0000000 --- a/src/ISO14496/Box/MOOF.php +++ /dev/null @@ -1,81 +0,0 @@ -Movie Fragment Box extend the presentation in time. They provide - * the information that would previously have been in the - * {@link ISO14496_Box_MOOV Movie Box}. The actual samples are in - * {@link ISO14496_Box_MDAT Media Data Boxes}, as usual, if they are in the same - * file. The data reference index is in the sample description, so it is - * possible to build incremental presentations where the media data is in files - * other than the file containing the Movie Box. - * - * The Movie Fragment Box is a top-level box, (i.e. a peer to the Movie Box and - * Media Data boxes). It contains a {@link ISO14496_Box_MFHD Movie Fragment - * Header Box}, and then one or more {@link ISO14496_Box_TRAF Track Fragment - * Boxes}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MOOF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 208f200..0000000 --- a/src/ISO14496/Box/MOOV.php +++ /dev/null @@ -1,72 +0,0 @@ -Movie Box - * which occurs at the top-level of a file. Normally this box is close to the - * beginning or end of the file, though this is not required. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MOOV extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index f4d4a4a..0000000 --- a/src/ISO14496/Box/MVEX.php +++ /dev/null @@ -1,74 +0,0 @@ -Movie Extends Box warns readers that there might be - * {@link ISO14496_Box_MFRA Movie Fragment Boxes} in this file. To know of all - * samples in the tracks, these Movie Fragment Boxes must be found and scanned - * in order, and their information logically added to that found in the - * {@link ISO14496_Box_MOOV Movie Box}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MVEX extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index dac4288..0000000 --- a/src/ISO14496/Box/MVHD.php +++ /dev/null @@ -1,166 +0,0 @@ -Movie Header Box defines overall information which is - * media-independent, and relevant to the entire presentation considered as a - * whole. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_MVHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_creationTime; - - /** @var integer */ - private $_modificationTime; - - /** @var integer */ - private $_timescale; - - /** @var integer */ - private $_duration; - - /** @var integer */ - private $_rate; - - /** @var integer */ - private $_volume; - - /** @var integer */ - private $_nextTrackId; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - if ($this->getVersion() == 1) { - $this->_creationTime = $this->_reader->readInt64BE(); - $this->_modificationTime = $this->_reader->readInt64BE(); - $this->_timescale = $this->_reader->readUInt32BE(); - $this->_duration = $this->_reader->readInt64BE(); - } else { - $this->_creationTime = $this->_reader->readUInt32BE(); - $this->_modificationTime = $this->_reader->readUInt32BE(); - $this->_timescale = $this->_reader->readUInt32BE(); - $this->_duration = $this->_reader->readUInt32BE(); - } - $this->_rate = - ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + - ($tmp & 0xffff) / 10; - $this->_volume = ((($tmp = $this->_reader->readUInt16BE()) >> 8) & 0xff) + - ($tmp & 0xff) / 10; - $this->_reader->skip(70); - $this->_nextTrackId = $this->_reader->readUInt32BE(); - } - - /** - * Returns the creation time of the presentation. The value is in seconds - * since midnight, Jan. 1, 1904, in UTC time. - * - * @return integer - */ - public function getCreationTime() { return $this->_creationTime; } - - /** - * Returns the most recent time the presentation was modified. The value is in - * seconds since midnight, Jan. 1, 1904, in UTC time. - * - * @return integer - */ - public function getModificationTime() { return $this->_modificationTime; } - - /** - * Returns the time-scale for the entire presentation. This is the number of - * time units that pass in one second. For example, a time coordinate system - * that measures time in sixtieths of a second has a time scale of 60. - * - * @return integer - */ - public function getTimescale() { return $this->_timescale; } - - /** - * Returns the length of the presentation in the indicated timescale. This - * property is derived from the presentation's tracks: the value of this field - * corresponds to the duration of the longest track in the presentation. - * - * @return integer - */ - public function getDuration() { return $this->_duration; } - - /** - * Returns the preferred rate to play the presentation. 1.0 is normal forward - * playback. - * - * @return integer - */ - public function getRate() { return $this->_rate; } - - /** - * Returns the preferred playback volume. 1.0 is full volume. - * - * @return integer - */ - public function getVolume() { return $this->_volume; } - - /** - * Returns a value to use for the track ID of the next track to be added to - * this presentation. Zero is not a valid track ID value. The value is larger - * than the largest track-ID in use. If this value is equal to or larger than - * 32-bit maxint, and a new media track is to be added, then a search must be - * made in the file for a unused track identifier. - * - * @return integer - */ - public function getNextTrackId() { return $this->_nextTrackId; } -} diff --git a/src/ISO14496/Box/NMHD.php b/src/ISO14496/Box/NMHD.php deleted file mode 100644 index 96ecf5b..0000000 --- a/src/ISO14496/Box/NMHD.php +++ /dev/null @@ -1,55 +0,0 @@ -Null Media Header Box, - * as defined here. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_NMHD extends ISO14496_Box_Full -{ -} diff --git a/src/ISO14496/Box/PADB.php b/src/ISO14496/Box/PADB.php deleted file mode 100644 index e1425ec..0000000 --- a/src/ISO14496/Box/PADB.php +++ /dev/null @@ -1,57 +0,0 @@ -Padding Bits BoxIn some streams the media samples do not occupy - * all bits of the bytes given by the sample size, and are padded at the end to - * a byte boundary. In some cases, it is necessary to record externally the - * number of padding bits used. This table supplies that information. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_PADB extends ISO14496_Box_Full -{ -} diff --git a/src/ISO14496/Box/PDIN.php b/src/ISO14496/Box/PDIN.php deleted file mode 100644 index 5bb3a40..0000000 --- a/src/ISO14496/Box/PDIN.php +++ /dev/null @@ -1,97 +0,0 @@ -Progressive Download Information Box aids the progressive download - * of an ISO file. The box contains pairs of numbers (to the end of the box) - * specifying combinations of effective file download bitrate in units of - * bytes/sec and a suggested initial playback delay in units of milliseconds. - * - * A receiving party can estimate the download rate it is experiencing, and from - * that obtain an upper estimate for a suitable initial delay by linear - * interpolation between pairs, or by extrapolation from the first or last - * entry. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_PDIN extends ISO14496_Box_Full -{ - /** @var Array */ - private $_progressiveDownloadInfo = 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, &$options = array()) - { - parent::__construct($reader, $options); - - while ($this->_reader->getOffset() < $this->getOffset() + $this->getSize()) - $this->_progressiveDownloadInfo[] = array - ("rate" => $this->_reader->readUInt32BE(), - "initialDelay" => $this->_reader->readUInt32BE()); - } - - /** - * Returns the progressive download information array. The array consists of - * items having two keys. - * - * o rate -- the download rate expressed in bytes/second - * o initialDelay -- the suggested delay to use when playing the file, - * such that if download continues at the given rate, all data within the - * file will arrive in time for its use and playback should not need to - * stall. - * - * @return Array - */ - public function getProgressiveDownloadInfo() - { - return $this->_progressiveDownloadInfo; - } -} diff --git a/src/ISO14496/Box/PITM.php b/src/ISO14496/Box/PITM.php deleted file mode 100644 index 465f48d..0000000 --- a/src/ISO14496/Box/PITM.php +++ /dev/null @@ -1,85 +0,0 @@ -Primary Item Box must - * occur, or there must be a box within the meta-box (e.g. an - * {@link ISO14496_Box_XML XML Box}) containing the primary information in the - * format required by the identified handler. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_PITM extends ISO14496_Box_Full -{ - /** @var string */ - private $_itemId; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_itemId = $this->_reader->readUInt16BE(); - } - - /** - * Returns the identifier of the primary item. - * - * @return integer - */ - public function getItemId() - { - return $this->_itemId; - } -} diff --git a/src/ISO14496/Box/SBGP.php b/src/ISO14496/Box/SBGP.php deleted file mode 100644 index 299cccd..0000000 --- a/src/ISO14496/Box/SBGP.php +++ /dev/null @@ -1,132 +0,0 @@ -Sample To Group Box table can be used to find the group that a - * sample belongs to and the associated description of that sample group. The - * table is compactly coded with each entry giving the index of the first sample - * of a run of samples with the same sample group descriptor. The sample group - * description ID is an index that refers to a {@link ISO14496_Box_SGPD Sample - * Group Description Box}, which contains entries describing the characteristics - * of each sample group. - * - * There may be multiple instances of this box if there is more than one sample - * grouping for the samples in a track. Each instance of the Sample To Group Box - * has a type code that distinguishes different sample groupings. Within a - * track, there shall be at most one instance of this box with a particular - * grouping type. The associated Sample Group Description shall indicate the - * same value for the grouping type. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SBGP extends ISO14496_Box_Full -{ - /** @var integer */ - private $_groupingType; - - /** @var Array */ - private $_sampleToGroupTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $groupingType = $this->_reader->readUInt32BE(); - $entryCount = $this->_reader->readUInt32BE(); - $data = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - for ($i = 1; $i <= $entryCount; $i++) - $this->_sampleToGroupTable[$i] = array - ("sampleCount" => - Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)), - "groupDescriptionIndex" => - Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4))); - } - - /** - * Returns the grouping type that identifies the type (i.e. criterion used to - * form the sample groups) of the sample grouping and links it to its sample - * group description table with the same value for grouping type. At most one - * occurrence of this box with the same value for groupingType shall exist for - * a track. - * - * @return integer - */ - public function getGroupingType() - { - return $this->_groupingType; - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o sampleCount -- an integer that gives the number of consecutive samples - * with the same sample group descriptor. If the sum of the sample count - * in this box is less than the total sample count, then the reader should - * effectively extend it with an entry that associates the remaining - * samples with no group. It is an error for the total in this box to be - * greater than the sample_count documented elsewhere, and the reader - * behavior would then be undefined. - * o groupDescriptionIndex -- an integer that gives the index of the sample - * group entry which describes the samples in this group. The index ranges - * from 1 to the number of sample group entries in the - * {@link ISO14496_Box_SGPD Sample Group Description Box}, or takes the - * value 0 to indicate that this sample is a member of no group of this - * type. - * - * @return Array - */ - public function getSampleToGroupTable() - { - return $this->_sampleToGroupTable; - } -} diff --git a/src/ISO14496/Box/SCHI.php b/src/ISO14496/Box/SCHI.php deleted file mode 100644 index 2e7c43e..0000000 --- a/src/ISO14496/Box/SCHI.php +++ /dev/null @@ -1,74 +0,0 @@ -Scheme Information Box is a container Box that is only interpreted - * by the scheme being used. Any information the encryption system needs is - * stored here. The content of this box is a series of boxes whose type and - * format are defined by the scheme declared in the - * {@link ISO14496_Box_SCHM Scheme Type Box}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SCHI extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 148448b..0000000 --- a/src/ISO14496/Box/SCHM.php +++ /dev/null @@ -1,103 +0,0 @@ -Scheme Type Box identifies the protection scheme. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SCHM extends ISO14496_Box_Full -{ - /** @var string */ - private $_schemeType; - - /** @var integer */ - private $_schemeVersion; - - /** @var string */ - private $_schemeUri; - - /** - * 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, &$options = array()) - { - 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->getOffset() + $this->getSize() - $this->_reader->getOffset())); - } - - /** - * Returns the code defining the protection scheme. - * - * @return string - */ - public function getSchemeType() { return $this->_schemeType; } - - /** - * Returns the version of the scheme used to create the content. - * - * @return integer - */ - public function getSchemeVersion() { return $this->_schemeVersion; } - - /** - * Returns the optional scheme address to allow for the option of directing - * the user to a web-page if they do not have the scheme installed on their - * system. It is an absolute URI. - * - * @return string - */ - public function getSchemeUri() { return $this->_schemeUri; } -} diff --git a/src/ISO14496/Box/SDTP.php b/src/ISO14496/Box/SDTP.php deleted file mode 100644 index b5b6818..0000000 --- a/src/ISO14496/Box/SDTP.php +++ /dev/null @@ -1,130 +0,0 @@ -Independent and Disposable Samples Box optional table answers - * three questions about sample dependency: - * 1) does this sample depend on others (is it an I-picture)? - * 2) do no other samples depend on this one? - * 3) does this sample contain multiple (redundant) encodings of the data at - * this time-instant (possibly with different dependencies)? - * - * In the absence of this table: - * 1) the sync sample table answers the first question; in most video codecs, - * I-pictures are also sync points, - * 2) the dependency of other samples on this one is unknown. - * 3) the existence of redundant coding is unknown. - * - * When performing trick modes, such as fast-forward, it is possible to use the - * first piece of information to locate independently decodable samples. - * Similarly, when performing random access, it may be necessary to locate the - * previous sync point or random access recovery point, and roll-forward from - * the sync point or the pre-roll starting point of the random access recovery - * point to the desired point. While rolling forward, samples on which no others - * depend need not be retrieved or decoded. - * - * The value of sampleIsDependedOn is independent of the existence of redundant - * codings. However, a redundant coding may have different dependencies from the - * primary coding; if redundant codings are available, the value of - * sampleDependsOn documents only the primary coding. - * - * A sample dependency Box may also occur in the {@link ISO14496_Box_TRAF Track - * Fragment Box}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SDTP extends ISO14496_Box_Full -{ - /** @var Array */ - private $_sampleDependencyTypeTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $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 = Transform::fromInt8 - ($data[$i - 1])) >> 4) & 0x3, - "sampleIsDependedOn" => ($tmp >> 2) & 0x3, - "sampleHasRedundancy" => $tmp & 0x3); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o sampleDependsOn -- takes one of the following four values: - * 0: the dependency of this sample is unknown; - * 1: this sample does depend on others (not an I picture); - * 2: this sample does not depend on others (I picture); - * 3: reserved - * o sampleIsDependedOn -- takes one of the following four values: - * 0: the dependency of other samples on this sample is unknown; - * 1: other samples depend on this one (not disposable); - * 2: no other sample depends on this one (disposable); - * 3: reserved - * o sampleHasRedundancy -- takes one of the following four values: - * 0: it is unknown whether there is redundant coding in this sample; - * 1: there is redundant coding in this sample; - * 2: there is no redundant coding in this sample; - * 3: reserved - * - * @return Array - */ - public function getSampleDependencyTypeTable() - { - return $this->_sampleDependencyTypeTable; - } -} diff --git a/src/ISO14496/Box/SGPD.php b/src/ISO14496/Box/SGPD.php deleted file mode 100644 index cf60fc4..0000000 --- a/src/ISO14496/Box/SGPD.php +++ /dev/null @@ -1,64 +0,0 @@ -Sample Group Description Box table gives information about the - * characteristics of sample groups. The descriptive information is any other - * information needed to define or characterize the sample group. - * - * There may be multiple instances of this box if there is more than one sample - * grouping for the samples in a track. Each instance of the Sample Group - * Description box has a type code that distinguishes different sample - * groupings. Within a track, there shall be at most one instance of this box - * with a particular grouping type. The associated Sample To Group shall - * indicate the same value for the grouping type. - * - * @todo Data parsing - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SGPD extends ISO14496_Box_Full -{ -} diff --git a/src/ISO14496/Box/SINF.php b/src/ISO14496/Box/SINF.php deleted file mode 100644 index 5651b75..0000000 --- a/src/ISO14496/Box/SINF.php +++ /dev/null @@ -1,87 +0,0 @@ -Protection Scheme Information Box contains all the information - * required both to understand the encryption transform applied and its - * parameters, and also to find other information such as the kind and location - * of the key management system. It also documents the original (unencrypted) - * format of the media. The Protection Scheme Info Box is a container Box. It is - * mandatory in a sample entry that uses a code indicating a protected stream. - * - * When used in a protected sample entry, this box must contain the original - * format box to document the original format. At least one of the following - * signaling methods must be used to identify the protection applied: - * - * a) MPEG-4 systems with IPMP: no other boxes, when IPMP descriptors in MPEG-4 - * systems streams are used; - * b) Standalone IPMP: an {@link ISO14496_Box_IMIF IPMP Info Box}, when IPMP - * descriptors outside MPEG-4 systems are used; - * c) Scheme signaling: a {@link ISO14496_Box_SCHM Scheme Type Box} and - * {@link ISO14496_Box_SCHI Scheme Information Box}, when these are used - * (either both must occur, or neither). - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SINF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index fa8ab98..0000000 --- a/src/ISO14496/Box/SKIP.php +++ /dev/null @@ -1,73 +0,0 @@ -Free Space Box are irrelevant and may be ignored, or - * the object deleted, without affecting the presentation. (Care should be - * exercised when deleting the object, as this may invalidate the offsets used - * in the sample table, unless this object is after all the media data). - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SKIP extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 9881452..0000000 --- a/src/ISO14496/Box/SMHD.php +++ /dev/null @@ -1,66 +0,0 @@ -Sound Media Header Box contains general presentation information, - * independent of the coding, for audio media. This header is used for all - * tracks containing audio. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SMHD extends ISO14496_Box_Full -{ - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - } -} diff --git a/src/ISO14496/Box/STBL.php b/src/ISO14496/Box/STBL.php deleted file mode 100644 index 8793f77..0000000 --- a/src/ISO14496/Box/STBL.php +++ /dev/null @@ -1,90 +0,0 @@ -Sample Table Box contains all the time and data indexing of the - * media samples in a track. Using the tables here, it is possible to locate - * samples in time, determine their type (e.g. I-frame or not), and determine - * their size, container, and offset into that container. - * - * If the track that contains the Sample Table Box references no data, then the - * Sample Table Box does not need to contain any sub-boxes (this is not a very - * useful media track). - * - * If the track that the Sample Table Box is contained in does reference data, - * then the following sub-boxes are required: {@link ISO14496_Box_STSD Sample - * Description}, {@link ISO14496_Box_STSZ Sample Size}, - * {@link ISO14496_Box_STSC Sample To Chunk}, and {@link ISO14496_Box_STCO Chunk - * Offset}. Further, the {@link ISO14496_Box_STSD Sample Description Box} shall - * contain at least one entry. A Sample Description Box is required because it - * contains the data reference index field which indicates which - * {@link ISO14496_Box_DREF Data Reference Box} to use to retrieve the media - * samples. Without the Sample Description, it is not possible to determine - * where the media samples are stored. The {@link ISO14496_Box_STSS Sync Sample - * Box} is optional. If the Sync Sample Box is not present, all samples are sync - * samples. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STBL extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index de83e94..0000000 --- a/src/ISO14496/Box/STCO.php +++ /dev/null @@ -1,122 +0,0 @@ -Chunk Offset Box table gives the index of each chunk into the - * containing file. There are two variants, permitting the use of 32-bit or - * 64-bit offsets. The latter is useful when managing very large presentations. - * At most one of these variants will occur in any single instance of a sample - * table. - * - * Offsets are file offsets, not the offset into any box within the file (e.g. - * {@link ISO14496_Box_MDAT Media Data Box}). This permits referring to media - * data in files without any box structure. It does also mean that care must be - * taken when constructing a self-contained ISO file with its metadata - * ({@link ISO14496_Box_MOOV Movie Box}) at the front, as the size of the - * {@link ISO14496_Box_MOOV Movie Box} will affect the chunk offsets to the - * media data. - * - * This box variant contains 32-bit offsets. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STCO extends ISO14496_Box_Full -{ - /** @var Array */ - private $_chunkOffsetTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $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)); - } - - /** - * Returns an array of values. Each entry has 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. - * - * @return Array - */ - 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) - { - $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 deleted file mode 100644 index 5eb371c..0000000 --- a/src/ISO14496/Box/STDP.php +++ /dev/null @@ -1,84 +0,0 @@ -Degradation Priority Box contains the degradation priority of each - * sample. Specifications derived from this define the exact meaning and - * acceptable range of the priority field. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STDP extends ISO14496_Box_Full -{ - /** @var Array */ - private $_values = 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, &$options = array()) - { - parent::__construct($reader, $options); - - while ($this->_reader->getOffset() < $this->getOffset() + $this->getSize()) - $this->_values[] = array("priority" => $this->_reader->readUInt16BE()); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o priority: specifies the degradation priority for each sample segment. - * - * @return Array - */ - public function getValues() - { - return $this->_values; - } -} diff --git a/src/ISO14496/Box/STSC.php b/src/ISO14496/Box/STSC.php deleted file mode 100644 index b0fc13e..0000000 --- a/src/ISO14496/Box/STSC.php +++ /dev/null @@ -1,110 +0,0 @@ -Sample To Chunk Box table can be used to find the chunk that - * contains a sample, its position, and the associated sample description. - * - * The table is compactly coded. Each entry gives the index of the first chunk - * of a run of chunks with the same characteristics. By subtracting one entry - * here from the previous one, you can compute how many chunks are in this run. - * You can convert this to a sample count by multiplying by the appropriate - * samplesPerChunk. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STSC extends ISO14496_Box_Full -{ - /** @var Array */ - private $_sampleToChunkTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - $data = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - for ($i = 1; $i <= $entryCount; $i++) - $this->_sampleToChunkTable[$i] = array - ("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))); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o firstChunk -- an integer that gives the index of the first chunk in - * this run of chunks that share the same samplesPerChunk and - * sampleDescriptionIndex; the index of the first chunk in a track has the - * value 1 (the firstChunk field in the first record of this box has the - * value 1, identifying that the first sample maps to the first chunk). - * o samplesPerChunk is an integer that gives the number of samples in each - * of these chunks. - * o sampleDescriptionIndex is an integer that gives the index of the sample - * entry that describes the samples in this chunk. The index ranges from 1 - * to the number of sample entries in the {@link ISO14496_Box_STSD Sample - * Description Box}. - * - * @return Array - */ - public function getSampleToChunkTable() - { - return $this->_sampleToChunkTable; - } -} diff --git a/src/ISO14496/Box/STSD.php b/src/ISO14496/Box/STSD.php deleted file mode 100644 index aa90e67..0000000 --- a/src/ISO14496/Box/STSD.php +++ /dev/null @@ -1,56 +0,0 @@ -Sample Description Box table gives detailed information about the - * coding type used, and any initialization information needed for that coding. - * - * @todo Data parsing - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STSD extends ISO14496_Box_Full -{ -} diff --git a/src/ISO14496/Box/STSH.php b/src/ISO14496/Box/STSH.php deleted file mode 100644 index 3990a0e..0000000 --- a/src/ISO14496/Box/STSH.php +++ /dev/null @@ -1,117 +0,0 @@ -Shadow Sync Sample Box table provides an optional set of sync - * samples that can be used when seeking or for similar purposes. In normal - * forward play they are ignored. - * - * Each entry in the Shadow Sync Table consists of a pair of sample numbers. The - * first entry (shadowedSampleNumber) indicates the number of the sample that a - * shadow sync will be defined for. This should always be a non-sync sample - * (e.g. a frame difference). The second sample number (syncSampleNumber) - * indicates the sample number of the sync sample (i.e. key frame) that can be - * used when there is a random access at, or before, the shadowedSampleNumber. - * - * The shadow sync samples are normally placed in an area of the track that is - * not presented during normal play (edited out by means of an edit list), - * though this is not a requirement. The shadow sync table can be ignored and - * the track will play (and seek) correctly if it is ignored (though perhaps not - * optimally). - * - * The Shadow Sync Sample replaces, not augments, the sample that it shadows - * (i.e. the next sample sent is shadowedSampleNumber+1). The shadow sync sample - * is treated as if it occurred at the time of the sample it shadows, having the - * duration of the sample it shadows. - * - * Hinting and transmission might become more complex if a shadow sample is used - * also as part of normal playback, or is used more than once as a shadow. In - * this case the hint track might need separate shadow syncs, all of which can - * get their media data from the one shadow sync in the media track, to allow - * for the different time-stamps etc. needed in their headers. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STSH extends ISO14496_Box_Full -{ - /** @var Array */ - private $_shadowSyncSampleTable = 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, &$options = array()) - { - 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" => - Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)), - "syncSampleNumber" => - Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4))); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o shadowedSampleNumber - gives the number of a sample for which there is - * an alternative sync sample. - * o syncSampleNumber - gives the number of the alternative sync sample. - * - * @return Array - */ - public function getShadowSyncSampleTable() - { - return $this->_shadowSyncSampleTable; - } -} diff --git a/src/ISO14496/Box/STSS.php b/src/ISO14496/Box/STSS.php deleted file mode 100644 index c5c3285..0000000 --- a/src/ISO14496/Box/STSS.php +++ /dev/null @@ -1,89 +0,0 @@ -Sync Sample Box provides a compact marking of the random access - * points within the stream. The table is arranged in strictly increasing order - * of sample number. If the sync sample box is not present, every sample is a - * random access point. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STSS extends ISO14496_Box_Full -{ - /** @var Array */ - private $_syncSampleTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $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)); - } - - /** - * Returns an array of values. Each entry has the entry number as its index - * and an integer that gives the numbers of the samples that are random access - * points in the stream as its value. - * - * @return Array - */ - public function getSyncSampleTable() - { - return $this->_syncSampleTable; - } -} diff --git a/src/ISO14496/Box/STSZ.php b/src/ISO14496/Box/STSZ.php deleted file mode 100644 index 264900e..0000000 --- a/src/ISO14496/Box/STSZ.php +++ /dev/null @@ -1,110 +0,0 @@ -Sample Size Box contains the sample count and a table giving the - * size in bytes of each sample. This allows the media data itself to be - * unframed. The total number of samples in the media is always indicated in the - * sample count. - * - * There are two variants of the sample size box. The first variant has a fixed - * size 32-bit field for representing the sample sizes; it permits defining a - * constant size for all samples in a track. The second variant permits smaller - * size fields, to save space when the sizes are varying but small. One of these - * boxes must be present; the first version is preferred for maximum - * compatibility. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STSZ extends ISO14496_Box_Full -{ - /** @var integer */ - private $_sampleSize; - - /** @var Array */ - private $_sampleSizeTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_sampleSize = $this->_reader->readUInt32BE(); - $sampleCount = $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)); - } - } - - /** - * Returns the default sample size. If all the samples are the same size, this - * field contains that size value. If this field is set to 0, then the samples - * have different sizes, and those sizes are stored in the sample size table. - * - * @return integer - */ - public function getSampleSize() { return $this->_sampleSize; } - - /** - * Returns an array of sample sizes specifying the size of a sample, indexed - * by its number. - * - * @return Array - */ - public function getSampleSizeTable() - { - return $this->_sampleSizeTable; - } -} diff --git a/src/ISO14496/Box/STTS.php b/src/ISO14496/Box/STTS.php deleted file mode 100644 index 446abd4..0000000 --- a/src/ISO14496/Box/STTS.php +++ /dev/null @@ -1,110 +0,0 @@ -Decoding Time to Sample Box contains a compact version of a table - * that allows indexing from decoding time to sample number. Other tables give - * sample sizes and pointers, from the sample number. Each entry in the table - * gives the number of consecutive samples with the same time delta, and the - * delta of those samples. By adding the deltas a complete time-to-sample map - * may be built. - * - * The Decoding Time to Sample Box contains decode time delta's: DT(n+1) = DT(n) - * + STTS(n) where STTS(n) is the (uncompressed) table entry for sample n. - * - * The sample entries are ordered by decoding time stamps; therefore the deltas - * are all non-negative. - * - * The DT axis has a zero origin; DT(i) = SUM(for j=0 to i-1 of delta(j)), and - * the sum of all deltas gives the length of the media in the track (not mapped - * to the overall timescale, and not considering any edit list). - * - * The {@link ISO14496_Box_ELST Edit List Box} provides the initial CT value if - * it is non-empty (non-zero). - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STTS extends ISO14496_Box_Full -{ - /** @var Array */ - private $_timeToSampleTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - $data = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - for ($i = 1; $i <= $entryCount; $i++) - $this->_timeToSampleTable[$i] = array - ("sampleCount" => - Transform::fromUInt32BE(substr($data, ($i - 1) * 8, 4)), - "sampleDelta" => - Transform::fromUInt32BE(substr($data, $i * 8 - 4, 4))); - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o sampleCount -- an integer that counts the number of consecutive samples - * that have the given duration. - * o sampleDelta -- an integer that gives the delta of these samples in the - * time-scale of the media. - * - * @return Array - */ - public function getTimeToSampleTable() - { - return $this->_timeToSampleTable; - } -} diff --git a/src/ISO14496/Box/STZ2.php b/src/ISO14496/Box/STZ2.php deleted file mode 100644 index fdcdc1b..0000000 --- a/src/ISO14496/Box/STZ2.php +++ /dev/null @@ -1,109 +0,0 @@ -Sample Size Box contains the sample count and a table giving the - * size in bytes of each sample. This allows the media data itself to be - * unframed. The total number of samples in the media is always indicated in the - * sample count. - * - * There are two variants of the sample size box. This variant permits smaller - * than 32-bit size fields, to save space when the sizes are varying but small. - * One of the boxes must be present; the {@link ISO14496_Box_STSZ another - * variant} is preferred for maximum compatibility. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_STZ2 extends ISO14496_Box_Full -{ - /** @var Array */ - private $_sampleSizeTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_reader->skip(3); - $fieldSize = $this->_reader->readInt8(); - $sampleCount = $this->_reader->readUInt32BE(); - $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 = Transform::fromInt8($data[$i - 1])) >> 4) & 0xf; - if ($i + 1 < $sampleCount) - $this->_sampleSizeTable[$i++] = $tmp & 0xf; - break; - case 8: - $this->_sampleSizeTable[$i] = Transform::fromInt8($data[$i - 1]); - break; - case 16: - $this->_sampleSizeTable[$i] = - Transform::fromUInt16BE(substr($data, ($i - 1) * 2, 2)); - break; - } - } - } - - /** - * Returns an array of sample sizes specifying the size of a sample, indexed - * by its number. - * - * @return Array - */ - public function getSampleSizeTable() - { - return $this->_sampleSizeTable; - } -} diff --git a/src/ISO14496/Box/SUBS.php b/src/ISO14496/Box/SUBS.php deleted file mode 100644 index eeda868..0000000 --- a/src/ISO14496/Box/SUBS.php +++ /dev/null @@ -1,138 +0,0 @@ -Sub-Sample Information Box is designed to contain sub-sample - * information. - * - * A sub-sample is a contiguous range of bytes of a sample. The specific - * definition of a sub-sample shall be supplied for a given coding system (e.g. - * for ISO/IEC 14496-10, Advanced Video Coding). In the absence of such a - * specific definition, this box shall not be applied to samples using that - * coding system. - * - * If subsample_count is 0 for any entry, then those samples have no subsample - * information and no array follows. The table is sparsely coded; the table - * identifies which samples have sub-sample structure by recording the - * difference in sample-number between each entry. The first entry in the table - * records the sample number of the first sample having sub-sample information. - * - * Note: It is possible to combine subsamplePriority and discardable such that - * when subsamplePriority is smaller than a certain value, discardable is set to - * 1. However, since different systems may use different scales of priority - * values, to separate them is safe to have a clean solution for discardable - * sub-samples. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_SUBS extends ISO14496_Box_Full -{ - /** @var Array */ - private $_subSampleTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $entryCount = $this->_reader->readUInt32BE(); - for ($i = 0; $i < $entryCount; $i++) { - $entry = array(); - $entry["sampleDelta"] = $this->_reader->readUInt32BE(); - $entry["subsamples"] = array(); - if (($subsampleCount = $this->_reader->readUInt16BE()) > 0) { - for ($j = 0; $j < $subsampleCount; $j++) { - $subsample = array(); - if ($this->getVersion() == 1) - $subsample["subsampleSize"] = $this->_reader->readUInt32BE(); - else - $subsample["subsampleSize"] = $this->_reader->readUInt16BE(); - $subsample["subsamplePriority"] = $this->_reader->readInt8(); - $subsample["discardable"] = $this->_reader->readInt8(); - $this->_reader->skip(4); - $entry["subsamples"][] = $subsample; - } - $this->_subSampleTable[] = $entry; - } - } - } - - /** - * Returns an array of values. Each entry is an array containing the following - * keys. - * o sampleDelta -- an integer that specifies the sample number of the - * sample having sub-sample structure. It is coded as the difference - * between the desired sample number, and the sample number indicated in - * the previous entry. If the current entry is the first entry, the value - * indicates the sample number of the first sample having sub-sample - * information, that is, the value is the difference between the sample - * number and zero (0). - * o subsamples -- an array of subsample arrays, each containing the - * following keys. - * o subsampleSize -- an integer that specifies the size, in bytes, of - * the current sub-sample. - * o subsamplePriority -- an integer specifying the degradation priority - * for each sub-sample. Higher values of subsamplePriority, indicate - * sub-samples which are important to, and have a greater impact on, - * the decoded quality. - * o discardable -- equal to 0 means that the sub-sample is required to - * decode the current sample, while equal to 1 means the sub-sample is - * not required to decode the current sample but may be used for - * enhancements, e.g., the sub-sample consists of supplemental - * enhancement information (SEI) messages. - * - * @return Array - */ - public function getSubSampleTable() - { - return $this->_subSampleTable; - } -} diff --git a/src/ISO14496/Box/TFHD.php b/src/ISO14496/Box/TFHD.php deleted file mode 100644 index 3126308..0000000 --- a/src/ISO14496/Box/TFHD.php +++ /dev/null @@ -1,194 +0,0 @@ -Track Fragment Header Box to - * each track; and a track fragment can add zero or more contiguous runs of - * samples. The track fragment header sets up information and defaults used for - * those runs of samples. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @author Anders Ă–dlund - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TFHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_trackId; - - /** @var integer */ - private $_baseDataOffset; - - /** @var integer */ - private $_sampleDescriptionIndex; - - /** @var integer */ - private $_defaultSampleDuration; - - /** @var integer */ - private $_defaultSampleSize; - - /** @var integer */ - private $_defaultSampleFlags; - - /** - * Indicates indicates the presence of the baseDataOffset field. This provides - * an explicit anchor for the data offsets in each track run (see below). If - * not provided, the base-dataoffset for the first track in the movie fragment - * is the position of the first byte of the enclosing Movie Fragment Box, and - * for second and subsequent track fragments, the default is the end of the - * data defined by the preceding fragment. Fragments inheriting their offset - * in this way must all use the same data-reference (i.e., the data for these - * tracks must be in the same file). - */ - const BASE_DATA_OFFSET = 0x1; - - /** - * Indicates the presence of the sampleDescriptionIndex field, which - * over-rides, in this fragment, the default set up in the - * {@link ISO14496_Box_TREX Track Extends Box}. - */ - const SAMPLE_DESCRIPTION_INDEX = 0x2; - - /** Indicates the precense of the defaultSampleDuration field. */ - const DEFAULT_SAMPLE_DURATION = 0x8; - - /** Indicates the precense of the defaultSampleSize field. */ - const DEFAULT_SAMPLE_SIZE = 0x10; - - /** Indicates the precense of the defaultSampleFlags field. */ - const DEFAULT_SAMPLE_FLAGS = 0x20; - - /** - * Indicates that the duration provided in either defaultSampleDuration, or by - * the defaultDuration in the {@link ISO14496_Box_TREX Track Extends Box}, is - * empty, i.e. that there are no samples for this time interval. - */ - const DURATION_IS_EMPTY = 0x10000; - - /** - * Constructs the class with given parameters and reads box related data from - * the ISO Base Media file. - * - * @param Reader $reader The reader object. - * @todo The sample flags could be parsed further - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_trackId = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::BASE_DATA_OFFSET)) - $this->_baseDataOffset = $this->_reader->readInt64BE(); - if ($this->hasFlag(self::SAMPLE_DESCRIPTION_INDEX)) - $this->_sampleDescriptionIndex = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::DEFAULT_SAMPLE_DURATION)) - $this->_defaultSampleDuration = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::DEFAULT_SAMPLE_SIZE)) - $this->_defaultSampleSize = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::DEFAULT_SAMPLE_FLAGS)) - $this->_defaultSampleFlags = $this->_reader->readUInt32BE(); - } - - /** - * Returns the track identifier. - * - * @return integer - */ - public function getTrackId() - { - return $this->_trackId; - } - - /** - * Returns the base offset to use when calculating data offsets. - * - * @return integer - */ - public function getBaseDataOffset() - { - return $this->_baseDataOffset; - } - - /** - * Returns the sample description index. - * - * @return integer - */ - public function getSampleDescriptionIndex() - { - return $this->_sampleDescriptionIndex; - } - - /** - * Returns the default sample duration. - * - * @return integer - */ - public function getDefaultSampleDuration() - { - return $this->_defaultSampleDuration; - } - - /** - * Returns the default sample size. - * - * @return integer - */ - public function getDefaultSampleSize() - { - return $this->_defaultSampleSize; - } - - /** - * Returns the default sample flags. - * - * @return integer - */ - public function getDefaultSampleFlags() - { - return $this->_defaultSampleFlags; - } -} diff --git a/src/ISO14496/Box/TFRA.php b/src/ISO14496/Box/TFRA.php deleted file mode 100644 index 177f6df..0000000 --- a/src/ISO14496/Box/TFRA.php +++ /dev/null @@ -1,142 +0,0 @@ -Track Fragment Random Access Box does not mean that - * all the samples are sync samples. Random access information in the - * {@link ISO14496_Box_TRUN Track Fragment Run Box}, - * {@link ISO14496_Box_TRAF Track Fragment Box} and - * {@link ISO14496_Box_TREX Track Fragment Box} shall be set appropriately - * regardless of the presence of this box. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TFRA extends ISO14496_Box_Full -{ - /** @var integer */ - private $_trackId; - - /** @var Array */ - private $_degradationPriorityTable = 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_trackId = $this->_reader->readUInt32BE(); - - $trafNumberSize = (($tmp = $this->_reader->readUInt32BE()) >> 4) & 0x3; - $trunNumberSize = ($tmp >> 2) & 0x3; - $sampleNumberSize = $tmp & 0x3; - $entryCount = $this->_reader->readUInt32BE(); - for ($i = 1; $i <= $entryCount; $i++) { - $entry = array(); - if ($this->getVersion() == 1) { - $entry["time"] = $this->_reader->readInt64BE(); - $entry["moofOffset"] = $this->_reader->readInt64BE(); - } else { - $entry["time"] = $this->_reader->readUInt32BE(); - $entry["moofOffset"] = $this->_reader->readUInt32BE(); - } - $entry["trafNumber"] = - ($trafNumberSize == 4 ? $this->_reader->readUInt32BE() : - ($trafNumberSize == 8 ? $this->_reader->readInt64BE() : 0)); - $entry["trunNumber"] = - ($trunNumberSize == 4 ? $this->_reader->readUInt32BE() : - ($trunNumberSize == 8 ? $this->_reader->readInt64BE() : 0)); - $entry["sampleNumber"] = - ($sampleNumberSize == 4 ? $this->_reader->readUInt32BE() : - ($sampleNumberSize == 8 ? $this->_reader->readInt64BE() : 0)); - $this->_degradationPriorityTable[$i] = $entry; - } - } - - /** - * Returns the track identifier. - * - * @return integer - */ - public function getTrackId() { return $this->_trackId; } - - /** - * Returns an array of entries. Each entry is an array containing the - * following keys. - * o time -- a 32 or 64 bits integer that indicates the presentation time of - * the random access sample in units defined in the - * {@link ISO14496_Box_MDHD Media Header Box} of the associated track. - * o moofOffset -- a 32 or 64 bits integer that gives the offset of the - * {@link ISO14496_Box_MOOF Movie Fragment Box} used in this entry. Offset - * is the byte-offset between the beginning of the file and the beginning - * of the Movie Fragment Box. - * o trafNumber -- indicates the {@link ISO14496_Box_TRAF Track Fragment - * Box} number that contains the random accessible sample. The number - * ranges from 1 (the first traf is numbered 1) in each Track Fragment - * Box. - * o trunNumber -- indicates the {@link ISO14496_Box_TRUN Track Fragment Run - * Box} number that contains the random accessible sample. The number - * ranges from 1 in each Track Fragment Run Box. - * o sampleNumber -- indicates the sample number that contains the random - * accessible sample. The number ranges from 1 in each Track Fragment Run - * Box. - * - * @return Array - */ - public function getDegradationPriorityTable() - { - return $this->_degradationPriorityTable; - } -} diff --git a/src/ISO14496/Box/TKHD.php b/src/ISO14496/Box/TKHD.php deleted file mode 100644 index f27e39d..0000000 --- a/src/ISO14496/Box/TKHD.php +++ /dev/null @@ -1,177 +0,0 @@ -Track Header Box specifies the characteristics of a single track. - * Exactly one Track Header Box is contained in a track. - * - * In the absence of an edit list, the presentation of a track starts at the - * beginning of the overall presentation. An empty edit is used to offset the - * start time of a track. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TKHD extends ISO14496_Box_Full -{ - /** @var integer */ - private $_creationTime; - - /** @var integer */ - private $_modificationTime; - - /** @var integer */ - private $_trackId; - - /** @var integer */ - private $_duration; - - /** @var integer */ - private $_width; - - /** @var integer */ - private $_height; - - /** - * Indicates that the track is enabled. A disabled track is treated as if it - * were not present. - */ - const TRACK_ENABLED = 1; - - /** Indicates that the track is used in the presentation. */ - const TRACK_IN_MOVIE = 2; - - /** Indicates that the track is used when previewing the presentation. */ - const TRACK_IN_PREVIEW = 4; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - if ($this->getVersion() == 1) { - $this->_creationTime = $this->_reader->readInt64BE(); - $this->_modificationTime = $this->_reader->readInt64BE(); - $this->_trackId = $this->_reader->readUInt32BE(); - $this->_reader->skip(4); - $this->_duration = $this->_reader->readInt64BE(); - } else { - $this->_creationTime = $this->_reader->readUInt32BE(); - $this->_modificationTime = $this->_reader->readUInt32BE(); - $this->_trackId = $this->_reader->readUInt32BE(); - $this->_reader->skip(4); - $this->_duration = $this->_reader->readUInt32BE(); - } - $this->_reader->skip(52); - $this->_width = - ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + - ($tmp & 0xffff) / 10; - $this->_height = - ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + - ($tmp & 0xffff) / 10; - } - - /** - * Returns the creation time of this track in seconds since midnight, Jan. 1, - * 1904, in UTC time. - * - * @return integer - */ - public function getCreationTime() { return $this->_creationTime; } - - /** - * Returns the most recent time the track was modified in seconds since - * midnight, Jan. 1, 1904, in UTC time. - * - * @return integer - */ - public function getModificationTime() { return $this->_modificationTime; } - - /** - * Returns a number that uniquely identifies this track over the entire - * life-time of this presentation. Track IDs are never re-used and cannot be - * zero. - * - * @return integer - */ - public function getTrackId() { return $this->_trackId; } - - /** - * Returns the duration of this track (in the timescale indicated in the - * {@link MVHD Movie Header Box}). The value of this field is equal to the sum - * of the durations of all of the track's edits. If there is no edit list, - * then the duration is the sum of the sample durations, converted into the - * timescale in the {@link MVHD Movie Header Box}. If the duration of this - * track cannot be determined then duration is set to all 32-bit maxint. - * - * @return integer - */ - public function getDuration() { return $this->_duration; } - - /** - * Returns the track's visual presentation width. This needs not be the same - * as the pixel width of the images; all images in the sequence are scaled to - * this width, before any overall transformation of the track represented by - * the matrix. The pixel width of the images is the default value. - * - * @return integer - */ - public function getWidth() { return $this->_rate; } - - /** - * Returns the track's visual presentation height. This needs not be the same - * as the pixel height of the images; all images in the sequence are scaled to - * this height, before any overall transformation of the track represented by - * the matrix. The pixel height of the images is the default value. - * - * @return integer - */ - public function getHeight() { return $this->_volume; } -} diff --git a/src/ISO14496/Box/TRAF.php b/src/ISO14496/Box/TRAF.php deleted file mode 100644 index 69a7bb7..0000000 --- a/src/ISO14496/Box/TRAF.php +++ /dev/null @@ -1,77 +0,0 @@ -Track Fragment Box there is a set of track fragments, zero - * or more per track. The track fragments in turn contain zero or more track - * runs, each of which document a contiguous run of samples for that track. - * - * Within these structures, many fields are optional and can be defaulted. It is - * possible to add empty time to a track using these structures, as well as - * adding samples. Empty inserts can be used in audio tracks doing silence - * suppression, for example. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TRAF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 8d6110f..0000000 --- a/src/ISO14496/Box/TRAK.php +++ /dev/null @@ -1,83 +0,0 @@ -Track Box is a container box for a single track of a presentation. - * A presentation consists of one or more tracks. Each track is independent of - * the other tracks in the presentation and carries its own temporal and spatial - * information. Each track will contain its associated {@link ISO14496_Box_MDIA - * Media Box}. - * - * Tracks are used for two purposes: - * (a) to contain media data (media tracks) and - * (b) to contain packetization information for streaming protocols - * (hint tracks). - * There shall be at least one media track within an ISO file, and all the media - * tracks that contributed to the hint tracks shall remain in the file, even if - * the media data within them is not referenced by the hint tracks; after - * deleting all hint tracks, the entire un-hinted presentation shall remain. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TRAK extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 33e7f27..0000000 --- a/src/ISO14496/Box/TREF.php +++ /dev/null @@ -1,81 +0,0 @@ -Track Reference Box provides a reference from the containing track - * to another track in the presentation. These references are typed. A {@link - * ISO14496_Box_HINT hint} reference links from the containing hint track to the - * media data that it hints. A content description reference {@link - * ISO14496_Box_CDSC cdsc} links a descriptive or metadata track to the content - * which it describes. - * - * Exactly one Track Reference Box can be contained within the {@link - * ISO14496_Box_TRAK Track Box}. - * - * If this box is not present, the track is not referencing any other track in - * any way. The reference array is sized to fill the reference type box. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TREF extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index b0e4361..0000000 --- a/src/ISO14496/Box/TREX.php +++ /dev/null @@ -1,138 +0,0 @@ -Track Extends Box sets up default values used by the movie - * fragments. By setting defaults in this way, space and complexity can be saved - * in each {@link ISO14496_Box_TRAF Track Fragment Box}. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TREX extends ISO14496_Box_Full -{ - /** @var integer */ - private $_trackId; - - /** @var integer */ - private $_defaultSampleDescriptionIndex; - - /** @var integer */ - private $_defaultSampleDuration; - - /** @var integer */ - private $_defaultSampleSize; - - /** @var integer */ - private $_defaultSampleFlags; - - /** - * Constructs the class with given parameters and reads box related data from - * the ISO Base Media file. - * - * @param Reader $reader The reader object. - * @todo The sample flags could be parsed further - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_trackId = $this->_reader->readUInt32BE(); - $this->_defaultSampleDescriptionIndex = $this->_reader->readUInt32BE(); - $this->_defaultSampleDuration = $this->_reader->readUInt32BE(); - $this->_defaultSampleSize = $this->_reader->readUInt32BE(); - $this->_defaultSampleFlags = $this->_reader->readUInt32BE(); - } - - /** - * Returns the default track identifier. - * - * @return integer - */ - public function getTrackId() - { - return $this->_trackId; - } - - /** - * Returns the default sample description index. - * - * @return integer - */ - public function getDefaultSampleDescriptionIndex() - { - return $this->_defaultSampleDescriptionIndex; - } - - /** - * Returns the default sample duration. - * - * @return integer - */ - public function getDefaultSampleDuration() - { - return $this->_defaultSampleDuration; - } - - /** - * Returns the default sample size. - * - * @return integer - */ - public function getDefaultSampleSize() - { - return $this->_defaultSampleSize; - } - - /** - * Returns the default sample flags. - * - * @return integer - */ - public function getDefaultSampleFlags() - { - return $this->_defaultSampleFlags; - } -} diff --git a/src/ISO14496/Box/TRUN.php b/src/ISO14496/Box/TRUN.php deleted file mode 100644 index ced6c9c..0000000 --- a/src/ISO14496/Box/TRUN.php +++ /dev/null @@ -1,150 +0,0 @@ -Track Fragment Run Boxes. If the durationIsEmpty flag is set, - * there are no track runs. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @author Anders Ă–dlund - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_TRUN extends ISO14496_Box_Full -{ - /** @var integer */ - private $_dataOffset; - - /** @var Array */ - private $_samples = array(); - - /** Indicates the precense of the dataOffset field. */ - const DATA_OFFSET = 0x1; - - /** - * Indicates the precense of the firstSampleFlags field; this over-rides the - * default flags for the first sample only. This makes it possible to record - * a group of frames where the first is a key and the rest are difference - * frames, without supplying explicit flags for every sample. If this flag and - * field are used, sampleFlags field shall not be present. - */ - const FIRST_SAMPLE_FLAGS = 0x4; - - /** - * Indicates that each sample has its own duration, otherwise the default is - * used. - */ - const SAMPLE_DURATION = 0x100; - - /** - * Indicates that each sample has its own size, otherwise the default is used. - */ - const SAMPLE_SIZE = 0x200; - - /** - * Indicates that each sample has its own flags, otherwise the default is - * used. - */ - const SAMPLE_FLAGS = 0x400; - - /** - * Indicates that each sample has a composition time offset (e.g. as used for - * I/P/B video in MPEG). - */ - const SAMPLE_COMPOSITION_TIME_OFFSETS = 0x800; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $flags = $this->_flags; - $sampleCount = $this->_reader->readUInt32BE(); - - if ($this->hasFlag(self::DATA_OFFSET)) - $this->_dataOffset = $this->_reader->readInt32BE(); - if ($this->hasFlag(self::FIRST_SAMPLE_FLAGS)) - $this->_flags = $this->_reader->readUInt32BE(); - - for ($i = 0; $i < $sampleCount; $i++) { - $sample = array(); - if ($this->hasFlag(self::SAMPLE_DURATION)) - $sample["duration"] = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::SAMPLE_SIZE)) - $sample["size"] = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::SAMPLE_FLAGS)) - $sample["flags"] = $this->_reader->readUInt32BE(); - if ($this->hasFlag(self::SAMPLE_COMPOSITION_TIME_OFFSETS)) - $sample["compositionTimeOffset"] = $this->_reader->readUInt32BE(); - $this->_samples[] = $sample; - $this->_flags = $flags; - } - } - - /** - * Returns the data offset. - * - * @return integer - */ - public function getDataOffset() - { - return $this->_dataOffset; - } - - /** - * Returns the array of samples. - * - * @return Array - */ - public function getSamples() - { - return $this->_samples; - } -} diff --git a/src/ISO14496/Box/UDTA.php b/src/ISO14496/Box/UDTA.php deleted file mode 100644 index e38b18d..0000000 --- a/src/ISO14496/Box/UDTA.php +++ /dev/null @@ -1,75 +0,0 @@ -User Data Box contains objects that declare user information about - * the containing box and its data (presentation or track). - * - * The User Data Box is a container box for informative user-data. This user - * data is formatted as a set of boxes with more specific box types, which - * declare more precisely their content. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_UDTA extends ISO14496_Box -{ - /** - * 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 = null, &$options = array()) - { - 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 deleted file mode 100644 index 2c210d8..0000000 --- a/src/ISO14496/Box/URL.php +++ /dev/null @@ -1,83 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_URL extends ISO14496_Box_Full -{ - /** @var string */ - private $_location; - - /** - * Indicates that the media data is in the same file as the Movie Box - * containing this data reference. - */ - const SELFCONTAINED = 1; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_location = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - } - - /** - * Returns the location. - * - * @return string - */ - public function getLocation() { return $this->_location; } -} diff --git a/src/ISO14496/Box/URN.php b/src/ISO14496/Box/URN.php deleted file mode 100644 index 6d5ce99..0000000 --- a/src/ISO14496/Box/URN.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_URN extends ISO14496_Box_Full -{ - /** @var string */ - private $_name; - - /** @var string */ - private $_location; - - /** - * Indicates that the media data is in the same file as the Movie Box - * containing this data reference. - */ - const SELFCONTAINED = 1; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - list ($this->_name, $this->_location) = preg_split - ("/\\x00/", $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset())); - } - - /** - * Returns the name. - * - * @return string - */ - public function getName() { return $this->_name; } - - /** - * Returns the location. - * - * @return string - */ - public function getLocation() { return $this->_location; } -} diff --git a/src/ISO14496/Box/VMHD.php b/src/ISO14496/Box/VMHD.php deleted file mode 100644 index a460161..0000000 --- a/src/ISO14496/Box/VMHD.php +++ /dev/null @@ -1,65 +0,0 @@ -Video Media Header Box contains general presentation information, - * independent of the coding, for video media. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_VMHD extends ISO14496_Box_Full -{ - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - } -} diff --git a/src/ISO14496/Box/XML.php b/src/ISO14496/Box/XML.php deleted file mode 100644 index 5d5aa4f..0000000 --- a/src/ISO14496/Box/XML.php +++ /dev/null @@ -1,87 +0,0 @@ -XML Box forms may be used. - * The {@link ISO14496_Box_BXML Binary XML Box} may only be used when there is a - * single well-defined binarization of the XML for that defined format as - * identified by the handler. - * - * Within an XML box the data is in UTF-8 format unless the data starts with a - * byte-order-mark (BOM), which indicates that the data is in UTF-16 format. - * - * @package php-reader - * @subpackage ISO 14496 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class ISO14496_Box_XML extends ISO14496_Box_Full -{ - /** @var string */ - private $_xml; - - /** - * 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, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_xml = $this->_reader->read - ($this->getOffset() + $this->getSize() - $this->_reader->getOffset()); - } - - /** - * Returns the XML data. - * - * @return string - */ - public function getXml() - { - return $this->_xml; - } -} diff --git a/src/ISO14496/Exception.php b/src/ISO14496/Exception.php deleted file mode 100644 index 7e6970d..0000000 --- a/src/ISO14496/Exception.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class ISO14496_Exception extends Exception -{ -} diff --git a/src/MPEG/ABS.php b/src/MPEG/ABS.php deleted file mode 100644 index 6061a18..0000000 --- a/src/MPEG/ABS.php +++ /dev/null @@ -1,395 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @todo Implement validation routines - */ -final class MPEG_ABS extends MPEG_ABS_Object -{ - /** @var integer */ - private $_bytes; - - /** @var Array */ - private $_frames = array(); - - /** @var MPEG_ABS_XINGHeader */ - private $_xingHeader = null; - - /** @var MPEG_ABS_LAMEHeader */ - private $_lameHeader = null; - - /** @var MPEG_ABS_VBRIHeader */ - private $_vbriHeader = null; - - /** @var integer */ - private $_cumulativeBitrate = 0; - - /** @var integer */ - private $_cumulativePlayDuration = 0; - - /** @var integer */ - private $_estimatedBitrate = 0; - - /** @var integer */ - private $_estimatedPlayDuration = 0; - - /** @var integer */ - private $_lastFrameOffset = false; - - - /** - * Constructs the MPEG_ABS class with given file and options. - * - * The following options are currently recognized: - * o readmode -- Can be one of full or lazy and determines when the read of - * frames and their data happens. When in full mode the data is read - * automatically during the instantiation of the frame and all the frames - * are read during the instantiation of this class. While this allows - * faster validation and data fetching, it is unnecessary in terms of - * determining just the play duration of the file. Defaults to lazy. - * - * o estimatePrecision -- Only applicaple with lazy read mode to determine - * the precision of play duration estimate. This precision is equal to how - * many frames are read before fixing the average bitrate that is used to - * calculate the play duration estimate of the whole file. Each frame adds - * about 0.1-0.2ms to the processing of the file. Defaults to 1000. - * - * When in lazy data reading mode it is first checked whether a VBR header is - * found in a file. If so, the play duration is calculated based no its data - * and no further frames are read from the file. If no VBR header is found, - * frames up to estimatePrecision are read to calculate an average bitrate. - * - * Hence, only zero or estimatePrecision number of frames are read - * in lazy data reading mode. The rest of the frames are read automatically - * when directly referenced, ie the data is read when it is needed. - * - * @param string|Reader $filename The path to the file, file descriptor of an - * opened file, or {@link Reader} instance. - * @param Array $options The options array. - */ - public function __construct($filename, $options = array()) - { - if ($filename instanceof Reader) - $reader = &$filename; - else - $reader = new Reader($filename); - - parent::__construct($reader, $options); - - $offset = $this->_reader->getOffset(); - $this->_bytes = $this->_reader->getSize(); - - /* Skip ID3v1 tag */ - $this->_reader->setOffset(-128); - if ($this->_reader->read(3) == "TAG") - $this->_bytes -= 128; - $this->_reader->setOffset($offset); - - /* Skip ID3v2 tag */ - if ($this->_reader->readString8(3) == "ID3") { - require_once("ID3/Header.php"); - $header = new ID3_Header($this->_reader); - $this->_reader->skip - ($header->getSize() + ($header->hasFlag(ID3_Header::FOOTER) ? 10 : 0)); - } - else - $this->_reader->setOffset($offset); - - /* Check for VBR headers */ - $offset = $this->_reader->getOffset(); - - $this->_frames[] = - $firstFrame = new MPEG_ABS_Frame($this->_reader, $options); - - $postoffset = $this->_reader->getOffset(); - - $this->_reader->setOffset - ($offset + 4 + self::$sidesizes - [$firstFrame->getFrequencyType()][$firstFrame->getMode()]); - if (($xing = $this->_reader->readString8(4)) == "Xing" || $xing == "Info") { - require_once("MPEG/ABS/XINGHeader.php"); - $this->_xingHeader = new MPEG_ABS_XINGHeader($this->_reader, $options); - if ($this->_reader->readString8(4) == "LAME") { - require_once("MPEG/ABS/LAMEHeader.php"); - $this->_lameHeader = - new MPEG_ABS_LAMEHeader($this->_reader, $options); - } - - // A header frame is not counted as an audio frame - array_pop($this->_frames); - } - - $this->_reader->setOffset($offset + 4 + 32); - if ($this->_reader->readString8(4) == "VBRI") { - require_once("MPEG/ABS/VBRIHeader.php"); - $this->_vbriHeader = new MPEG_ABS_VBRIHeader($this->_reader, $options); - - // A header frame is not counted as an audio frame - array_pop($this->_frames); - } - - $this->_reader->setOffset($postoffset); - - // Ensure we always have read at least one frame - if (empty($this->_frames)) - $this->_readFrames(1); - - /* Read necessary frames */ - if ($this->getOption("readmode", "lazy") == "lazy") { - if (($header = $this->_xingHeader) !== null || - ($header = $this->_vbriHeader) !== null) { - $this->_estimatedPlayDuration = $header->getFrames() * - $firstFrame->getSamples() / $firstFrame->getSamplingFrequency(); - if ($this->_lameHeader !== null) { - $this->_estimatedBitrate = $this->_lameHeader->getBitrate(); - if ($this->_estimatedBitrate == 255) - $this->_estimatedBitrate = round - (($this->_lameHeader->getMusicLength()) / - (($header->getFrames() * $firstFrame->getSamples()) / - $firstFrame->getSamplingFrequency()) / 1000 * 8); - } - else - $this->_estimatedBitrate = ($this->_bytes - $offset) / - $this->_estimatedPlayDuration / 1000 * 8; - } - else { - $this->_readFrames($this->getOption("estimatePrecision", 1000)); - - $this->_estimatedBitrate = - $this->_cumulativeBitrate / count($this->_frames); - $this->_estimatedPlayDuration = - ($this->_bytes - $offset) / ($this->_estimatedBitrate * 1000 / 8); - } - } - else { - $this->_readFrames(); - - $this->_estimatedBitrate = - $this->_cumulativeBitrate / count($this->_frames); - $this->_estimatedPlayDuration = $this->_cumulativePlayDuration; - } - } - - /** - * Returns true if the audio bitstream contains the Xing VBR - * header, or false otherwise. - * - * @return boolean - */ - public function hasXingHeader() { return $this->_xingHeader === null; } - - /** - * Returns the Xing VBR header, or null if not found in the audio - * bitstream. - * - * @return MPEG_ABS_XINGHeader - */ - public function getXingHeader() { return $this->_xingHeader; } - - /** - * Returns true if the audio bitstream contains the LAME VBR - * header, or false otherwise. - * - * @return boolean - */ - public function hasLameHeader() { return $this->_lameHeader === null; } - - /** - * Returns the LAME VBR header, or null if not found in the audio - * bitstream. - * - * @return MPEG_ABS_LAMEHeader - */ - public function getLameHeader() { return $this->_lameHeader; } - - /** - * Returns true if the audio bitstream contains the Fraunhofer IIS - * VBR header, or false otherwise. - * - * @return boolean - */ - public function hasVbriHeader() { return $this->_vbriHeader === null; } - - /** - * Returns the Fraunhofer IIS VBR header, or null if not found in - * the audio bitstream. - * - * @return MPEG_ABS_VBRIHeader - */ - public function getVbriHeader() { return $this->_vbriHeader; } - - /** - * Returns the bitrate estimate. This value is either fetched from one of the - * headers or calculated based on the read frames. - * - * @return integer - */ - public function getBitrateEstimate() - { - return $this->_estimatedBitrate; - } - - /** - * For variable bitrate files this method returns the exact average bitrate of - * the whole file. - * - * @return integer - */ - public function getBitrate() - { - if ($this->getOption("readmode", "lazy") == "lazy") - $this->_readFrames(); - return $this->_cumulativeBitrate / count($this->_frames); - } - - /** - * Returns the playtime estimate, in seconds. - * - * @return integer - */ - public function getLengthEstimate() - { - return $this->_estimatedPlayDuration; - } - - /** - * Returns the exact playtime in seconds. In lazy reading mode the frames are - * read from the file the first time you call this method to get the exact - * playtime of the file. - * - * @return integer - */ - public function getLength() - { - if ($this->getOption("readmode", "lazy") == "lazy") - $this->_readFrames(); - return $this->_cumulativePlayDuration; - } - - /** - * Returns the playtime estimate as a string in the form of - * [hours:]minutes:seconds.milliseconds. - * - * @param integer $seconds The playtime in seconds. - * @return string - */ - public function getFormattedLengthEstimate() - { - return $this->formatTime($this->getLengthEstimate()); - } - - /** - * Returns the exact playtime given in seconds as a string in the form of - * [hours:]minutes:seconds.milliseconds. In lazy reading mode the frames are - * read from the file the first time you call this method to get the exact - * playtime of the file. - * - * @param integer $seconds The playtime in seconds. - * @return string - */ - public function getFormattedLength() - { - return $this->formatTime($this->getLength()); - } - - /** - * Returns all the frames of the audio bitstream as an array. In lazy reading - * mode the frames are read from the file the first time you call this method. - * - * @return Array - */ - public function getFrames() - { - if ($this->getOption("readmode", "lazy") == "lazy") { - $this->_readFrames(); - } - return $this->_frames; - } - - /** - * Reads frames up to given limit. If called subsequently the method continues - * after the last frame read in the last call, again to read up to the limit - * or just the rest of the frames. - * - * @param integer $limit The maximum number of frames read from the bitstream - */ - private function _readFrames($limit = false) - { - if ($this->_lastFrameOffset !== false) - $this->_reader->setOffset($this->_lastFrameOffset); - - for ($i = 0; $this->_reader->getOffset() < $this->_bytes; $i++) { - $options = $this->getOptions(); - $frame = new MPEG_ABS_Frame($this->_reader, $options); - - $this->_cumulativePlayDuration += - (double)($frame->getLength() / ($frame->getBitrate() * 1000 / 8)); - $this->_cumulativeBitrate += $frame->getBitrate(); - $this->_frames[] = $frame; - - if ($limit === false) - $this->_lastFrameOffset = $this->_reader->getOffset(); - if ($limit !== false && ($i + 1) == $limit) { - $this->_lastFrameOffset = $this->_reader->getOffset(); - break; - } - } - } -} diff --git a/src/MPEG/ABS/Frame.php b/src/MPEG/ABS/Frame.php deleted file mode 100644 index 55ce81e..0000000 --- a/src/MPEG/ABS/Frame.php +++ /dev/null @@ -1,507 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class MPEG_ABS_Frame extends MPEG_ABS_Object -{ - /** - * The bitrate lookup table. The table has the following format. - * - * - * array ( - * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( - * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) - * ) - * ) - * - * - * @var Array - */ - private static $bitrates = array ( - self::SAMPLING_FREQUENCY_HIGH => array ( - self::LAYER_ONE => array ( - 1 => 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 - ), - self::LAYER_TWO => array ( - 1 => 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 - ), - self::LAYER_THREE => array ( - 1 => 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 - ) - ), - self::SAMPLING_FREQUENCY_LOW => array ( - self::LAYER_ONE => array ( - 1 => 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 - ), - self::LAYER_TWO => array ( - 1 => 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 - ), - self::LAYER_THREE => array ( - 1 => 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 - ) - ) - ); - - /** - * Sample rate lookup table. The table has the following format. - * - * - * array ( - * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) - * ) - * - * - * @var Array - */ - private static $samplingFrequencies = array ( - self::VERSION_ONE => array (44100, 48000, 32000), - self::VERSION_TWO => array (22050, 24000, 16000), - self::VERSION_TWO_FIVE => array (11025, 12000, 8000) - ); - - /** - * Samples per frame lookup table. The table has the following format. - * - * - * array ( - * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( - * LAYER_ONE | LAYER_TWO | LAYER_TREE => - * ) - * ) - * - * - * @var Array - */ - private static $samples = array ( - self::SAMPLING_FREQUENCY_HIGH => array ( - self::LAYER_ONE => 384, - self::LAYER_TWO => 1152, - self::LAYER_THREE => 1152), - self::SAMPLING_FREQUENCY_LOW => array ( - self::LAYER_ONE => 384, - self::LAYER_TWO => 1152, - self::LAYER_THREE => 576)); - - /** - * Coefficient lookup table. The table has the following format. - * - * - * array ( - * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( - * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) - * ) - * ) - * - * - * @var Array - */ - private static $coefficients = array ( - self::SAMPLING_FREQUENCY_HIGH => array ( - self::LAYER_ONE => 12, self::LAYER_TWO => 144, self::LAYER_THREE => 144 - ), - self::SAMPLING_FREQUENCY_LOW => array ( - self::LAYER_ONE => 12, self::LAYER_TWO => 144, self::LAYER_THREE => 72 - ) - ); - - /** - * Slot size per layer lookup table. The table has the following format. - * - * - * array ( - * LAYER_ONE | LAYER_TWO | LAYER_TREE => - * ) - * - * - * - * @var Array - */ - private static $slotsizes = array ( - self::LAYER_ONE => 4, self::LAYER_TWO => 1, self::LAYER_THREE => 1 - ); - - - /** @var integer */ - private $_offset; - - /** @var integer */ - private $_version; - - /** @var integer */ - private $_frequencyType; - - /** @var integer */ - private $_layer; - - /** @var integer */ - private $_redundancy; - - /** @var integer */ - private $_bitrate; - - /** @var integer */ - private $_samplingFrequency; - - /** @var integer */ - private $_padding; - - /** @var integer */ - private $_mode; - - /** @var integer */ - private $_modeExtension; - - /** @var integer */ - private $_copyright; - - /** @var integer */ - private $_original; - - /** @var integer */ - private $_emphasis; - - /** @var integer */ - private $_length; - - /** @var integer */ - private $_samples; - - /** @var integer */ - private $_crc = false; - - /** @var string */ - private $_data = false; - - /** - * Constructs the class with given parameters and reads object related data - * from the frame. - * - * @param Reader $reader The reader object. - * @param Array $options Array of options. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_offset = $this->_reader->getOffset(); - - $header = Transform::fromUInt32BE($this->_reader->read(4)); - $this->_version = Twiddling::getValue($header, 19, 20); - $this->_frequencyType = Twiddling::testBit($header, 19); - $this->_layer = Twiddling::getValue($header, 17, 18); - $this->_redundancy = !Twiddling::testBit($header, 16); - $this->_bitrate = isset - (self::$bitrates[$this->_frequencyType][$this->_layer] - [$index = Twiddling::getValue($header, 12, 15)]) ? - self::$bitrates[$this->_frequencyType][$this->_layer][$index] : false; - $this->_samplingFrequency = isset - (self::$samplingFrequencies[$this->_version] - [$index = Twiddling::getValue($header, 10, 11)]) ? - self::$samplingFrequencies[$this->_version][$index] : false; - $this->_padding = Twiddling::testBit($header, 9); - $this->_mode = Twiddling::getValue($header, 6, 7); - $this->_modeExtension = Twiddling::getValue($header, 4, 5); - $this->_copyright = Twiddling::testBit($header, 3); - $this->_original = Twiddling::testBit($header, 2); - $this->_emphasis = Twiddling::getValue($header, 0, 1); - - $this->_length = (int) - ((self::$coefficients[$this->_frequencyType][$this->_layer] * - ($this->_bitrate * 1000) / $this->_samplingFrequency) + - ($this->_padding ? 1 : 0)) * self::$slotsizes[$this->_layer]; - $this->_samples = self::$samples[$this->_frequencyType][$this->_layer]; - - if ($this->getOption("readmode", "lazy") == "full") { - $this->_readCrc(); - $this->_readData(); - } - $this->_reader->skip($this->_length - 4); - } - - /** - * Returns the version identifier of the algorithm. - * - * @see VERSION_ONE, VERSION_TWO, VERSION_TWO_FIVE - * @return integer - */ - public function getVersion() { return $this->_version; } - - /** - * Returns the sampling frequency type. This can be one of the following - * values. - * - * o {@link SAMPLING_FREQUENCY_HIGH} -- Higher Sampling Frequency - * (Version 1) - * o {@link SAMPLING_FREQUENCY_LOW} -- Lower Sampling Frequency - * (Version 2 and 2.5) - * - * @see SAMPLING_FREQUENCY_LOW, SAMPLING_FREQUENCY_HIGH - * @return integer - */ - public function getFrequencyType() { return $this->_frequencyType; } - - /** - * Returns the type of layer used. - * - * @see LAYER_ONE, LAYER_TWO, LAYER_THREE - * @return integer - */ - public function getLayer() { return $this->_layer; } - - /** - * An alias to getRedundancy(). - * - * @see getRedundancy - * @return boolean - */ - public function hasRedundancy() { return $this->getRedundancy(); } - - /** - * Returns boolean corresponding to whether redundancy has been added in the - * audio bitstream to facilitate error detection and concealment. Equals - * false if no redundancy has been added, true if - * redundancy has been added. - * - * @return boolean - */ - public function getRedundancy() { return $this->_redundancy; } - - /** - * Returns the bitrate in kbps. The returned value indicates the total bitrate - * irrespective of the mode (stereo, joint_stereo, dual_channel, - * single_channel). - * - * @return integer - */ - public function getBitrate() { return $this->_bitrate; } - - /** - * Returns the sampling frequency in Hz. - * - * @return integer - */ - public function getSamplingFrequency() { return $this->_samplingFrequency; } - - /** - * An alias to getPadding(). - * - * @see getPadding - * @return boolean - */ - public function hasPadding() { return $this->getPadding(); } - - /** - * Returns boolean corresponding the frame contains an additional slot to - * adjust the mean bitrate to the sampling frequency. Equals to - * true if padding has been added, false otherwise. - * - * Padding is only necessary with a sampling frequency of 44.1kHz. - * - * @return boolean - */ - public function getPadding() { return $this->_padding; } - - /** - * Returns the mode. In Layer I and II the CHANNEL_JOINT_STEREO mode is - * intensity_stereo, in Layer III it is intensity_stereo and/or ms_stereo. - * - * @see CHANNEL_STEREO, CHANNEL_JOINT_STEREO, CHANNEL_DUAL_CHANNEL, - * CHANNEL_SINGLE_CHANNEL - * @return integer - */ - public function getMode() { return $this->_mode; } - - /** - * Returns the mode extension used in CHANNEL_JOINT_STEREO mode. - * - * In Layer I and II the return type indicates which subbands are in - * intensity_stereo. All other subbands are coded in stereo. - * - * o {@link MODE_SUBBAND_4_TO_31} -- subbands 4-31 in - * intensity_stereo, bound==4 - * o {@link MODE_SUBBAND_8_TO_31} -- subbands 8-31 in - * intensity_stereo, bound==8 - * o {@link MODE_SUBBAND_12_TO_31} -- subbands 12-31 in - * intensity_stereo, bound==12 - * o {@link MODE_SUBBAND_16_TO_31} -- subbands 16-31 in - * intensity_stereo, bound==16 - * - * In Layer III they indicate which type of joint stereo coding method is - * applied. The frequency ranges over which the intensity_stereo and ms_stereo - * modes are applied are implicit in the algorithm. Please see - * {@link MODE_ISOFF_MSSOFF}, {@link MODE_ISON_MSSOFF}, - * {@link MODE_ISOFF_MSSON}, and {@link MODE_ISON_MSSON}. - * - * @return integer - */ - public function getModeExtension() { return $this->_modeExtension; } - - /** - * An alias to getCopyright(). - * - * @see getCopyright - * @return boolean - */ - public function hasCopyright() { return $this->getCopyright(); } - - /** - * Returns true if the coded bitstream is copyright protected, - * false otherwise. - * - * @return boolean - */ - public function getCopyright() { return $this->_copyright; } - - /** - * An alias to getOriginal(). - * - * @see getOriginal - * @return boolean - */ - public function isOriginal() { return $this->getOriginal(); } - - /** - * Returns whether the bitstream is original or home made. - * - * @return boolean - */ - public function getOriginal() { return $this->_original; } - - /** - * Returns the type of de-emphasis that shall be used. The value is one of the - * following. - * - * o {@link EMPHASIS_NONE} -- No emphasis - * o {@link EMPHASIS_50_15} -- 50/15 microsec. emphasis - * o {@link EMPHASIS_CCIT_J17} -- CCITT J.17 - * - * @see EMPHASIS_NONE, EMPHASIS_50_15, EMPHASIS_CCIT_J17 - * @return integer - */ - public function getEmphasis() { return $this->_emphasis; } - - /** - * Returns the length of the frame based on the current layer, bit rate, - * sampling frequency and padding, in bytes. - * - * @return integer - */ - public function getLength() { return $this->_length; } - - /** - * Returns the number of samples contained in the frame. - * - * @return integer - */ - public function getSamples() { return $this->_samples; } - - /** - * Returns the 16-bit CRC of the frame or false if not present. - * - * @return integer - */ - public function getCrc() - { - if ($this->getOption("readmode", "lazy") == "lazy" && - $this->hasRedundancy() && $this->_crc === false) { - $this->_readCrc(); - } - return $this->_crc; - } - - /** - * Reads the CRC data. - */ - private function _readCrc() - { - if ($this->hasRedundancy()) { - $offset = $this->_reader->getOffset(); - $this->_reader->setOffset($this->_offset + 4); - $this->_crc = $this->_reader->readUInt16BE(); - $this->_reader->setOffset($offset); - } - } - - /** - * Returns the audio data. - * - * @return string - */ - public function getData() - { - if ($this->getOption("readmode", "lazy") == "lazy" && - $this->_data === false) { - $this->_readData(); - } - return $this->_data; - } - - /** - * Reads the frame data. - */ - private function _readData() - { - $offset = $this->_reader->getOffset(); - $this->_reader->setOffset - ($this->_offset + 4 + ($this->hasRedundancy() ? 2 : 0)); - $this->_data = $this->_reader->read - ($this->getLength() - 4 - ($this->hasRedundancy() ? 2 : 0)); - $this->_reader->setOffset($offset); - } -} diff --git a/src/MPEG/ABS/LAMEHeader.php b/src/MPEG/ABS/LAMEHeader.php deleted file mode 100644 index 035d8fd..0000000 --- a/src/MPEG/ABS/LAMEHeader.php +++ /dev/null @@ -1,481 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class MPEG_ABS_LAMEHeader extends MPEG_ABS_Object -{ - - /** @var integer */ - const VBR_METHOD_CONSTANT = 1; - - /** @var integer */ - const VBR_METHOD_ABR = 2; - - /** @var integer */ - const VBR_METHOD_RH = 3; - - /** @var integer */ - const VBR_METHOD_MTRH = 4; - - /** @var integer */ - const VBR_METHOD_MT = 5; - - /** @var integer */ - const ENCODING_FLAG_NSPSYTUNE = 1; - - /** @var integer */ - const ENCODING_FLAG_NSSAFEJOINT = 2; - - /** @var integer */ - const ENCODING_FLAG_NOGAP_CONTINUED = 4; - - /** @var integer */ - const ENCODING_FLAG_NOGAP_CONTINUATION = 8; - - /** @var integer */ - const MODE_MONO = 0; - - /** @var integer */ - const MODE_STEREO = 1; - - /** @var integer */ - const MODE_DUAL = 2; - - /** @var integer */ - const MODE_JOINT = 3; - - /** @var integer */ - const MODE_FORCE = 4; - - /** @var integer */ - const MODE_AUTO = 5; - - /** @var integer */ - const MODE_INTENSITY = 6; - - /** @var integer */ - const MODE_UNDEFINED = 7; - - /** @var integer */ - const SOURCE_FREQUENCY_32000_OR_LOWER = 0; - - /** @var integer */ - const SOURCE_FREQUENCY_44100 = 1; - - /** @var integer */ - const SOURCE_FREQUENCY_48000 = 2; - - /** @var integer */ - const SOURCE_FREQUENCY_HIGHER = 3; - - /** @var integer */ - const SURROUND_NONE = 0; - - /** @var integer */ - const SURROUND_DPL = 1; - - /** @var integer */ - const SURROUND_DPL2 = 2; - - /** @var integer */ - const SURROUND_AMBISONIC = 3; - - /** @var string */ - private $_version; - - /** @var integer */ - private $_revision; - - /** @var integer */ - private $_vbrMethod; - - /** @var integer */ - private $_lowpass; - - /** @var integer */ - private $_peakSignalAmplitude; - - /** @var integer */ - private $_radioReplayGain; - - /** @var integer */ - private $_audiophileReplayGain; - - /** @var integer */ - private $_encodingFlags; - - /** @var integer */ - private $_athType; - - /** @var integer */ - private $_bitrate; - - /** @var integer */ - private $_encoderDelaySamples; - - /** @var integer */ - private $_paddedSamples; - - /** @var integer */ - private $_sourceSampleFrequency; - - /** @var boolean */ - private $_unwiseSettingsUsed; - - /** @var integer */ - private $_mode; - - /** @var integer */ - private $_noiseShaping; - - /** @var integer */ - private $_mp3Gain; - - /** @var integer */ - private $_surroundInfo; - - /** @var integer */ - private $_presetUsed; - - /** @var integer */ - private $_musicLength; - - /** @var integer */ - private $_musicCrc; - - /** @var integer */ - private $_crc; - - /** - * Constructs the class with given parameters and reads object related data - * from the bitstream. - * - * @param Reader $reader The reader object. - * @param Array $options Array of options. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $this->_version = $this->_reader->readString8(5); - - $tmp = $this->_reader->readUInt8(); - $this->_revision = Twiddling::getValue($tmp, 4, 8); - $this->_vbrMethod = Twiddling::getValue($tmp, 0, 3); - - $this->_lowpass = $this->_reader->readUInt8() * 100; - - $this->_peakSignalAmplitude = $this->_reader->readUInt32BE(); - - $tmp = $this->_reader->readUInt16BE(); - $this->_radioReplayGain = array( - "name" => Twiddling::getValue($tmp, 0, 2), - "originator" => Twiddling::getValue($tmp, 3, 5), - "absoluteGainAdjustment" => Twiddling::getValue($tmp, 7, 15) / 10 - ); - - $tmp = $this->_reader->readUInt16BE(); - $this->_audiophileReplayGain = array( - "name" => Twiddling::getValue($tmp, 0, 2), - "originator" => Twiddling::getValue($tmp, 3, 5), - "absoluteGainAdjustment" => Twiddling::getValue($tmp, 7, 15) / 10 - ); - - $tmp = $this->_reader->readUInt8(); - $this->_encodingFlags = Twiddling::getValue($tmp, 4, 8); - $this->_athType = Twiddling::getValue($tmp, 0, 3); - - $this->_bitrate = $this->_reader->readUInt8(); - - $tmp = $this->_reader->readUInt32BE(); - // Encoder delay fields - $this->_encoderDelaySamples = Twiddling::getValue($tmp, 20, 31); - $this->_paddedSamples = Twiddling::getValue($tmp, 8, 19); - // Misc field - $this->_sourceSampleFrequency = Twiddling::getValue($tmp, 6, 7); - $this->_unwiseSettingsUsed = Twiddling::testBit($tmp, 5); - $this->_mode = Twiddling::getValue($tmp, 2, 4); - $this->_noiseShaping = Twiddling::getValue($tmp, 0, 1); - - $this->_mp3Gain = pow(2, $this->_reader->readInt8() / 4); - - $tmp = $this->_reader->readUInt16BE(); - $this->_surroundInfo = Twiddling::getValue($tmp, 11, 14); - $this->_presetUsed = Twiddling::getValue($tmp, 0, 10); - - $this->_musicLength = $this->_reader->readUInt32BE(); - - $this->_musicCrc = $this->_reader->readUInt16BE(); - $this->_crc = $this->_reader->readUInt16BE(); - } - - /** - * Returns the version string of the header. - * - * @return string - */ - public function getVersion() { return $this->_version; } - - /** - * Returns the info tag revision. - * - * @return integer - */ - public function getRevision() { return $this->_revision; } - - /** - * Returns the VBR method used for encoding. See the corresponding constants - * for possible return values. - * - * @return integer - */ - public function getVbrMethod() { return $this->_vbrMethod; } - - /** - * Returns the lowpass filter value. - * - * @return integer - */ - public function getLowpass() { return $this->_lowpass; } - - /** - * Returns the peak signal amplitude field of replay gain. The value of 1.0 - * (ie 100%) represents maximal signal amplitude storeable in decoding format. - * - * @return integer - */ - public function getPeakSignalAmplitude() - { - return $this->_peakSignalAmplitude; - } - - /** - * Returns the radio replay gain field of replay gain, required to make all - * tracks equal loudness, as an array that consists of the following keys. - * - * o name -- Specifies the name of the gain adjustment. Can be one of the - * following values: 0 = not set, 1 = radio, or 2 = audiophile. - * - * o originator -- Specifies the originator of the gain adjustment. Can be - * one of the following values: 0 = not set, 1 = set by artist, 2 = set - * by user, 3 = set by my model, 4 = set by simple RMS average. - * - * o absoluteGainAdjustment -- Speficies the absolute gain adjustment. - * - * @return Array - */ - public function getRadioReplayGain() { return $this->_radioReplayGain; } - - /** - * Returns the audiophile replay gain field of replay gain, required to give - * ideal listening loudness, as an array that consists of the following keys. - * - * o name -- Specifies the name of the gain adjustment. Can be one of the - * following values: 0 = not set, 1 = radio, or 2 = audiophile. - * - * o originator -- Specifies the originator of the gain adjustment. Can be - * one of the following values: 0 = not set, 1 = set by artist, 2 = set - * by user, 3 = set by my model, 4 = set by simple RMS average. - * - * o absoluteGainAdjustment -- Speficies the absolute gain adjustment. - * - * @return Array - */ - public function getAudiophileReplayGain() - { - return $this->_audiophileReplayGain; - } - - /** - * Returns the encoding flags. See the corresponding flag constants for - * possible values. - * - * @return integer - */ - public function getEncodingFlags() { return $this->_encodingFlags; } - - /** - * Returns the ATH type. - * - * @return integer - */ - public function getAthType() { return $this->_athType; } - - /** - * Returns the bitrate for CBR encoded files and the minimal birate for - * VBR encoded file. The maximum value of this field is 255 even with higher - * actual bitrates. - * - * @return integer - */ - public function getBitrate() { return $this->_bitrate; } - - /** - * Returns the encoder delay or number of samples added at start. - * - * @return integer - */ - public function getEncoderDelaySamples() - { - return $this->_encoderDelaySamples; - } - - /** - * Returns the number of padded samples to complete the last frame. - * - * @return integer - */ - public function getPaddedSamples() { return $this->_paddedSamples; } - - /** - * Returns the source sample frequency. See corresponding constants for - * possible values. - * - * @return integer - */ - public function getSourceSampleFrequency() - { - return $this->_sourceSampleFrequency; - } - - /** - * An alias to getUnwiseSettingsUsed(). - * - * @see getUnwiseSettingsUsed - * @return boolean - */ - public function areUnwiseSettingsUsed() - { - return $this->getUnwiseSettingsUsed(); - } - - /** - * Returns whether unwise settings were used to encode the file. - * - * @return boolean - */ - public function getUnwiseSettingsUsed() { return $this->_unwiseSettingsUsed; } - - /** - * Returns the stereo mode. See corresponding constants for possible values. - * - * @return integer - */ - public function getMode() { return $this->_mode; } - - /** - * Returns the noise shaping. - * - * @return integer - */ - public function getNoiseShaping() { return $this->_noiseShaping; } - - /** - * Returns the MP3 gain change. Any MP3 can be amplified in a lossless manner. - * If done so, this field can be used to log such transformation happened so - * that any given time it can be undone. - * - * @return integer - */ - public function getMp3Gain() { return $this->_mp3Gain; } - - /** - * Returns the surround info. See corresponding contants for possible values. - * - * @return integer - */ - public function getSurroundInfo() { return $this->_surroundInfo; } - - /** - * Returns the preset used in encoding. - * - * @return integer - */ - public function getPresetUsed() { return $this->_presetUsed; } - - /** - * Returns the exact length in bytes of the MP3 file originally made by LAME - * excluded ID3 tag info at the end. - * - * The first byte it counts is the first byte of this LAME header and the last - * byte it counts is the last byte of the last MP3 frame containing music. - * The value should be equal to file length at the time of LAME encoding, - * except when using ID3 tags. - * - * @return integer - */ - public function getMusicLength() { return $this->_musicLength; } - - /** - * Returns the CRC-16 of the complete MP3 music data as made originally by - * LAME. - * - * @return integer - */ - public function getMusicCrc() { return $this->_musicCrc; } - - /** - * Returns the CRC-16 of the first 190 bytes of the header frame. - * - * @return integer - */ - public function getCrc() { return $this->_crc; } -} diff --git a/src/MPEG/ABS/Object.php b/src/MPEG/ABS/Object.php deleted file mode 100644 index b05588a..0000000 --- a/src/MPEG/ABS/Object.php +++ /dev/null @@ -1,167 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class MPEG_ABS_Object extends MPEG_Object -{ - /** @var integer */ - const VERSION_ONE = 3; - - /** @var integer */ - const VERSION_TWO = 2; - - /** @var integer */ - const VERSION_TWO_FIVE = 0; - - /** @var integer */ - const SAMPLING_FREQUENCY_LOW = 0; - - /** @var integer */ - const SAMPLING_FREQUENCY_HIGH = 1; - - /** @var integer */ - const LAYER_ONE = 3; - - /** @var integer */ - const LAYER_TWO = 2; - - /** @var integer */ - const LAYER_THREE = 1; - - /** @var integer */ - const CHANNEL_STEREO = 0; - - /** @var integer */ - const CHANNEL_JOINT_STEREO = 1; - - /** @var integer */ - const CHANNEL_DUAL_CHANNEL = 2; - - /** @var integer */ - const CHANNEL_SINGLE_CHANNEL = 3; - - /** @var integer */ - const MODE_SUBBAND_4_TO_31 = 0; - - /** @var integer */ - const MODE_SUBBAND_8_TO_31 = 1; - - /** @var integer */ - const MODE_SUBBAND_12_TO_31 = 2; - - /** @var integer */ - const MODE_SUBBAND_16_TO_31 = 3; - - /** @var integer */ - const MODE_ISOFF_MSSOFF = 0; - - /** @var integer */ - const MODE_ISON_MSSOFF = 1; - - /** @var integer */ - const MODE_ISOFF_MSSON = 2; - - /** @var integer */ - const MODE_ISON_MSSON = 3; - - /** @var integer */ - const EMPHASIS_NONE = 0; - - /** @var integer */ - const EMPHASIS_50_15 = 1; - - /** @var integer */ - const EMPHASIS_CCIT_J17 = 3; - - - /** - * Layer III side information size lookup table. The table has the following - * format. - * - * - * array ( - * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( - * CHANNEL_STEREO | CHANNEL_JOINT_STEREO | CHANNEL_DUAL_CHANNEL | - * CHANNEL_SINGLE_CHANNEL => - * ) - * ) - * - * - * - * @var Array - */ - protected static $sidesizes = array( - self::SAMPLING_FREQUENCY_HIGH => array( - self::CHANNEL_STEREO => 32, - self::CHANNEL_JOINT_STEREO => 32, - self::CHANNEL_DUAL_CHANNEL => 32, - self::CHANNEL_SINGLE_CHANNEL => 17 - ), - self::SAMPLING_FREQUENCY_LOW => array( - self::CHANNEL_STEREO => 17, - self::CHANNEL_JOINT_STEREO => 17, - self::CHANNEL_DUAL_CHANNEL => 17, - self::CHANNEL_SINGLE_CHANNEL => 9 - ) - ); - - - /** - * Constructs the class with given parameters. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - } -} diff --git a/src/MPEG/ABS/VBRIHeader.php b/src/MPEG/ABS/VBRIHeader.php deleted file mode 100644 index f874e93..0000000 --- a/src/MPEG/ABS/VBRIHeader.php +++ /dev/null @@ -1,165 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class MPEG_ABS_VBRIHeader extends MPEG_ABS_Object -{ - /** @var integer */ - private $_version; - - /** @var integer */ - private $_delay; - - /** @var integer */ - private $_qualityIndicator; - - /** @var integer */ - private $_bytes; - - /** @var integer */ - private $_frames; - - /** @var Array */ - private $_toc = array(); - - /** @var integer */ - private $_tocFramesPerEntry; - - /** @var integer */ - private $_length; - - /** - * Constructs the class with given parameters and reads object related data - * from the bitstream. - * - * @param Reader $reader The reader object. - * @param Array $options Array of options. - */ - public function __construct($reader, &$options = array()) - { - $offset = $this->_reader->getOffset(); - $this->_version = $this->_reader->readUInt16BE(); - $this->_delay = $this->_reader->readUInt16BE(); - $this->_qualityIndicator = $this->_reader->readUInt16BE(); - $this->_bytes = $this->_reader->readUInt32BE(); - $this->_frames = $this->_reader->readUInt32BE(); - $tocEntries = $this->_reader->readUInt16BE(); - $tocEntryScale = $this->_reader->readUInt16BE(); - $tocEntrySize = $this->_reader->readUInt16BE(); - $this->_tocFramesPerEntry = $this->_reader->readUInt16BE(); - $this->_toc = array_merge(unpack(($tocEntrySize == 1) ? "C*" : - ($tocEntrySize == 2) ? "n*" : "N*", - $this->_reader->read($tocCount * $tocEntrySize))); - foreach ($this->_toc as $key => $value) - $this->_toc[$key] = $tocEntryScale * $value; - $this->_length = $this->_reader->getOffset() - $offset; - } - - /** - * Returns the header version. - * - * @return integer - */ - public function getVersion() { return $this->_version; } - - /** - * Returns the delay. - * - * @return integer - */ - public function getDelay() { return $this->_delay; } - - /** - * Returns the quality indicator. Return value varies from 0 (best quality) to - * 100 (worst quality). - * - * @return integer - */ - public function getQualityIndicator() { return $this->_qualityIndicator; } - - /** - * Returns the number of bytes in the file. - * - * @return integer - */ - public function getBytes() { return $this->_bytes; } - - /** - * Returns the number of frames in the file. - * - * @return integer - */ - public function getFrames() { return $this->_frames; } - - /** - * Returns the table of contents array. - * - * @return Array - */ - public function getToc() { return $this->_toc; } - - /** - * Returns the number of frames per TOC entry. - * - * @return integer - */ - public function getTocFramesPerEntry() { return $this->_tocFramesPerEntry; } - - /** - * Returns the length of the header in bytes. - * - * @return integer - */ - public function getLength() { return $this->_length; } -} diff --git a/src/MPEG/ABS/XINGHeader.php b/src/MPEG/ABS/XINGHeader.php deleted file mode 100644 index d7ce7a7..0000000 --- a/src/MPEG/ABS/XINGHeader.php +++ /dev/null @@ -1,136 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class MPEG_ABS_XINGHeader extends MPEG_ABS_Object -{ - /** @var integer */ - private $_frames = false; - - /** @var integer */ - private $_bytes = false; - - /** @var Array */ - private $_toc = array(); - - /** @var integer */ - private $_qualityIndicator = false; - - /** - * Constructs the class with given parameters and reads object related data - * from the bitstream. - * - * @param Reader $reader The reader object. - * @param Array $options Array of options. - */ - public function __construct($reader, &$options = array()) - { - parent::__construct($reader, $options); - - $flags = $reader->readUInt32BE(); - - if (Twiddling::testAnyBits($flags, 0x1)) - $this->_frames = $this->_reader->readUInt32BE(); - if (Twiddling::testAnyBits($flags, 0x2)) - $this->_bytes = $this->_reader->readUInt32BE(); - if (Twiddling::testAnyBits($flags, 0x4)) - $this->_toc = array_merge(unpack("C*", $this->_reader->read(100))); - if (Twiddling::testAnyBits($flags, 0x8)) - $this->_qualityIndicator = $this->_reader->readUInt32BE(); - } - - /** - * Returns the number of frames in the file. - * - * @return integer - */ - public function getFrames() { return $this->_frames; } - - /** - * Returns the number of bytes in the file. - * - * @return integer - */ - public function getBytes() { return $this->_bytes; } - - /** - * Returns the table of contents array. The returned array has a fixed amount - * of 100 seek points to the file. - * - * @return Array - */ - public function getToc() { return $this->_toc; } - - /** - * Returns the quality indicator. The indicator is from 0 (best quality) to - * 100 (worst quality). - * - * @return integer - */ - public function getQualityIndicator() { return $this->_qualityIndicator; } - - /** - * Returns the length of the header in bytes. - * - * @return integer - */ - public function getLength() - { - return 4 + - ($this->_frames !== false ? 4 : 0) + - ($this->_bytes !== false ? 4 : 0) + - (empty($this->_toc) ? 0 : 100) + - ($this->_qualityIndicator !== false ? 4 : 0); - } -} diff --git a/src/MPEG/Exception.php b/src/MPEG/Exception.php deleted file mode 100644 index 6f24368..0000000 --- a/src/MPEG/Exception.php +++ /dev/null @@ -1,51 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class MPEG_Exception extends Exception -{ -} diff --git a/src/MPEG/Object.php b/src/MPEG/Object.php deleted file mode 100644 index d772e4d..0000000 --- a/src/MPEG/Object.php +++ /dev/null @@ -1,258 +0,0 @@ - - * @copyright Copyright (c) 2008-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -abstract class MPEG_Object -{ - /** - * The reader object. - * - * @var Reader - */ - protected $_reader; - - /** - * The options array. - * - * @var Array - */ - private $_options; - - /** - * Constructs the class with given parameters. - * - * @param Reader $reader The reader object. - * @param Array $options The options array. - */ - public function __construct($reader, &$options = array()) - { - $this->_reader = $reader; - $this->_options = &$options; - } - - /** - * Returns the options array. - * - * @return Array - */ - public final 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 final function getOption($option, $defaultValue = false) - { - if (isset($this->_options[$option])) - return $this->_options[$option]; - return $defaultValue; - } - - /** - * Sets the options array. See {@link MPEG} class for available options. - * - * @param Array $options The options array. - */ - public final 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 final function setOption($option, $value) - { - $this->_options[$option] = $value; - } - - /** - * Finds and returns the next start code. Start codes are reserved bit - * patterns in the video file that do not otherwise occur in the video stream. - * - * All start codes are byte aligned and start with the following byte - * sequence: 0x00 0x00 0x01. - * - * @return integer - */ - protected final function nextStartCode() - { - $buffer = " "; - for ($i = 0; $i < 4; $i++) { - $start = $this->_reader->getOffset(); - if (($buffer = substr($buffer, -4) . - $this->_reader->read(512)) === false) { - require_once("MPEG/Exception.php"); - throw new MPEG_Exception("Invalid data"); - } - $limit = strlen($buffer); - $pos = 0; - while ($pos < $limit - 3) { - if (Transform::fromUInt8($buffer{$pos++}) == 0 && - Transform::fromUInt16BE(substr($buffer, $pos, 2)) == 1) { - if (($pos += 2) < $limit - 2) - if (Transform::fromUInt16BE(substr($buffer, $pos, 2)) == 0 && - Transform::fromUInt8($buffer{$pos + 2}) == 1) - continue; - $this->_reader->setOffset($start + $pos - 3); - return Transform::fromUInt8($buffer{$pos++}) & 0xff | 0x100; - } - } - $this->_reader->setOffset($start + $limit); - } - - /* No start code found within 2048 bytes, the maximum size of a pack */ - require_once("MPEG/Exception.php"); - throw new MPEG_Exception("Invalid data"); - } - - /** - * Finds and returns the previous start code. Start codes are reserved bit - * patterns in the video file that do not otherwise occur in the video stream. - * - * All start codes are byte aligned and start with the following byte - * sequence: 0x00 0x00 0x01. - * - * @return integer - */ - protected final function prevStartCode() - { - $buffer = " "; - $start; - $position = $this->_reader->getOffset(); - while ($position > 0) { - $start = 0; - $position = $position - 512; - if ($position < 0) { - require_once("MPEG/Exception.php"); - throw new MPEG_Exception("Invalid data"); - } - $this->_reader->setOffset($position); - $buffer = $this->_reader->read(512) . substr($buffer, 0, 4); - $pos = 512 - 8; - while ($pos > 3) { - if (Transform::fromUInt8($buffer{$pos}) == 0 && - Transform::fromUInt16BE(substr($buffer, $pos + 1, 2)) == 1) { - - if ($pos + 2 < 512 && - Transform::fromUInt16BE(substr($buffer, $pos + 3, 2)) == 0 && - Transform::fromUInt8($buffer{$pos + 5}) == 1) { - $pos --; - continue; - } - $this->_reader->setOffset($position + $pos); - return Transform::fromUInt8($buffer{$pos + 3}) & 0xff | 0x100; - } - $pos--; - } - $this->_reader->setOffset($position = $position + 3); - } - return 0; - } - - /** - * Formats given time in seconds into the form of - * [hours:]minutes:seconds.milliseconds. - * - * @param integer $seconds The time to format, in seconds - * @return string - */ - protected final function formatTime($seconds) - { - $milliseconds = round(($seconds - floor($seconds)) * 1000); - $seconds = floor($seconds); - $minutes = floor($seconds / 60); - $hours = floor($minutes / 60); - return - ($minutes > 0 ? - ($hours > 0 ? $hours . ":" . - str_pad($minutes % 60, 2, "0", STR_PAD_LEFT) : $minutes % 60) . ":" . - str_pad($seconds % 60, 2, "0", STR_PAD_LEFT) : $seconds % 60) . "." . - str_pad($milliseconds, 3, "0", STR_PAD_LEFT); - } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst($name))) - return call_user_func(array($this, "get" . ucfirst($name))); - else { - require_once("MPEG/Exception.php"); - throw new MPEG_Exception("Unknown 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 { - require_once("MPEG/Exception.php"); - throw new MPEG_Exception("Unknown field: " . $name); - } - } -} diff --git a/src/MPEG/PS.php b/src/MPEG/PS.php deleted file mode 100644 index e867fad..0000000 --- a/src/MPEG/PS.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @todo Full implementation - */ -final class MPEG_PS extends MPEG_Object -{ - /** @var integer */ - private $_length; - - /** - * Constructs the class with given file and options. - * - * @param string|Reader $filename The path to the file, file descriptor of an - * opened file, or {@link Reader} instance. - * @param Array $options The options array. - */ - public function __construct($filename, $options = array()) - { - if ($filename instanceof Reader) - $reader = &$filename; - else - $reader = new Reader($filename); - - parent::__construct($reader, $options); - - $startCode = 0; $startTime = 0; - $pictureCount = 0; $pictureRate = 0; - $rates = array ( 0, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60 ); - $foundSeqHdr = false; $foundGOP = false; - - do { - do { - $startCode = $this->nextStartCode(); - } while ($startCode != 0x1b3 && $startCode != 0x1b8); - if ($startCode == 0x1b3 /* sequence_header_code */ && $pictureRate == 0) { - $i1 = $this->_reader->readUInt32BE(); - $i2 = $this->_reader->readUInt32BE(); - if (!Twiddling::testAllBits($i2, 0x2000)) - throw new RuntimeException("Invalid mark"); - $pictureRate = $rates[Twiddling::getValue($i1, 4, 8)]; - $foundSeqHdr = true; - } - if ($startCode == 0x1b8 /* group_start_code */) { - $tmp = $this->_reader->readUInt32BE(); - $startTime = (($tmp >> 26) & 0x1f) * 60 * 60 * 1000 /* hours */ + - (($tmp >> 20) & 0x3f) * 60 * 1000 /* minutes */ + - (($tmp >> 13) & 0x3f) * 1000 /* seconds */ + - (int)(1 / $pictureRate * (($tmp >> 7) & 0x3f) * 1000); - $foundGOP = true; - } - } while (!$foundSeqHdr || !$foundGOP); - - $this->_reader->setOffset($this->_reader->getSize()); - - do { - if (($startCode = $this->prevStartCode()) == 0x100) - $pictureCount++; - } while ($startCode != 0x1b8); - - $this->_reader->skip(4); - $tmp = $this->_reader->readUInt32BE(); - $this->_length = - (((($tmp >> 26) & 0x1f) * 60 * 60 * 1000 /* hours */ + - (($tmp >> 20) & 0x3f) * 60 * 1000 /* minutes */ + - (($tmp >> 13) & 0x3f) * 1000 /* seconds */ + - (int)(1 / $pictureRate * (($tmp >> 7) & 0x3f) * 1000)) - $startTime + - (int)(1 / $pictureRate * $pictureCount * 1000)) / 1000; - } - - /** - * Returns the exact playtime in seconds. - * - * @return integer - */ - public function getLength() { return $this->_length; } - - /** - * Returns the exact playtime given in seconds as a string in the form of - * [hours:]minutes:seconds.milliseconds. - * - * @param integer $seconds The playtime in seconds. - * @return string - */ - public function getFormattedLength() - { - return $this->formatTime($this->getLength()); - } -} diff --git a/src/Magic.php b/src/Magic.php deleted file mode 100644 index 21a3c27..0000000 --- a/src/Magic.php +++ /dev/null @@ -1,177 +0,0 @@ -1 -- byte number to begin checking from. ">" indicates a dependency - * upon the previous non-">" line - * o 2 -- type of data to match. Can be one of following - * - byte (single character) - * - short (machine-order 16-bit integer) - * - long (machine-order 32-bit integer) - * - string (arbitrary-length string) - * - date (long integer date (seconds since Unix epoch/1970)) - * - beshort (big-endian 16-bit integer) - * - belong (big-endian 32-bit integer) - * - bedate (big-endian 32-bit integer date) - * - leshort (little-endian 16-bit integer) - * - lelong (little-endian 32-bit integer) - * - ledate (little-endian 32-bit integer date) - * o 3 -- contents of data to match - * o 4 -- file description/MIME type if matched - * o 5 -- optional MIME encoding if matched and if above was a MIME type - * - * @package php-reader - * @author Sven Vollbehr - * @copyright Copyright (c) 2006-2008 PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -final class Magic -{ - /** @var string */ - private $_magic; - - /** - * Reads the magic information from given magic file. - * - * @param string $filename The path to the magic file. - */ - public function __construct($filename) - { - $reader = new Reader($filename); - $this->_magic = $reader->read($reader->getSize()); - } - - /** - * Returns the recognized MIME type/description of the given file. The type - * is determined by the content using magic bytes characteristic for the - * particular file type. - * - * If the type could not be found, the function returns the default value, or - * false. - * - * @param string $filename The file path whose type to determine. - * @param string $default The default value. - * @return string|false - */ - public function getType($filename, $default = false) - { - $reader = new Reader($filename); - - $parentOffset = 0; - foreach (preg_split("/^/m", $this->_magic) as $line) { - $chunks = array(); - if (!preg_match("/^(?P>?)(?P\d+)\s+(?P\S+)" . - "\s+(?P\S+)(?:\s+(?P[a-z]+\/[a-z-" . - "0-9]+)?(?:\s+(?P.+))?)?$/", $line, $chunks)) - continue; - - if ($chunks["Dependant"]) { - $reader->setOffset($parentOffset); - $reader->skip($chunks["Byte"]); - } else - $reader->setOffset($parentOffset = $chunks["Byte"]); - - $matchType = strtolower($chunks["MatchType"]); - $matchData = preg_replace - (array("/\\\\ /", "/\\\\\\\\/", "/\\\\([0-7]{1,3})/e", - "/\\\\x([0-9A-Fa-f]{1,2})/e", "/0x([0-9A-Fa-f]+)/e"), - array(" ", "\\\\", "pack(\"H*\", base_convert(\"$1\", 8, 16));", - "pack(\"H*\", \"$1\");", "hexdec(\"$1\");"), - $chunks["MatchData"]); - - switch ($matchType) { - case "byte": // single character - $data = $reader->readInt8(); - break; - case "short": // machine-order 16-bit integer - $data = $reader->readInt16(); - break; - case "long": // machine-order 32-bit integer - $data = $reader->readInt32(); - break; - case "string": // arbitrary-length string - $data = $reader->readString8(strlen($matchData)); - break; - case "date": // long integer date (seconds since Unix epoch/1970) - $data = $reader->readInt64BE(); - break; - case "beshort": // big-endian 16-bit integer - $data = $reader->readUInt16BE(); - break; - case "belong": // big-endian 32-bit integer - case "bedate": // big-endian 32-bit integer date - $data = $reader->readUInt32BE(); - break; - case "leshort": // little-endian 16-bit integer - $data = $reader->readUInt16LE(); - break; - case "lelong": // little-endian 32-bit integer - case "ledate": // little-endian 32-bit integer date - $data = $reader->readUInt32LE(); - break; - default: - $data = null; - break; - } - - if (strcmp($data, $matchData) == 0) { - if (!empty($chunks["MIMEType"])) - return $chunks["MIMEType"]; - if (!empty($chunks["Description"])) - return $chunks["Description"]; - } - } - return $default; - } -} diff --git a/src/Reader.php b/src/Reader.php deleted file mode 100644 index d6c185b..0000000 --- a/src/Reader.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class Reader -{ - /** @var resource */ - private $_fd; - - /** @var integer */ - private $_size; - - /** - * Constructs the Reader class with given file. - * - * @param string $filename The path to the file. - * @param string $mode The type of access. - * @throws Reader_Exception if the file cannot be read. - */ - public function __construct($filename, $mode = "rb") - { - if (is_resource($filename) && - in_array(get_resource_type($filename), array("file", "stream"))) - $this->_fd = $filename; - else if (($this->_fd = fopen($filename, $mode)) === false) - throw new Reader_Exception("Unable to open file:" . $filename); - - fseek($this->_fd, 0, SEEK_END); - $this->_size = ftell($this->_fd); - fseek($this->_fd, 0); - } - - /** - * Closes the file. - */ - public function __destruct() - { - @fclose($this->_fd); - } - - /** - * Checks whether there is more to be read in the file. Returns - * true if the end of the file has not yet been reached; - * false otherwise. - * - * @return boolean - */ - public function available() - { - return $this->getOffset() < $this->_size; - } - - /** - * Jumps size amount of bytes in the file stream. - * - * @param integer $size The amount of bytes. - * @return void - * @throws Reader_Exception if size attribute is negative. - */ - public function skip($size) - { - if ($size < 0) - throw new Reader_Exception("Invalid argument"); - if ($size == 0) - return; - fseek($this->_fd, $size, SEEK_CUR); - } - - /** - * Reads length amount of bytes from the file stream. - * - * @param integer $length The amount of bytes. - * @return string - * @throws Reader_Exception if length attribute is negative. - */ - public function read($length) - { - if ($length < 0) - throw new Reader_Exception("Invalid argument"); - if ($length == 0) - return ""; - return fread($this->_fd, $length); - } - - /** - * Returns the current point of operation. - * - * @return integer - */ - public function getOffset() - { - return ftell($this->_fd); - } - - /** - * Sets the point of operation, ie the cursor offset value. The offset can - * also be set to a negative value when it is interpreted as an offset from - * the end of the file instead of the beginning. - * - * @param integer $offset The new point of operation. - * @return void - */ - public function setOffset($offset) - { - fseek($this->_fd, $offset < 0 ? $this->_size + $offset : $offset); - } - - /** - * Returns the file size in bytes. - * - * @return integer - */ - public function getSize() { return $this->_size; } - - /** - * Magic function so that $obj->value will work. - * - * @param string $name The field name. - * @return mixed - */ - public function __get($name) - { - if (method_exists($this, "get" . ucfirst(strtolower($name)))) - return call_user_func(array($this, "get" . ucfirst(strtolower($name)))); - else throw new Reader_Exception("Unknown 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(strtolower($name)))) - call_user_func - (array($this, "set" . ucfirst(strtolower($name))), $value); - else throw new Reader_Exception("Unknown field: " . $name); - } - - /** - * Magic function to delegate the call to helper methods of - * Transform class to transform read data in another format. - * - * The read data length is determined from the helper method name. For methods - * where arbitrary data lengths are accepted a parameter can be used to - * specify the length. - * - * @param string $method The method to be called. - * @param string $params The parameters should the function accept them. - * @return mixed - * @throws Reader_Exception if no such transformer is implemented - */ - public function __call($method, $params) - { - $chunks = array(); - - // To keep compatibility with PHP 5.0.0 we use a static array instead of - // method_exists to check if a method of the Transform class can be called. - static $methods = array( - "isLittleEndian", "isBigEndian", "toInt64LE", "fromInt64LE", "toInt64BE", - "fromInt64BE", "toInt32", "fromInt32", "toInt32LE", "fromInt32LE", - "toInt32BE", "fromInt32BE", "toUInt32LE", "fromUInt32LE", "toUInt32BE", - "fromUInt32BE", "toInt16", "fromInt16", "toInt16LE", "fromInt16LE", - "toInt16BE", "fromInt16BE", "toUInt16LE", "fromUInt16LE", "toUInt16BE", - "fromUInt16BE", "toInt8", "fromInt8", "toUInt8", "fromUInt8", "toFloat", - "fromFloat", "toFloatLE", "fromFloatLE", "toFloatBE", "fromFloatBE", - "toString8", "fromString8", "toString16", "fromString16", "toString16LE", - "fromString16LE", "toString16BE", "fromString16BE", "toHHex", "fromHHex", - "toLHex", "fromLHex", "toGUID", "fromGUID" - ); - if (preg_match - ("/read([a-z]{3,6})?(\d{1,2})?(?:LE|BE)?/i", $method, $chunks) && - in_array(preg_replace("/^read/", "from", $method), $methods)) - return call_user_func - (array("Transform", preg_replace("/^read/", "from", $method)), - $this->read(preg_match("/String|(?:H|L)Hex/", $chunks[1]) ? - (isset($params[0]) ? $params[0] : 1) : - ($chunks[1] == "GUID" ? 16 : $chunks[2] / 8))); - else throw new Reader_Exception("Unknown method: " . $method); - } -} diff --git a/src/Reader/Exception.php b/src/Reader/Exception.php deleted file mode 100644 index 18be17d..0000000 --- a/src/Reader/Exception.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - */ -class Reader_Exception extends Exception -{ -} diff --git a/src/Transform.php b/src/Transform.php deleted file mode 100644 index 339af14..0000000 --- a/src/Transform.php +++ /dev/null @@ -1,711 +0,0 @@ - - * @author Ryan Butterfield - * @copyright Copyright (c) 2006-2009 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @static - */ -final class Transform -{ - const MACHINE_ENDIAN_ORDER = 0; - const LITTLE_ENDIAN_ORDER = 1; - const BIG_ENDIAN_ORDER = 2; - - /** - * Default private constructor for a static class. - */ - private function __construct() {} - - /** - * Returns whether the current machine endian order is little endian. - * - * @return boolean - */ - public static function isLittleEndian() - { - return self::fromInt32("\x01\x00\x00\x00") == 1; - } - - /** - * Returns whether the current machine endian order is big endian. - * - * @return boolean - */ - public static function isBigEndian() - { - return self::fromInt32("\x00\x00\x00\x01") == 1; - } - - /** - * Returns 64-bit float as little-endian ordered binary data string. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt64LE($value) - { - return pack("V*", $value & 0xffffffff, $value / (0xffffffff+1)); - } - - /** - * Returns little-endian ordered binary data as 64-bit float. PHP does not - * support 64-bit integers as the long integer is of 32-bits but using - * aritmetic operations it is implicitly converted into floating point which - * is of 64-bits long. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt64LE($value) - { - list(, $lolo, $lohi, $hilo, $hihi) = unpack("v*", $value); - return ($hihi * (0xffff+1) + $hilo) * (0xffffffff+1) + - ($lohi * (0xffff+1) + $lolo); - } - - /** - * Returns 64-bit float as big-endian ordered binary data string. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt64BE($value) - { - return pack("N*", $value / (0xffffffff+1), $value & 0xffffffff); - } - - /** - * Returns big-endian ordered binary data as 64-bit float. PHP does not - * support 64-bit integers as the long integer is of 32-bits but using - * aritmetic operations it is implicitly converted into floating point which - * is of 64-bits long. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt64BE($value) - { - list(, $hihi, $hilo, $lohi, $lolo) = unpack("n*", $value); - return ($hihi * (0xffff+1) + $hilo) * (0xffffffff+1) + - ($lohi * (0xffff+1) + $lolo); - } - - /** - * Returns signed 32-bit integer as machine-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt32($value) - { - return pack("l*", $value); - } - - /** - * Returns machine-endian ordered binary data as signed 32-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt32($value) - { - list(, $int) = unpack("l*", $value); - return $int; - } - - /** - * Returns signed 32-bit integer as little-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt32LE($value) - { - if (self::isBigEndian()) - return strrev(self::toInt32($value)); - else - return self::toInt32($value); - } - - /** - * Returns little-endian ordered binary data as signed 32-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt32LE($value) - { - if (self::isBigEndian()) - return self::fromInt32(strrev($value)); - else - return self::fromInt32($value); - } - - /** - * Returns signed 32-bit integer as big-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt32BE($value) - { - if (self::isBigEndian()) - return self::toInt32($value); - else - return strrev(self::toInt32($value)); - } - - /** - * Returns big-endian ordered binary data as signed 32-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt32BE($value) - { - if (self::isBigEndian()) - return self::fromInt32($value); - else - return self::fromInt32(strrev($value)); - } - - /** - * Returns unsigned 32-bit integer as little-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toUInt32LE($value) - { - return pack("V*", $value); - } - - /** - * Returns little-endian ordered binary data as unsigned 32-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromUInt32LE($value) - { - if (PHP_INT_SIZE < 8) { - list(, $lo, $hi) = unpack("v*", $value); - return $hi * (0xffff+1) + $lo; // eq $hi << 16 | $lo - } else { - list(, $int) = unpack("V*", $value); - return $int; - } - } - - /** - * Returns unsigned 32-bit integer as big-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toUInt32BE($value) - { - return pack("N*", $value); - } - - /** - * Returns big-endian ordered binary data as unsigned 32-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromUInt32BE($value) - { - if (PHP_INT_SIZE < 8) { - list(, $hi, $lo) = unpack("n*", $value); - return $hi * (0xffff+1) + $lo; // eq $hi << 16 | $lo - } else { - list(, $int) = unpack("N*", $value); - return $int; - } - } - - /** - * Returns signed 16-bit integer as machine endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt16($value) - { - return pack("s*", $value); - } - - /** - * Returns machine endian ordered binary data as signed 16-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt16($value) - { - list(, $int) = unpack("s*", $value); - return $int; - } - - /** - * Returns signed 16-bit integer as little-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt16LE($value) - { - if (self::isBigEndian()) - return strrev(self::toInt16($value)); - else - return self::toInt16($value); - } - - /** - * Returns little-endian ordered binary data as signed 16-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt16LE($value) - { - if (self::isBigEndian()) - return self::fromInt16(strrev($value)); - else - return self::fromInt16($value); - } - - /** - * Returns signed 16-bit integer as big-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toInt16BE($value) - { - if (self::isBigEndian()) - return self::toInt16($value); - else - return strrev(self::toInt16($value)); - } - - /** - * Returns big-endian ordered binary data as signed 16-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt16BE($value) - { - if (self::isBigEndian()) - return self::fromInt16($value); - else - return self::fromInt16(strrev($value)); - } - - /** - * Returns machine endian ordered binary data as unsigned 16-bit integer. - * - * @param string $value The binary data string. - * @param integer $order The byte order of the binary data string. - * @return integer - */ - private static function fromUInt16($value, $order = self::MACHINE_ENDIAN_ORDER) - { - list(, $int) = unpack - (($order == self::BIG_ENDIAN_ORDER ? "n" : - ($order == self::LITTLE_ENDIAN_ORDER ? "v" : "S")) . "*", $value); - return $int; - } - - /** - * Returns unsigned 16-bit integer as little-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toUInt16LE($value) - { - return pack("v*", $value); - } - - /** - * Returns little-endian ordered binary data as unsigned 16-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromUInt16LE($value) - { - return self::fromUInt16($value, self::LITTLE_ENDIAN_ORDER); - } - - /** - * Returns unsigned 16-bit integer as big-endian ordered binary data. - * - * @param integer $value The input value. - * @return string - */ - public static function toUInt16BE($value) - { - return pack("n*", $value); - } - - /** - * Returns big-endian ordered binary data as unsigned 16-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromUInt16BE($value) - { - return self::fromUInt16($value, self::BIG_ENDIAN_ORDER); - } - - /** - * Returns an 8-bit integer as binary data. - * - * @param integer $value The input value. - * @return integer - */ - public static function toInt8($value) - { - return pack("c*", $value); - } - - /** - * Returns binary data as 8-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromInt8($value) - { - list(, $int) = unpack("c*", $value); - return $int; - } - - /** - * Returns an unsigned 8-bit integer as binary data. - * - * @param integer $value The input value. - * @return integer - */ - public static function toUInt8($value) - { - return pack("C*", $value); - } - - /** - * Returns binary data as an unsigned 8-bit integer. - * - * @param string $value The binary data string. - * @return integer - */ - public static function fromUInt8($value) - { - list(, $int) = unpack("C*", $value); - return $int; - } - - /** - * Returns a floating point number as machine endian ordered binary data. - * - * @param float $value The input value. - * @return string - */ - public static function toFloat($value) - { - return pack("f*", $value); - } - - /** - * Returns machine endian ordered binary data as a floating point number. - * - * @param string $value The binary data string. - * @return float - */ - public static function fromFloat($value) - { - list(, $float) = unpack("f*", $value); - return $float; - } - - /** - * Returns a floating point number as little-endian ordered binary data. - * - * @param float $value The input value. - * @return string - */ - public static function toFloatLE($value) - { - if (self::isBigEndian()) - return strrev(self::toFloat($value)); - else - return self::toFloat($value); - } - - /** - * Returns little-endian ordered binary data as a floating point number. - * - * @param string $value The binary data string. - * @return float - */ - public static function fromFloatLE($value) - { - if (self::isBigEndian()) - return self::fromFloat(strrev($value)); - else - return self::fromFloat($value); - } - - /** - * Returns a floating point number as big-endian ordered binary data. - * - * @param float $value The input value. - * @return string - */ - public static function toFloatBE($value) - { - if (self::isBigEndian()) - return self::toFloat($value); - else - return strrev(self::toFloat($value)); - } - - /** - * Returns big-endian ordered binary data as a float point number. - * - * @param string $value The binary data string. - * @return float - */ - public static function fromFloatBE($value) - { - if (self::isBigEndian()) - return self::fromFloat($value); - else - return self::fromFloat(strrev($value)); - } - - /** - * Returns string as binary data padded to given length with zeros. If length - * is smaller than the length of the string, it is considered as the length of - * the padding. - * - * @param string $value The input value. - * @param integer $length The length to which to pad the value. - * @param string $padding The padding character. - * @return string - */ - public static function toString8($value, $length = false, $padding = "\0") - { - if ($length === false) - $length = strlen($value); - if ($length < ($tmp = strlen($value))) - $length = $tmp + $length; - return str_pad($value, $length, $padding); - } - - /** - * Returns binary data as string. Removes terminating zero. - * - * @param string $value The binary data string. - * @return string - */ - public static function fromString8($value) - { - return rtrim($value, "\0"); - } - - /** - * Returns the multibyte string as binary data with given byte order mark - * (BOM) and padded to given length with zeros. Length is given in unicode - * characters so each character adds two zeros to the string. If length is - * smaller than the length of the string, it is considered as the length of - * the padding. - * - * If byte order mark is false no mark is inserted to the binary - * data. - * - * @param string $value The input value. - * @param integer $order The byte order of the binary data string. - * @param integer $length The length to which to pad the value. - * @param string $padding The padding character. - * @return string - */ - public static function toString16 - ($value, $order = false, $length = false, $padding = "\0") - { - if ($length === false) - $length = (int)(strlen($value) / 2); - if ($length < ($tmp = strlen($value) / 2)) - $length = $tmp + $length; - if ($order == self::BIG_ENDIAN_ORDER && - !(ord($value[0]) == 0xfe && ord($value[1]) == 0xff)) { - $value = 0xfeff . $value; - $length++; - } - if ($order == self::LITTLE_ENDIAN_ORDER && - !(ord($value[0]) == 0xff && ord($value[1]) == 0xfe)) { - $value = 0xfffe . $value; - $length++; - } - return str_pad($value, $length * 2, $padding); - } - - /** - * Returns binary data as multibyte Unicode string. Removes terminating zero. - * - * The byte order is possibly determined from the byte order mark included in - * the binary data string. The order parameter is updated if the BOM is found. - * - * @param string $value The binary data string. - * @param integer $order The endianess of the string. - * @param integer $trimOrder Whether to remove the byte order mark from the - * string. - * @return string - */ - public static function fromString16 - ($value, &$order = false, $trimOrder = false) - { - if (strlen($value) < 2) - return ""; - - if (ord($value[0]) == 0xfe && ord($value[1]) == 0xff) { - $order = self::BIG_ENDIAN_ORDER; - if ($trimOrder) - $value = substr($value, 2); - } - if (ord($value[0]) == 0xff && ord($value[1]) == 0xfe) { - $order = self::LITTLE_ENDIAN_ORDER; - if ($trimOrder) - $value = substr($value, 2); - } - - return substr($value, -2) == "\0\0" ? substr($value, 0, -2) : $value; - } - - /** - * Returns hexadecimal string having high nibble first as binary data. - * - * @param string $value The input value. - * @return string - */ - public static function toHHex($value) - { - return pack("H*", $value); - } - - /** - * Returns binary data as hexadecimal string having high nibble first. - * - * @param string $value The binary data string. - * @return string - */ - public static function fromHHex($value) - { - list($hex) = unpack("H*0", $value); - return $hex; - } - - /** - * Returns hexadecimal string having low nibble first as binary data. - * - * @param string $value The input value. - * @return string - */ - public static function toLHex($value) - { - return pack("h*", $value); - } - - /** - * Returns binary data as hexadecimal string having low nibble first. - * - * @param string $value The binary data string. - * @return string - */ - public static function fromLHex($value) - { - list($hex) = unpack("h*0", $value); - return $hex; - } - - /** - * Returns big-endian ordered hexadecimal GUID string as little-endian ordered - * binary data string. - * - * @param string $value The input value. - * @return string - */ - public static function toGUID($value) - { - $string = ""; $C = preg_split("/-/", $value); - return pack - ("V1v2N2", hexdec($C[0]), hexdec($C[1]), hexdec($C[2]), - hexdec($C[3] . substr($C[4], 0, 4)), hexdec(substr($C[4], 4))); - } - - /** - * Returns the little-endian ordered binary data as big-endian ordered - * hexadecimal GUID string. - * - * @param string $value The binary data string. - * @return string - */ - public static function fromGUID($value) - { - $C = @unpack("V1V/v2v/N2N", $value); - list($hex) = @unpack("H*0", pack - ("NnnNN", $C["V"], $C["v1"], $C["v2"], $C["N1"], $C["N2"])); - - /* Fixes a bug in PHP versions earlier than Jan 25 2006 */ - if (implode("", unpack("H*", pack("H*", "a"))) == "a00") - $hex = substr($hex, 0, -1); - - return preg_replace - ("/^(.{8})(.{4})(.{4})(.{4})/", "\\1-\\2-\\3-\\4-", $hex); - } -} diff --git a/src/Twiddling.php b/src/Twiddling.php deleted file mode 100644 index f48ef0a..0000000 --- a/src/Twiddling.php +++ /dev/null @@ -1,233 +0,0 @@ - - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ - * @static - */ -final class Twiddling -{ - /** - * Default private constructor for a static class. - */ - private function __construct() {} - - /** - * Sets a bit at a given position in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $position The position of the bit to set. - * @param boolean $on Whether to enable or clear the bit. - * @return integer - */ - public static function setBit($integer, $position, $on) - { - return $on ? self::enableBit($integer, $position) : - self::clearBit($integer, $position); - } - - /** - * Enables a bit at a given position in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $position The position of the bit to enable. - * @return integer - */ - public static function enableBit($integer, $position) - { - return $integer | (1 << $position); - } - - /** - * Clears a bit at a given position in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $position The position of the bit to clear. - * @return integer - */ - public static function clearBit($integer, $position) - { - return $integer & ~(1 << $position); - } - - /** - * Toggles a bit at a given position in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $position The position of the bit to toggle. - * @return integer - */ - public static function toggleBit($integer, $position) - { - return $integer ^ (1 << $position); - } - - /** - * Tests a bit at a given position in an integer. - * - * @param integer $integer The value to test. - * @param integer $position The position of the bit to test. - * @return boolean - */ - public static function testBit($integer, $position) - { - return ($integer & (1 << $position)) != 0; - } - - /** - * Sets a given set of bits in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $bits The bits to set. - * @param boolean $on Whether to enable or clear the bits. - * @return integer - */ - public static function setBits($integer, $bits, $on) - { - return $on ? self::enableBits($integer, $bits) : - self::clearBits($integer, $bits); - } - - /** - * Enables a given set of bits in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $bits The bits to enable. - * @return integer - */ - public static function enableBits($integer, $bits) - { - return $integer | $bits; - } - - /** - * Clears a given set of bits in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $bits The bits to clear. - * @return integer - */ - public static function clearBits($integer, $bits) - { - return $integer & ~$bits; - } - - /** - * Toggles a given set of bits in an integer. - * - * @param integer $integer The value to manipulate. - * @param integer $bits The bits to toggle. - * @return integer - */ - public static function toggleBits($integer, $bits) - { - return $integer ^ $bits; - } - - /** - * Tests a given set of bits in an integer - * returning whether all bits are set. - * - * @param integer $integer The value to test. - * @param integer $bits The bits to test. - * @return boolean - */ - public static function testAllBits($integer, $bits) - { - return ($integer & $bits) == $bits; - } - - /** - * Tests a given set of bits in an integer - * returning whether any bits are set. - * - * @param integer $integer The value to test. - * @param integer $bits The bits to test. - * @return boolean - */ - public static function testAnyBits($integer, $bits) - { - return ($integer & $bits) != 0; - } - - /** - * Stores a value in a given range in an integer. - * - * @param integer $integer The value to store into. - * @param integer $start The position to store from. Must be <= $end. - * @param integer $end The position to store to. Must be >= $start. - * @param integer $value The value to store. - * @return integer - */ - public static function setValue($integer, $start, $end, $value) - { - return self::clearBits - ($integer, self::getMask($start, $end) << $start) | ($value << $start); - } - - /** - * Retrieves a value from a given range in an integer, inclusive. - * - * @param integer $integer The value to read from. - * @param integer $start The position to read from. Must be <= $end. - * @param integer $end The position to read to. Must be >= $start. - * @return integer - */ - public static function getValue($integer, $start, $end) - { - return ($integer & self::getMask($start, $end)) >> $start; - } - - /** - * Returns an integer with all bits set from start to end. - * - * @param integer $start The position to start setting bits from. Must - * be <= $end. - * @param integer $end The position to stop setting bits. Must be >= $start. - * @return integer - */ - public static function getMask($start, $end) - { - return ($tmp = (1 << $end)) + $tmp - (1 << $start); - } -} diff --git a/src/Zend/Bit/Twiddling.php b/src/Zend/Bit/Twiddling.php new file mode 100644 index 0000000..d34c4a1 --- /dev/null +++ b/src/Zend/Bit/Twiddling.php @@ -0,0 +1,223 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @static + */ +final class Zend_Bit_Twiddling +{ + /** + * Default private constructor for a static class. + */ + private function __construct() + { + } + + /** + * Sets a bit at a given position in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $position The position of the bit to set. + * @param boolean $on Whether to enable or clear the bit. + * @return integer + */ + public static function setBit($integer, $position, $on) + { + return $on ? self::enableBit($integer, $position) : + self::clearBit($integer, $position); + } + + /** + * Enables a bit at a given position in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $position The position of the bit to enable. + * @return integer + */ + public static function enableBit($integer, $position) + { + return $integer | (1 << $position); + } + + /** + * Clears a bit at a given position in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $position The position of the bit to clear. + * @return integer + */ + public static function clearBit($integer, $position) + { + return $integer & ~(1 << $position); + } + + /** + * Toggles a bit at a given position in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $position The position of the bit to toggle. + * @return integer + */ + public static function toggleBit($integer, $position) + { + return $integer ^ (1 << $position); + } + + /** + * Tests a bit at a given position in an integer. + * + * @param integer $integer The value to test. + * @param integer $position The position of the bit to test. + * @return boolean + */ + public static function testBit($integer, $position) + { + return ($integer & (1 << $position)) != 0; + } + + /** + * Sets a given set of bits in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $bits The bits to set. + * @param boolean $on Whether to enable or clear the bits. + * @return integer + */ + public static function setBits($integer, $bits, $on) + { + return $on ? self::enableBits($integer, $bits) : + self::clearBits($integer, $bits); + } + + /** + * Enables a given set of bits in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $bits The bits to enable. + * @return integer + */ + public static function enableBits($integer, $bits) + { + return $integer | $bits; + } + + /** + * Clears a given set of bits in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $bits The bits to clear. + * @return integer + */ + public static function clearBits($integer, $bits) + { + return $integer & ~$bits; + } + + /** + * Toggles a given set of bits in an integer. + * + * @param integer $integer The value to manipulate. + * @param integer $bits The bits to toggle. + * @return integer + */ + public static function toggleBits($integer, $bits) + { + return $integer ^ $bits; + } + + /** + * Tests a given set of bits in an integer + * returning whether all bits are set. + * + * @param integer $integer The value to test. + * @param integer $bits The bits to test. + * @return boolean + */ + public static function testAllBits($integer, $bits) + { + return ($integer & $bits) == $bits; + } + + /** + * Tests a given set of bits in an integer + * returning whether any bits are set. + * + * @param integer $integer The value to test. + * @param integer $bits The bits to test. + * @return boolean + */ + public static function testAnyBits($integer, $bits) + { + return ($integer & $bits) != 0; + } + + /** + * Stores a value in a given range in an integer. + * + * @param integer $integer The value to store into. + * @param integer $start The position to store from. Must be <= $end. + * @param integer $end The position to store to. Must be >= $start. + * @param integer $value The value to store. + * @return integer + */ + public static function setValue($integer, $start, $end, $value) + { + return self::clearBits + ($integer, self::getMask + ($start, $end) << $start) | ($value << $start); + } + + /** + * Retrieves a value from a given range in an integer, inclusive. + * + * @param integer $integer The value to read from. + * @param integer $start The position to read from. Must be <= $end. + * @param integer $end The position to read to. Must be >= $start. + * @return integer + */ + public static function getValue($integer, $start, $end) + { + return ($integer & self::getMask($start, $end)) >> $start; + } + + /** + * Returns an integer with all bits set from start to end. + * + * @param integer $start The position to start setting bits from. Must + * be <= $end. + * @param integer $end The position to stop setting bits. Must + * be >= $start. + * @return integer + */ + public static function getMask($start, $end) + { + return ($tmp = (1 << $end)) + $tmp - (1 << $start); + } +} diff --git a/src/Zend/Io/Exception.php b/src/Zend/Io/Exception.php new file mode 100644 index 0000000..52318a0 --- /dev/null +++ b/src/Zend/Io/Exception.php @@ -0,0 +1,38 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_Exception extends Zend_Exception +{} diff --git a/src/Zend/Io/FileReader.php b/src/Zend/Io/FileReader.php new file mode 100644 index 0000000..8ef48fb --- /dev/null +++ b/src/Zend/Io/FileReader.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_FileReader extends Zend_Io_Reader +{ + /** + * Constructs the Zend_Io_FileReader class with given path to the file. By + * default the file is opened in read (rb) mode. + * + * @param string $filename The path to the file. + * @throws Zend_Io_Exception if the file cannot be read + */ + public function __construct($filename, $mode = null) + { + if ($mode === null) + $mode = 'rb'; + if (!file_exists($filename) || !is_readable($filename) || + ($fd = fopen($filename, $mode)) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Unable to open file for reading: ' . $filename); + } + parent::__construct($fd); + } + + /** + * Closes the file descriptor. + */ + public function __destruct() + { + $this->close(); + } +} diff --git a/src/Zend/Io/FileWriter.php b/src/Zend/Io/FileWriter.php new file mode 100644 index 0000000..591e3f9 --- /dev/null +++ b/src/Zend/Io/FileWriter.php @@ -0,0 +1,66 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_FileWriter extends Zend_Io_Writer +{ + /** + * Constructs the Zend_Io_FileWriter class with given path to the file. By + * default the file is opened in write mode without altering its content + * (ie r+b mode if the file exists, and wb mode if not). + * + * @param string $filename The path to the file. + * @throws Zend_Io_Exception if the file cannot be written + */ + public function __construct($filename, $mode = null) + { + if ($mode === null) + $mode = file_exists($filename) ? 'r+b' : 'wb'; + if (($fd = fopen($filename, $mode)) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Unable to open file for writing: ' . $filename); + } + parent::__construct($fd); + } + + /** + * Closes the file descriptor. + */ + public function __destruct() + { + $this->close(); + } +} diff --git a/src/Zend/Io/Reader.php b/src/Zend/Io/Reader.php new file mode 100644 index 0000000..2145c85 --- /dev/null +++ b/src/Zend/Io/Reader.php @@ -0,0 +1,785 @@ + + * @author Ryan Butterfield + * @author Marc Bennewitz + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_Reader +{ + const MACHINE_ENDIAN_ORDER = 0; + const LITTLE_ENDIAN_ORDER = 1; + const BIG_ENDIAN_ORDER = 2; + + /** + * The endianess of the current machine. + * + * @var integer + */ + private static $_endianess = 0; + + /** + * The resource identifier of the stream. + * + * @var resource + */ + protected $_fd = null; + + /** + * Size of the underlying stream. + * + * @var integer + */ + protected $_size = 0; + + /** + * Constructs the Zend_Io_Reader class with given open file descriptor. + * + * @param resource $fd The file descriptor. + * @throws Zend_Io_Exception if given file descriptor is not valid + */ + public function __construct($fd) + { + if (!is_resource($fd) || + !in_array(get_resource_type($fd), array('stream'))) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Invalid resource type (only resources of type stream are supported)'); + } + + $this->_fd = $fd; + + $offset = $this->getOffset(); + fseek($this->_fd, 0, SEEK_END); + $this->_size = ftell($this->_fd); + fseek($this->_fd, $offset); + } + + /** + * Default destructor. + */ + public function __destruct() {} + + /** + * Checks whether there is more to be read from the stream. Returns + * true if the end has not yet been reached; false + * otherwise. + * + * @return boolean + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function available() + { + return $this->getOffset() < $this->getSize(); + } + + /** + * Returns the current point of operation. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function getOffset() + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + return ftell($this->_fd); + } + + /** + * Sets the point of operation, ie the cursor offset value. The offset may + * also be set to a negative value when it is interpreted as an offset from + * the end of the stream instead of the beginning. + * + * @param integer $offset The new point of operation. + * @return void + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function setOffset($offset) + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + fseek($this->_fd, $offset < 0 ? $this->getSize() + $offset : $offset); + } + + /** + * Returns the stream size in bytes. + * + * @return integer + */ + public function getSize() + { + return $this->_size; + } + + /** + * Returns the underlying stream file descriptor. + * + * @return resource + */ + public function getFileDescriptor() + { + return $this->_fd; + } + + /** + * Jumps size amount of bytes in the stream. + * + * @param integer $size The amount of bytes. + * @return void + * @throws Zend_Io_Exception if size attribute is negative or if + * an I/O error occurs + */ + public function skip($size) + { + if ($size < 0) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Size cannot be negative'); + } + if ($size == 0) { + return; + } + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + fseek($this->_fd, $size, SEEK_CUR); + } + + /** + * Reads length amount of bytes from the stream. + * + * @param integer $length The amount of bytes. + * @return string + * @throws Zend_Io_Exception if length attribute is negative or + * if an I/O error occurs + */ + public function read($length) + { + if ($length < 0) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Length cannot be negative'); + } + if ($length == 0) { + return ''; + } + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + return fread($this->_fd, $length); + } + + /** + * Reads 1 byte from the stream and returns binary data as an 8-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt8() + { + $ord = ord($this->read(1)); + if ($ord > 127) { + return -$ord - 2 * (128 - $ord); + } else { + return $ord; + } + } + + /** + * Reads 1 byte from the stream and returns binary data as an unsigned 8-bit + * integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt8() + { + return ord($this->read(1)); + } + + /** + * Returns machine endian ordered binary data as signed 16-bit integer. + * + * @param string $value The binary data string. + * @return integer + */ + private function _fromInt16($value) + { + list(, $int) = unpack('s*', $value); + return $int; + } + + /** + * Reads 2 bytes from the stream and returns little-endian ordered binary + * data as signed 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt16LE() + { + if ($this->_isBigEndian()) { + return $this->_fromInt16(strrev($this->read(2))); + } else { + return $this->_fromInt16($this->read(2)); + } + } + + /** + * Reads 2 bytes from the stream and returns big-endian ordered binary data + * as signed 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt16BE() + { + if ($this->_isLittleEndian()) { + return $this->_fromInt16(strrev($this->read(2))); + } else { + return $this->_fromInt16($this->read(2)); + } + } + + /** + * Reads 2 bytes from the stream and returns machine ordered binary data + * as signed 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt16() + { + return $this->_fromInt16($this->read(2)); + } + + /** + * Returns machine endian ordered binary data as unsigned 16-bit integer. + * + * @param string $value The binary data string. + * @param integer $order The byte order of the binary data string. + * @return integer + */ + private function _fromUInt16($value, $order = 0) + { + list(, $int) = unpack + (($order == self::BIG_ENDIAN_ORDER ? 'n' : + ($order == self::LITTLE_ENDIAN_ORDER ? 'v' : 'S')) . '*', + $value); + return $int; + } + + /** + * Reads 2 bytes from the stream and returns little-endian ordered binary + * data as unsigned 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt16LE() + { + return $this->_fromUInt16($this->read(2), self::LITTLE_ENDIAN_ORDER); + } + + /** + * Reads 2 bytes from the stream and returns big-endian ordered binary data + * as unsigned 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt16BE() + { + return $this->_fromUInt16($this->read(2), self::BIG_ENDIAN_ORDER); + } + + /** + * Reads 2 bytes from the stream and returns machine ordered binary data + * as unsigned 16-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt16() + { + return $this->_fromUInt16($this->read(2), self::MACHINE_ENDIAN_ORDER); + } + + /** + * Returns machine-endian ordered binary data as signed 32-bit integer. + * + * @param string $value The binary data string. + * @return integer + */ + private final function _fromInt32($value) + { + list(, $int) = unpack('l*', $value); + return $int; + } + + /** + * Reads 4 bytes from the stream and returns little-endian ordered binary + * data as signed 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt32LE() + { + if ($this->_isBigEndian()) + return $this->_fromInt32(strrev($this->read(4))); + else + return $this->_fromInt32($this->read(4)); + } + + /** + * Reads 4 bytes from the stream and returns big-endian ordered binary data + * as signed 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt32BE() + { + if ($this->_isLittleEndian()) + return $this->_fromInt32(strrev($this->read(4))); + else + return $this->_fromInt32($this->read(4)); + } + + /** + * Reads 4 bytes from the stream and returns machine ordered binary data + * as signed 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt32() + { + return $this->_fromInt32($this->read(4)); + } + + /** + * Reads 4 bytes from the stream and returns little-endian ordered binary + * data as unsigned 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt32LE() + { + if (PHP_INT_SIZE < 8) { + list(, $lo, $hi) = unpack('v*', $this->read(4)); + return $hi * (0xffff+1) + $lo; // eq $hi << 16 | $lo + } else { + list(, $int) = unpack('V*', $this->read(4)); + return $int; + } + } + + /** + * Reads 4 bytes from the stream and returns big-endian ordered binary data + * as unsigned 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt32BE() + { + if (PHP_INT_SIZE < 8) { + list(, $hi, $lo) = unpack('n*', $this->read(4)); + return $hi * (0xffff+1) + $lo; // eq $hi << 16 | $lo + } else { + list(, $int) = unpack('N*', $this->read(4)); + return $int; + } + } + + /** + * Reads 4 bytes from the stream and returns machine ordered binary data + * as unsigned 32-bit integer. + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readUInt32() + { + if (PHP_INT_SIZE < 8) { + list(, $hi, $lo) = unpack('L*', $this->read(4)); + return $hi * (0xffff+1) + $lo; // eq $hi << 16 | $lo + } else { + list(, $int) = unpack('L*', $this->read(4)); + return $int; + } + } + + /** + * Reads 8 bytes from the stream and returns little-endian ordered binary + * data as 64-bit float. + * + * {@internal PHP does not support 64-bit integers as the long + * integer is of 32-bits but using aritmetic operations it is implicitly + * converted into floating point which is of 64-bits long.}} + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt64LE() + { + list(, $lolo, $lohi, $hilo, $hihi) = unpack('v*', $this->read(8)); + return ($hihi * (0xffff+1) + $hilo) * (0xffffffff+1) + + ($lohi * (0xffff+1) + $lolo); + } + + /** + * Reads 8 bytes from the stream and returns big-endian ordered binary data + * as 64-bit float. + * + * {@internal PHP does not support 64-bit integers as the long integer is of + * 32-bits but using aritmetic operations it is implicitly converted into + * floating point which is of 64-bits long.}} + * + * @return integer + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readInt64BE() + { + list(, $hihi, $hilo, $lohi, $lolo) = unpack('n*', $this->read(8)); + return ($hihi * (0xffff+1) + $hilo) * (0xffffffff+1) + + ($lohi * (0xffff+1) + $lolo); + } + + /** + * Returns machine endian ordered binary data as a 32-bit floating point + * number as defined by IEEE 754. + * + * @param string $value The binary data string. + * @return float + */ + private function _fromFloat($value) + { + list(, $float) = unpack('f', $value); + return $float; + } + + /** + * Reads 4 bytes from the stream and returns little-endian ordered binary + * data as a 32-bit float point number as defined by IEEE 754. + * + * @return float + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readFloatLE() + { + if ($this->_isBigEndian()) { + return $this->_fromFloat(strrev($this->read(4))); + } else { + return $this->_fromFloat($this->read(4)); + } + } + + /** + * Reads 4 bytes from the stream and returns big-endian ordered binary data + * as a 32-bit float point number as defined by IEEE 754. + * + * @return float + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readFloatBE() + { + if ($this->_isLittleEndian()) { + return $this->_fromFloat(strrev($this->read(4))); + } else { + return $this->_fromFloat($this->read(4)); + } + } + + /** + * Returns machine endian ordered binary data as a 64-bit floating point + * number as defined by IEEE754. + * + * @param string $value The binary data string. + * @return float + */ + private function _fromDouble($value) + { + list(, $double) = unpack('d', $value); + return $double; + } + + /** + * Reads 8 bytes from the stream and returns little-endian ordered binary + * data as a 64-bit floating point number as defined by IEEE 754. + * + * @return float + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readDoubleLE() + { + if ($this->_isBigEndian()) { + return $this->_fromDouble(strrev($this->read(8))); + } else { + return $this->_fromDouble($this->read(8)); + } + } + + /** + * Reads 8 bytes from the stream and returns big-endian ordered binary data + * as a 64-bit float point number as defined by IEEE 754. + * + * @return float + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readDoubleBE() + { + if ($this->_isLittleEndian()) { + return $this->_fromDouble(strrev($this->read(8))); + } else { + return $this->_fromDouble($this->read(8)); + } + } + + /** + * Reads length amount of bytes from the stream and returns + * binary data as string. Removes terminating zero. + * + * @param integer $length The amount of bytes. + * @param string $charList The list of characters you want to strip. + * @return string + * @throws Zend_Io_Exception if length attribute is negative or + * if an I/O error occurs + */ + public final function readString8($length, $charList = "\0") + { + return rtrim($this->read($length), $charList); + } + + /** + * Reads length amount of bytes from the stream and returns + * binary data as multibyte Unicode string. Removes terminating zero. + * + * The byte order is possibly determined from the byte order mark included + * in the binary data string. The order parameter is updated if the BOM is + * found. + * + * @param integer $length The amount of bytes. + * @param integer $order The endianess of the string. + * @param integer $trimOrder Whether to remove the byte order mark read the + * string. + * @return string + * @throws Zend_Io_Exception if length attribute is negative or + * if an I/O error occurs + */ + public final function readString16 + ($length, &$order = null, $trimOrder = false) + { + $value = $this->read($length); + + if (strlen($value) < 2) { + return ''; + } + + if (ord($value[0]) == 0xfe && ord($value[1]) == 0xff) { + $order = self::BIG_ENDIAN_ORDER; + if ($trimOrder) { + $value = substr($value, 2); + } + } + if (ord($value[0]) == 0xff && ord($value[1]) == 0xfe) { + $order = self::LITTLE_ENDIAN_ORDER; + if ($trimOrder) { + $value = substr($value, 2); + } + } + + while (substr($value, -2) == "\0\0") { + $value = substr($value, 0, -2); + } + + return $value; + } + + /** + * Reads length amount of bytes from the stream and returns + * binary data as hexadecimal string having high nibble first. + * + * @param integer $length The amount of bytes. + * @return string + * @throws Zend_Io_Exception if length attribute is negative or + * if an I/O error occurs + */ + public final function readHHex($length) + { + list($hex) = unpack('H*0', $this->read($length)); + return $hex; + } + + /** + * Reads length amount of bytes from the stream and returns + * binary data as hexadecimal string having low nibble first. + * + * @param integer $length The amount of bytes. + * @return string + * @throws Zend_Io_Exception if length attribute is negative or + * if an I/O error occurs + */ + public final function readLHex($length) + { + list($hex) = unpack('h*0', $this->read($length)); + return $hex; + } + + /** + * Reads 16 bytes from the stream and returns the little-endian ordered + * binary data as mixed-ordered hexadecimal GUID string. + * + * @return string + * @throws Zend_Io_Exception if an I/O error occurs + */ + public final function readGuid() + { + $C = @unpack('V1V/v2v/N2N', $this->read(16)); + list($hex) = @unpack('H*0', pack + ('NnnNN', $C['V'], $C['v1'], $C['v2'], $C['N1'], $C['N2'])); + + /* Fixes a bug in PHP versions earlier than Jan 25 2006 */ + if (implode('', unpack('H*', pack('H*', 'a'))) == 'a00') { + $hex = substr($hex, 0, -1); + } + + return preg_replace + ('/^(.{8})(.{4})(.{4})(.{4})/', "\\1-\\2-\\3-\\4-", $hex); + } + + /** + * Resets the stream. Attempts to reset it in some way appropriate to the + * particular stream, for example by repositioning it to its starting point. + * + * @return void + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function reset() + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + fseek($this->_fd, 0); + } + + /** + * Closes the stream. Once a stream has been closed, further calls to read + * methods will throw an exception. Closing a previously-closed stream, + * however, has no effect. + * + * @return void + */ + public function close() + { + if ($this->_fd !== null) { + @fclose($this->_fd); + $this->_fd = null; + } + } + + /** + * Returns the current machine endian order. + * + * @return integer + */ + private function _getEndianess() + { + if (self::$_endianess === 0) { + self::$_endianess = $this->_fromInt32("\x01\x00\x00\x00") == 1 ? + self::LITTLE_ENDIAN_ORDER : self::BIG_ENDIAN_ORDER; + } + return self::$_endianess; + } + + /** + * Returns whether the current machine endian order is little endian. + * + * @return boolean + */ + private function _isLittleEndian() + { + return $this->_getEndianess() == self::LITTLE_ENDIAN_ORDER; + } + + /** + * Returns whether the current machine endian order is big endian. + * + * @return boolean + */ + private function _isBigEndian() + { + return $this->_getEndianess() == self::BIG_ENDIAN_ORDER; + } + + /** + * Magic function so that $obj->value will work. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst(strtolower($name)))) { + return call_user_func + (array($this, 'get' . ucfirst(strtolower($name)))); + } else { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unknown 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(strtolower($name)))) { + call_user_func + (array($this, 'set' . ucfirst(strtolower($name))), $value); + } else { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Io/StringReader.php b/src/Zend/Io/StringReader.php new file mode 100644 index 0000000..46d338c --- /dev/null +++ b/src/Zend/Io/StringReader.php @@ -0,0 +1,86 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_StringReader extends Zend_Io_Reader +{ + /** + * Constructs the Zend_Io_StringReader class with given source string. + * + * @param string $data The string to use as the source. + * @param integer $length If the length argument is given, + * reading will stop after length bytes have been read or + * the end of string is reached, whichever comes first. + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function __construct($data, $length = null) + { + if (($this->_fd = fopen('php://memory', 'w+b')) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unable to open php://memory stream'); + } + if ($data !== null && is_string($data)) { + if ($length === null) { + $length = strlen($data); + } + if (($this->_size = fwrite($this->_fd, $data, $length)) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Unable to write data to php://memory stream'); + } + fseek($this->_fd, 0); + } + } + + /** + * Returns the string representation of this class. + */ + public function toString() + { + $offset = $this->getOffset(); + $this->setOffset(0); + $data = $this->read($this->getSize()); + $this->setOffset($offset); + return $data; + } + + /** + * Closes the file descriptor. + */ + public function __destruct() + { + $this->close(); + } +} diff --git a/src/Zend/Io/StringWriter.php b/src/Zend/Io/StringWriter.php new file mode 100644 index 0000000..b743a2f --- /dev/null +++ b/src/Zend/Io/StringWriter.php @@ -0,0 +1,89 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_StringWriter extends Zend_Io_Writer +{ + /** + * Constructs the Zend_Io_StringWriter class with given source string. + * + * @param string $data The string to use as the source. + * @param integer $length If the length argument is given, + * reading will stop after length bytes have been read or + * the end of string is reached, whichever comes first. + * @throws Zend_Io_Exception if an I/O error occurs + */ + public function __construct($data = null, $length = null) + { + if (($this->_fd = fopen('php://memory', 'w+b')) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unable to open php://memory stream'); + } + if ($data !== null && is_string($data)) { + if ($length === null) { + $length = strlen($data); + } + if (($this->_size = fwrite($this->_fd, $data, $length)) === false) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Unable to write data to php://memory stream'); + } + fseek($this->_fd, 0); + } + } + + /** + * Returns the string representation of this class. + */ + public function toString() + { + if ($this->getSize() == 0) { + return ''; + } + $offset = $this->getOffset(); + $this->setOffset(0); + $data = fread($this->getFileDescriptor(), $this->getSize()); + $this->setOffset($offset); + return $data; + } + + /** + * Closes the file descriptor. + */ + public function __destruct() + { + $this->close(); + } +} diff --git a/src/Zend/Io/Writer.php b/src/Zend/Io/Writer.php new file mode 100644 index 0000000..9359f7c --- /dev/null +++ b/src/Zend/Io/Writer.php @@ -0,0 +1,631 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Io_Writer +{ + const MACHINE_ENDIAN_ORDER = 0; + const LITTLE_ENDIAN_ORDER = 1; + const BIG_ENDIAN_ORDER = 2; + + /** + * The endianess of the current machine. + * + * @var integer + */ + private static $_endianess = 0; + + /** + * The resource identifier of the stream. + * + * @var resource + */ + protected $_fd = null; + + /** + * Size of the underlying stream. + * + * @var integer + */ + protected $_size = 0; + + /** + * Constructs the Zend_Io_Writer class with given open file descriptor. + * + * @param resource $fd The file descriptor. + * @throws Zend_Io_Exception if file descriptor is not valid + */ + public function __construct($fd) + { + if (!is_resource($fd) || + !in_array(get_resource_type($fd), array('stream'))) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception + ('Invalid resource type (only resources of type stream are supported)'); + } + + $this->_fd = $fd; + + $offset = $this->getOffset(); + fseek($this->_fd, 0, SEEK_END); + $this->_size = ftell($this->_fd); + fseek($this->_fd, $offset); + } + + /** + * Default destructor. + */ + public function __destruct() {} + + /** + * Returns the current point of operation. + * + * @return integer + * @throws Zend_Io_Exception if the stream is closed + */ + public function getOffset() + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + return ftell($this->_fd); + } + + /** + * Sets the point of operation, ie the cursor offset value. The offset may + * also be set to a negative value when it is interpreted as an offset from + * the end of the stream instead of the beginning. + * + * @param integer $offset The new point of operation. + * @return void + * @throws Zend_Io_Exception if the stream is closed + */ + public function setOffset($offset) + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + fseek($this->_fd, $offset < 0 ? $this->getSize() + $offset : $offset); + } + + /** + * Returns the stream size in bytes. + * + * @return integer + * @throws Zend_Io_Exception if the stream is closed + */ + public function getSize() + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + return $this->_size; + } + + /** + * Sets the stream size in bytes, and truncates if required. + * + * @param integer $size The new size + * @return void + * @throws Zend_Io_Exception if the stream is closed + */ + public function setSize($size) + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + ftruncate($this->_fd, $size); + } + + /** + * Returns the underlying stream file descriptor. + * + * @return resource + */ + public function getFileDescriptor() + { + return $this->_fd; + } + + /** + * Writes value up to length bytes to the stream. + * + * @param string $value The value to write to the stream. + * @param integer $length The number of bytes to write. Defaults to the + * length of the given value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public function write($value, $length = null) + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + if ($length === null) { + $length = strlen($value); + } + fwrite($this->_fd, $value, $length); + $this->_size += $length; + return $this; + } + + /** + * Writes an 8-bit integer as binary data to the stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt8($value) + { + return $this->write(pack('c*', $value)); + } + + /** + * Writes an unsigned 8-bit integer as binary data to the stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeUInt8($value) + { + return $this->write(pack('C*', $value)); + } + + /** + * Returns signed 16-bit integer as machine endian ordered binary data. + * + * @param integer $value The input value. + * @return string + */ + private function _toInt16($value) + { + return pack('s*', $value); + } + + /** + * Writes a signed 16-bit integer as little-endian ordered binary data to + * the stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt16LE($value) + { + if ($this->_isLittleEndian()) { + return $this->write(strrev($this->_toInt16($value))); + } else { + return $this->write($this->_toInt16($value)); + } + } + + /** + * Returns signed 16-bit integer as big-endian ordered binary data to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt16BE($value) + { + if ($this->_isBigEndian()) { + return $this->write(strrev($this->_toInt16($value))); + } else { + return $this->write($this->_toInt16($value)); + } + } + + /** + * Writes unsigned 16-bit integer as little-endian ordered binary data + * to the stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeUInt16LE($value) + { + return $this->write(pack('v*', $value)); + } + + /** + * Writes unsigned 16-bit integer as big-endian ordered binary data to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeUInt16BE($value) + { + return $this->write(pack('n*', $value)); + } + + /** + * Returns signed 32-bit integer as machine-endian ordered binary data. + * + * @param integer $value The input value. + * @return string + */ + private final function _toInt32($value) + { + return pack('l*', $value); + } + + /** + * Writes signed 32-bit integer as little-endian ordered binary data to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt32LE($value) + { + if ($this->_isLittleEndian()) { + return $this->write(strrev($this->_toInt32($value))); + } else { + return $this->write($this->_toInt32($value)); + } + } + + /** + * Writes signed 32-bit integer as big-endian ordered binary data to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt32BE($value) + { + if ($this->_isBigEndian()) { + return $this->write(strrev($this->_toInt32($value))); + } else { + return $this->write($this->_toInt32($value)); + } + } + + /** + * Writes unsigned 32-bit integer as little-endian ordered binary data to + * the stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeUInt32LE($value) + { + return $this->write(pack('V*', $value)); + } + + /** + * Writes unsigned 32-bit integer as big-endian ordered binary data to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeUInt32BE($value) + { + return $this->write(pack('N*', $value)); + } + + /** + * Writes 64-bit float as little-endian ordered binary data string to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt64LE($value) + { + return $this->write + (pack('V*', $value & 0xffffffff, $value / (0xffffffff+1))); + } + + /** + * Writes 64-bit float as big-endian ordered binary data string to the + * stream. + * + * @param integer $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeInt64BE($value) + { + return $this->write + (pack('N*', $value / (0xffffffff+1), $value & 0xffffffff)); + } + + /** + * Returns a floating point number as machine endian ordered binary data. + * + * @param float $value The input value. + * @return string + */ + private function _toFloat($value) + { + return pack('f*', $value); + } + + /** + * Writes a floating point number as little-endian ordered binary data to + * the stream. + * + * @param float $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeFloatLE($value) + { + if ($this->_isLittleEndian()) { + return $this->write(strrev($this->_toFloat($value))); + } else { + return $this->write($this->_toFloat($value)); + } + } + + /** + * Writes a floating point number as big-endian ordered binary data to the + * stream. + * + * @param float $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeFloatBE($value) + { + if ($this->_isBigEndian()) { + return $this->write(strrev($this->_toFloat($value))); + } else { + return $this->write($this->_toFloat($value)); + } + } + + /** + * Writes string as binary data padded to given length with zeros. If + * length is smaller than the length of the string, it is + * considered as the length of the padding. + * + * @param string $value The input value. + * @param integer $length The length to which to pad the value. + * @param string $padding The padding character. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeString8($value, $length = null, $padding = "\0") + { + if ($length === null) { + $length = strlen($value); + } + if ($length < ($tmp = strlen($value))) { + $length = $tmp + $length; + } + return $this->write(str_pad($value, $length, $padding)); + } + + /** + * Writes the multibyte string as binary data with given byte order mark + * (BOM) and padded to given length with zeros. Length is given in unicode + * characters so each character adds two zeros to the string. If length is + * smaller than the length of the string, it is considered as the length of + * the padding. + * + * If byte order mark is null no mark is inserted to the binary + * data. + * + * @param string $value The input value. + * @param integer $order The byte order of the binary data string. + * @param integer $length The length to which to pad the value. + * @param string $padding The padding character. + * @return string + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeString16 + ($value, $order = null, $length = null, $padding = "\0") + { + if ($length === null) { + $length = (int)(strlen($value) / 2); + } + if ($length < ($tmp = strlen($value) / 2)) { + $length = $tmp + $length; + } + if ($order == self::BIG_ENDIAN_ORDER && + !(ord($value[0]) == 0xfe && ord($value[1]) == 0xff)) { + $value = 0xfeff . $value; + $length++; + } + if ($order == self::LITTLE_ENDIAN_ORDER && + !(ord($value[0]) == 0xff && ord($value[1]) == 0xfe)) { + $value = 0xfffe . $value; + $length++; + } + return $this->write(str_pad($value, $length * 2, $padding)); + } + + /** + * Writes hexadecimal string having high nibble first as binary data to the + * stream. + * + * @param string $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if length attribute is negative or + * if the stream is closed + */ + public final function writeHHex($value) + { + return $this->write(pack('H*', $value)); + } + + /** + * Writes hexadecimal string having low nibble first as binary data to the + * stream. + * + * @param string $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if length attribute is negative or + * if the stream is closed + */ + public final function writeLHex($value) + { + return $this->write(pack('h*', $value)); + } + + /** + * Writes big-endian ordered hexadecimal GUID string as little-endian + * ordered binary data string to the stream. + * + * @param string $value The input value. + * @return Zend_Io_Writer + * @throws Zend_Io_Exception if the stream is closed + */ + public final function writeGuid($value) + { + $string = ''; + $C = preg_split('/-/', $value); + return $this->write + (pack + ('V1v2N2', hexdec($C[0]), hexdec($C[1]), hexdec($C[2]), + hexdec($C[3] . substr($C[4], 0, 4)), hexdec(substr($C[4], 4)))); + } + + /** + * Forces write of all buffered output to the underlying resource. + * + * @return void + * @throws Zend_Io_Exception if the stream is closed + */ + public function flush() + { + if ($this->_fd === null) { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Cannot operate on a closed stream'); + } + fflush($this->_fd); + } + + /** + * Closes the stream. Once a stream has been closed, further calls to write + * methods will throw an exception. Closing a previously-closed stream, + * however, has no effect. + * + * @return void + * @throws Zend_Io_Exception if the stream is closed + */ + public function close() + { + if ($this->_fd !== null) { + @fclose($this->_fd); + $this->_fd = null; + } + } + + /** + * Returns the current machine endian order. + * + * @return integer + */ + private function _getEndianess() + { + if (self::$_endianess === 0) { + self::$_endianess = $this->_toInt32("\x01\x00\x00\x00") == 1 ? + self::LITTLE_ENDIAN_ORDER : self::BIG_ENDIAN_ORDER; + } + return self::$_endianess; + } + + /** + * Returns whether the current machine endian order is little endian. + * + * @return boolean + */ + private function _isLittleEndian() + { + return $this->_getEndianess() == self::LITTLE_ENDIAN_ORDER; + } + + /** + * Returns whether the current machine endian order is big endian. + * + * @return boolean + */ + private function _isBigEndian() + { + return $this->_getEndianess() == self::BIG_ENDIAN_ORDER; + } + + /** + * Magic function so that $obj->value will work. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst(strtolower($name)))) { + return call_user_func + (array($this, 'get' . ucfirst(strtolower($name)))); + } else { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unknown 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(strtolower($name)))) { + call_user_func + (array($this, 'set' . ucfirst(strtolower($name))), $value); + } else { + require_once('Zend/Io/Exception.php'); + throw new Zend_Io_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Media/Asf.php b/src/Zend/Media/Asf.php new file mode 100644 index 0000000..38550a6 --- /dev/null +++ b/src/Zend/Media/Asf.php @@ -0,0 +1,214 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Asf extends Zend_Media_Asf_Object_Container +{ + /** @var string */ + private $_filename; + + /** + * Constructs the ASF class with given file and options. + * + * The following options are currently recognized: + * o encoding -- Indicates the encoding that all the texts are presented + * with. By default this is set to utf-8. See the documentation of iconv + * for accepted values. + * o readonly -- Indicates that the file is read from a temporary location + * or another source it cannot be written back to. + * + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @param Array $options The options array. + */ + public function __construct($filename, $options = array()) + { + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + require_once 'Zend/Io/FileReader.php'; + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Asf_Exception($e->getMessage()); + } + if (is_string($filename) && !isset($options['readonly'])) { + $this->_filename = $filename; + } + } + $this->setOptions($options); + if ($this->getOption('encoding', null) === null) { + $this->setOption('encoding', 'utf-8'); + } + $this->setOffset(0); + $this->setSize($this->_reader->getSize()); + $this->constructObjects + (array + (self::HEADER => 'Header', + self::DATA => 'Data', + self::SIMPLE_INDEX => 'SimpleIndex', + self::INDEX => 'Index', + self::MEDIA_OBJECT_INDEX => 'MediaObjectIndex', + self::TIMECODE_INDEX => 'TimecodeIndex')); + } + + /** + * Returns the mandatory header object contained in this file. + * + * @return Zend_Media_Asf_Object_Header + */ + public function getHeader() + { + $header = $this->getObjectsByIdentifier(self::HEADER); + return $header[0]; + } + + /** + * Returns the mandatory data object contained in this file. + * + * @return Zend_Media_Asf_Object_Data + */ + public function getData() + { + $data = $this->getObjectsByIdentifier(self::DATA); + return $data[0]; + } + + /** + * Returns an array of index objects contained in this file. + * + * @return Array + */ + public function getIndices() + { + return $this->getObjectsByIdentifier + (self::SIMPLE_INDEX . '|' . self::INDEX . '|' . + self::MEDIA_OBJECT_INDEX . '|' . self::TIMECODE_INDEX); + } + + /** + * Writes the changes to given media file. All object offsets must be + * assumed to be invalid after the write operation. + * + * @param string $filename The optional path to the file, use null to save + * to the same file. + */ + public function write($filename) + { + if ($filename === null && ($filename = $this->_filename) === null) { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception + ('No file given to write to'); + } else if ($filename !== null && $this->_filename !== null && + realpath($filename) != realpath($this->_filename) && + !copy($this->_filename, $filename)) { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception + ('Unable to copy source to destination: ' . + realpath($this->_filename) . '->' . realpath($filename)); + } + + if (($fd = fopen + ($filename, file_exists($filename) ? 'r+b' : 'wb')) === false) { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception + ('Unable to open file for writing: ' . $filename); + } + + $header = $this->getHeader(); + $headerLengthOld = $header->getSize(); + $header->removeObjectsByIdentifier(Zend_Media_Asf_Object::PADDING); + $header->headerExtension->removeObjectsByIdentifier + (Zend_Media_Asf_Object::PADDING); + + require_once 'Zend/Io/StringWriter.php'; + $buffer = new Zend_Io_StringWriter(); + $header->write($buffer); + $headerData = $buffer->toString(); + $headerLengthNew = $header->getSize(); + + // Fits right in + if ($headerLengthOld == $headerLengthNew) { + } + + // Fits with adjusted padding + else if ($headerLengthOld >= $headerLengthNew + 24 /* for header */) { + $header->headerExtension->padding->setSize + ($headerLengthOld - $headerLengthNew); + $buffer = new Zend_Io_StringWriter(); + $header->write($buffer); + $headerData = $buffer->toString(); + $headerLengthNew = $header->getSize(); + } + + // Must expand + else { + $header->headerExtension->padding->setSize(4096); + $buffer = new Zend_Io_StringWriter(); + $header->write($buffer); + $headerData = $buffer->toString(); + $headerLengthNew = $header->getSize(); + + fseek($fd, 0, SEEK_END); + $oldFileSize = ftell($fd); + ftruncate + ($fd, $newFileSize = $headerLengthNew - $headerLengthOld + + $oldFileSize); + for ($i = 1, $cur = $oldFileSize; $cur > 0; $cur -= 1024, $i++) { + fseek($fd, -(($i * 1024) + + ($newFileSize - $oldFileSize)), SEEK_END); + $buffer = fread($fd, 1024); + fseek($fd, -($i * 1024), SEEK_END); + fwrite($fd, $buffer, 1024); + } + } + + fseek($fd, 0); + fwrite($fd, $headerData, $headerLengthNew); + fclose($fd); + } +} diff --git a/src/Zend/Media/Asf/Exception.php b/src/Zend/Media/Asf/Exception.php new file mode 100644 index 0000000..f17474e --- /dev/null +++ b/src/Zend/Media/Asf/Exception.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Asf_Exception extends Zend_Media_Exception +{} diff --git a/src/Zend/Media/Asf/Object.php b/src/Zend/Media/Asf/Object.php new file mode 100644 index 0000000..830dfd5 --- /dev/null +++ b/src/Zend/Media/Asf/Object.php @@ -0,0 +1,322 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Asf_Object +{ + /* ASF Objects */ + const HEADER = '75b22630-668e-11cf-a6d9-00aa0062ce6c'; + const DATA = '75b22636-668e-11cf-a6d9-00aa0062ce6c'; + const SIMPLE_INDEX = '33000890-e5b1-11cf-89f4-00a0c90349cb'; + const INDEX = 'd6e229d3-35da-11d1-9034-00a0c90349be'; + const MEDIA_OBJECT_INDEX = 'feb103f8-12ad-4c64-840f-2a1d2f7ad48c'; + const TIMECODE_INDEX = '3cb73fd0-0c4a-4803-953d-edf7b6228f0c'; + + /* Header Objects */ + const FILE_PROPERTIES = '8cabdca1-a947-11cf-8ee4-00c00c205365'; + const STREAM_PROPERTIES = 'b7dc0791-a9b7-11cf-8ee6-00c00c205365'; + const HEADER_EXTENSION = '5fbf03b5-a92e-11cf-8ee3-00c00c205365'; + const CODEC_LIST = '86d15240-311d-11d0-a3a4-00a0c90348f6'; + const SCRIPT_COMMAND = '1efb1a30-0b62-11d0-a39b-00a0c90348f6'; + const MARKER = 'f487cd01-a951-11cf-8ee6-00c00c205365'; + const BITRATE_MUTUAL_EXCLUSION = 'd6e229dc-35da-11d1-9034-00a0c90349be'; + const ERROR_CORRECTION = '75b22635-668e-11cf-a6d9-00aa0062ce6c'; + const CONTENT_DESCRIPTION = '75b22633-668e-11cf-a6d9-00aa0062ce6c'; + const EXTENDED_CONTENT_DESCRIPTION = 'd2d0a440-e307-11d2-97f0-00a0c95ea850'; + const CONTENT_BRANDING = '2211b3fa-bd23-11d2-b4b7-00a0c955fc6e'; + const STREAM_BITRATE_PROPERTIES = '7bf875ce-468d-11d1-8d82-006097c9a2b2'; + const CONTENT_ENCRYPTION = '2211b3fb-bd23-11d2-b4b7-00a0c955fc6e'; + const EXTENDED_CONTENT_ENCRYPTION = '298ae614-2622-4c17-b935-dae07ee9289c'; + const DIGITAL_SIGNATURE = '2211b3fc-bd23-11d2-b4b7-00a0c955fc6e'; + const PADDING = '1806d474-cadf-4509-a4ba-9aabcb96aae8'; + + /* Header Extension Objects */ + const EXTENDED_STREAM_PROPERTIES = '14e6a5cb-c672-4332-8399-a96952065b5a'; + const ADVANCED_MUTUAL_EXCLUSION = 'a08649cf-4775-4670-8a16-6e35357566cd'; + const GROUP_MUTUAL_EXCLUSION = 'd1465a40-5a79-4338-b71b-e36b8fd6c249'; + const STREAM_PRIORITIZATION = 'd4fed15b-88d3-454f-81f0-ed5c45999e24'; + const BANDWIDTH_SHARING = 'a69609e6-517b-11d2-b6af-00c04fd908e9'; + const LANGUAGE_LIST = '7c4346a9-efe0-4bfc-b229-393ede415c85'; + const METADATA = 'c5f8cbea-5baf-4877-8467-aa8c44fa4cca'; + const METADATA_LIBRARY = '44231c94-9498-49d1-a141-1d134e457054'; + const INDEX_PARAMETERS = 'd6e229df-35da-11d1-9034-00a0c90349be'; + const MEDIA_OBJECT_INDEX_PARAMETERS = + '6b203bad-3f11-48e4-aca8-d7613de2cfa7'; + const TIMECODE_INDEX_PARAMETERS = 'f55e496d-9797-4b5d-8c8b-604dfe9bfb24'; + const COMPATIBILITY = '75b22630-668e-11cf-a6d9-00aa0062ce6c'; + const ADVANCED_CONTENT_ENCRYPTION = '43058533-6981-49e6-9b74-ad12cb86d58c'; + + /** + * The reader object. + * + * @var Zend_Io_Reader + */ + protected $_reader; + + /** + * The options array. + * + * @var Array + */ + protected $_options; + + /** @var integer */ + private $_offset = false; + + /** @var string */ + private $_identifier = false; + + /** @var integer */ + private $_size = false; + + /** @var Zend_Media_Asf_Object */ + private $_parent = null; + + /** + * Constructs the class with given parameters and options. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + $this->_reader = $reader; + $this->_options = &$options; + + if (($this->_reader = $reader) === null) { + if (defined($constant = 'self::' . strtoupper + (preg_replace + ('/(?<=[a-z])[A-Z]/', '_$0', substr(get_class($this), 22))))) { + $this->_identifier = constant($constant); + } else { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception + ('Object identifier could not be determined'); + } + } else { + $this->_offset = $this->_reader->getOffset(); + $this->_identifier = $this->_reader->readGuid(); + $this->_size = $this->_reader->readInt64LE(); + } + } + + /** + * Returns the options array. + * + * @return Array + */ + public final 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 final function getOption($option, $defaultValue = null) + { + if (isset($this->_options[$option])) { + return $this->_options[$option]; + } + return $defaultValue; + } + + /** + * Sets the options array. See {@link Zend_Media_Asf} class for available + * options. + * + * @param Array $options The options array. + */ + public final 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 final function setOption($option, $value) + { + $this->_options[$option] = $value; + } + + /** + * Clears the given option value. + * + * @param string $option The name of the option. + */ + public final function clearOption($option) + { + unset($this->_options[$option]); + } + + /** + * Returns the file offset to object start, or false if the + * object was created on heap. + * + * @return integer + */ + public final function getOffset() + { + return $this->_offset; + } + + /** + * Sets the file offset where the object starts. + * + * @param integer $offset The file offset to object start. + */ + public final function setOffset($offset) + { + $this->_offset = $offset; + } + + /** + * Returns the GUID of the ASF object. + * + * @return string + */ + public final function getIdentifier() + { + return $this->_identifier; + } + + /** + * Set the GUID of the ASF object. + * + * @param string $identifier The GUID + */ + public final function setIdentifier($identifier) + { + $this->_identifier = $identifier; + } + + /** + * Returns the object size in bytes, including the header. + * + * @return integer + */ + public final function getSize() + { + return $this->_size; + } + + /** + * Sets the object size. The size must include the 24 byte header. + * + * @param integer $size The object size. + */ + public final 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 parent object containing this object. + * + * @return Zend_Media_Asf_Object + */ + public final function getParent() + { + return $this->_parent; + } + + /** + * Sets the parent containing object. + * + * @param Zend_Media_Asf_Object $parent The parent object. + */ + public final function setParent(&$parent) + { + $this->_parent = $parent; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + abstract public function write($writer); + + /** + * Magic function so that $obj->value will work. The method will attempt to + * invoke a getter method. If there are no getter methods with given name, + * an exception is thrown. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func(array($this, 'get' . ucfirst($name))); + } + if (method_exists($this, 'is' . ucfirst($name))) { + return call_user_func(array($this, 'is' . ucfirst($name))); + } + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Unknown 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 { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Media/Asf/Object/AdvancedContentEncryption.php b/src/Zend/Media/Asf/Object/AdvancedContentEncryption.php new file mode 100644 index 0000000..d2c3bf9 --- /dev/null +++ b/src/Zend/Media/Asf/Object/AdvancedContentEncryption.php @@ -0,0 +1,168 @@ +Advanced Content Encryption Object lets authors protect content by + * using Next Generation Windows Media Digital Rights Management for Network + * Devices. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_AdvancedContentEncryption + extends Zend_Media_Asf_Object +{ + const WINDOWS_MEDIA_DRM_NETWORK_DEVICES = + '7a079bb6-daa4-4e12-a5ca-91d3 8dc11a8d'; + + /** @var Array */ + private $_contentEncryptionRecords = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + $contentEncryptionRecordsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $contentEncryptionRecordsCount; $i++) { + $entry = array('systemId' => $this->_reader->readGuid(), + 'systemVersion' => $this->_reader->readUInt32LE(), + 'streamNumbers' => array()); + $encryptedObjectRecordCount = $this->_reader->readUInt16LE(); + for ($j = 0; $j < $encryptedObjectRecordCount; $j++) { + $this->_reader->skip(4); + $entry['streamNumbers'][] = $this->_reader->readUInt16LE(); + } + $dataCount = $this->_reader->readUInt32LE(); + $entry['data'] = $this->_reader->read($dataCount); + $this->_contentEncryptionRecords[] = $entry; + } + } + + /** + * Returns an array of content encryption records. Each record consists of + * the following keys. + * + * o systemId -- Specifies the unique identifier for the content + * encryption system. + * + * o systemVersion -- Specifies the version of the content encryption + * system. + * + * o streamNumbers -- An array of stream numbers a particular Content + * Encryption Record is associated with. A value of 0 in this field + * indicates that it applies to the whole file; otherwise, the entry + * applies only to the indicated stream number. + * + * o data -- The content protection data for this Content Encryption + * Record. + * + * @return Array + */ + public function getContentEncryptionRecords() + { + return $this->_contentEncryptionRecords; + } + + /** + * Sets the array of content encryption records. Each record must consist of + * the following keys. + * + * o systemId -- Specifies the unique identifier for the content + * encryption system. + * + * o systemVersion -- Specifies the version of the content encryption + * system. + * + * o streamNumbers -- An array of stream numbers a particular Content + * Encryption Record is associated with. A value of 0 in this field + * indicates that it applies to the whole file; otherwise, the entry + * applies only to the indicated stream number. + * + * o data -- The content protection data for this Content Encryption + * Record. + * + * @param Array $contentEncryptionRecords The array of content encryption + * records. + */ + public function setContentEncryptionRecords($contentEncryptionRecords) + { + $this->_contentEncryptionRecords = $contentEncryptionRecords; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $contentEncryptionRecordsCount = + count($this->_contentEncryptionRecords); + $contentEncryptionRecordsWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $contentEncryptionRecordsCount; $i++) { + $contentEncryptionRecordsWriter + ->writeGuid($this->_contentEncryptionRecords['systemId']) + ->writeUInt32LE + ($this->_contentEncryptionRecords['systemVersion']) + ->writeUInt16LE + ($encryptedObjectRecordCount = + $this->_contentEncryptionRecords['streamNumbers']); + for ($j = 0; $j < $encryptedObjectRecordCount; $j++) { + $contentEncryptionRecordsWriter + ->writeUInt16LE(1) + ->writeUInt16LE(2) + ->writeUInt16LE + ($this->_contentEncryptionRecords['streamNumbers'][$j]); + } + $contentEncryptionRecordsWriter + ->writeUInt32LE + (strlen($this->_contentEncryptionRecords['data'])) + ->write($this->_contentEncryptionRecords['data']); + } + + $this->setSize + (24 /* for header */ + 2 + + $contentEncryptionRecordsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($contentEncryptionRecordsCount) + ->write($contentEncryptionRecordsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/AdvancedMutualExclusion.php b/src/Zend/Media/Asf/Object/AdvancedMutualExclusion.php new file mode 100644 index 0000000..e74166a --- /dev/null +++ b/src/Zend/Media/Asf/Object/AdvancedMutualExclusion.php @@ -0,0 +1,140 @@ +Advanced Mutual Exclusion Object identifies streams that have a + * mutual exclusion relationship to each other (in other words, only one of the + * streams within such a relationship can be streamed—the rest are ignored). + * There should be one instance of this object for each set of objects that + * contain a mutual exclusion relationship. The exclusion type is used so that + * implementations can allow user selection of common choices, such as language. + * This object must be used if any of the streams in the mutual exclusion + * relationship are hidden. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_AdvancedMutualExclusion + extends Zend_Media_Asf_Object +{ + const MUTEX_LANGUAGE = 'd6e22a00-35da-11d1-9034-00a0c90349be'; + const MUTEX_BITRATE = 'd6e22a01-35da-11d1-9034-00a0c90349be'; + const MUTEX_UNKNOWN = 'd6e22a02-35da-11d1-9034-00a0c90349be'; + + /** @var string */ + private $_exclusionType; + + /** @var Array */ + private $_streamNumbers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_exclusionType = $this->_reader->readGuid(); + $streamNumbersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $this->_streamNumbers[] = $this->_reader->readUInt16LE(); + } + } + + /** + * Returns the nature of the mutual exclusion relationship. + * + * @return string + */ + public function getExclusionType() + { + return $this->_exclusionType; + } + + /** + * Returns the nature of the mutual exclusion relationship. + * + * @return string + */ + public function setExclusionType($exclusionType) + { + $this->_exclusionType = $exclusionType; + } + + /** + * Returns an array of stream numbers. + * + * @return Array + */ + public function getStreamNumbers() + { + return $this->_streamNumbers; + } + + /** + * Sets the array of stream numbers. + * + * @return Array + */ + public function setStreamNumbers($streamNumbers) + { + $this->_streamNumbers = $streamNumbers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $streamNumbersCount = count($this->_streamNumbers); + + $this->setSize(24 /* for header */ + 18 + $streamNumbersCount * 2); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_exclusionType) + ->writeUInt16LE($streamNumbersCount); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $writer->writeUInt16LE($this->_streamNumbers[$i]); + } + } +} diff --git a/src/Zend/Media/Asf/Object/BandwidthSharing.php b/src/Zend/Media/Asf/Object/BandwidthSharing.php new file mode 100644 index 0000000..e3a8e1a --- /dev/null +++ b/src/Zend/Media/Asf/Object/BandwidthSharing.php @@ -0,0 +1,217 @@ +Bandwidth Sharing Object indicates streams that share bandwidth in + * such a way that the maximum bandwidth of the set of streams is less than the + * sum of the maximum bandwidths of the individual streams. There should be one + * instance of this object for each set of objects that share bandwidth. Whether + * or not this object can be used meaningfully is content-dependent. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_BandwidthSharing extends Zend_Media_Asf_Object +{ + const SHARING_EXCLUSIVE = 'af6060aa-5197-11d2-b6af-00c04fd908e9'; + const SHARING_PARTIAL = 'af6060ab-5197-11d2-b6af-00c04fd908e9'; + + /** @var string */ + private $_sharingType; + + /** @var integer */ + private $_dataBitrate; + + /** @var integer */ + private $_bufferSize; + + /** @var Array */ + private $_streamNumbers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader = null, $options); + + if ($reader === null) { + return; + } + + $this->_sharingType = $this->_reader->readGuid(); + $this->_dataBitrate = $this->_reader->readUInt32LE(); + $this->_bufferSize = $this->_reader->readUInt32LE(); + $streamNumbersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $this->_streamNumbers[] = $this->_reader->readUInt16LE(); + } + } + + /** + * Returns the type of sharing relationship for this object. Two types are + * predefined: SHARING_PARTIAL, in which any number of the streams in the + * relationship may be streaming data at any given time; and + * SHARING_EXCLUSIVE, in which only one of the streams in the relationship + * may be streaming data at any given time. + * + * @return string + */ + public function getSharingType() + { + return $this->_sharingType; + } + + /** + * Sets the type of sharing relationship for this object. Two types are + * predefined: SHARING_PARTIAL, in which any number of the streams in the + * relationship may be streaming data at any given time; and + * SHARING_EXCLUSIVE, in which only one of the streams in the relationship + * may be streaming data at any given time. + * + * @return string + */ + public function setSharingType($sharingType) + { + $this->_sharingType = $sharingType; + } + + /** + * Returns the leak rate R, in bits per second, of a leaky bucket that + * contains the data portion of all of the streams, excluding all ASF Data + * Packet overhead, without overflowing. The size of the leaky bucket is + * specified by the value of the Buffer Size field. This value can be less + * than the sum of all of the data bit rates in the + * {@link Zend_Media_Asf_Object_ExtendedStreamProperties Extended Stream + * Properties} Objects for the streams contained in this bandwidth-sharing + * relationship. + * + * @return integer + */ + public function getDataBitrate() + { + return $this->_dataBitrate; + } + + /** + * Sets the leak rate R, in bits per second, of a leaky bucket that contains + * the data portion of all of the streams, excluding all ASF Data Packet + * overhead, without overflowing. The size of the leaky bucket is specified + * by the value of the Buffer Size field. This value can be less than the + * sum of all of the data bit rates in the + * {@link Zend_Media_Asf_Object_ExtendedStreamProperties Extended Stream + * Properties} Objects for the streams contained in this bandwidth-sharing + * relationship. + * + * @param integer $dataBitrate The data bitrate. + */ + public function setDataBitrate($dataBitrate) + { + $this->_dataBitrate = $dataBitrate; + } + + /** + * Specifies the size B, in bits, of the leaky bucket used in the Data + * Bitrate definition. This value can be less than the sum of all of the + * buffer sizes in the + * {@link Zend_Media_Asf_Object_ExtendedStreamProperties Extended Stream + * Properties} Objects for the streams contained in this bandwidth-sharing + * relationship. + * + * @return integer + */ + public function getBufferSize() + { + return $this->_bufferSize; + } + + /** + * Sets the size B, in bits, of the leaky bucket used in the Data Bitrate + * definition. This value can be less than the sum of all of the buffer + * sizes in the + * {@link Zend_Media_Asf_Object_ExtendedStreamProperties Extended Stream + * Properties} Objects for the streams contained in this bandwidth-sharing + * relationship. + * + * @param integer $bufferSize The buffer size. + */ + public function setBufferSize($bufferSize) + { + $this->_bufferSize = $bufferSize; + } + + /** + * Returns an array of stream numbers. + * + * @return Array + */ + public function getStreamNumbers() + { + return $this->_streamNumbers; + } + + /** + * Sets the array of stream numbers. + * + * @param Array $streamNumbers The array of stream numbers. + */ + public function setStreamNumbers($streamNumbers) + { + $this->_streamNumbers = $streamNumbers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $streamNumbersCount = count($this->_streamNumber); + + $this->setSize(24 /* for header */ + 28 + $streamNumbersCount * 2); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_sharingType) + ->writeUInt32LE($this->_dataBitrate) + ->writeUInt32LE($this->_bufferSize) + ->writeUInt16LE($streamNumbersCount); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $writer->writeUInt16LE($this->_streamNumbers[$i]); + } + } +} diff --git a/src/Zend/Media/Asf/Object/BitrateMutualExclusion.php b/src/Zend/Media/Asf/Object/BitrateMutualExclusion.php new file mode 100644 index 0000000..eb5e4d7 --- /dev/null +++ b/src/Zend/Media/Asf/Object/BitrateMutualExclusion.php @@ -0,0 +1,141 @@ +Bitrate Mutual Exclusion Object identifies video streams that have + * a mutual exclusion relationship to each other (in other words, only one of + * the streams within such a relationship can be streamed at any given time and + * the rest are ignored). One instance of this object must be present for each + * set of objects that contains a mutual exclusion relationship. All video + * streams in this relationship must have the same frame size. The exclusion + * type is used so that implementations can allow user selection of common + * choices, such as bit rate. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_BitrateMutualExclusion + extends Zend_Media_Asf_Object +{ + const MUTEX_LANGUAGE = 'd6e22a00-35da-11d1-9034-00a0c90349be'; + const MUTEX_BITRATE = 'd6e22a01-35da-11d1-9034-00a0c90349be'; + const MUTEX_UNKNOWN = 'd6e22a02-35da-11d1-9034-00a0c90349be'; + + /** @var string */ + private $_exclusionType; + + /** @var Array */ + private $_streamNumbers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_exclusionType = $this->_reader->readGuid(); + $streamNumbersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $this->_streamNumbers[] = $this->_reader->readUInt16LE(); + } + } + + /** + * Returns the nature of the mutual exclusion relationship. + * + * @return string + */ + public function getExclusionType() + { + return $this->_exclusionType; + } + + /** + * Sets the nature of the mutual exclusion relationship. + * + * @param string $exclusionType The nature of the mutual exclusion + * relationship. + */ + public function setExclusionType($exclusionType) + { + $this->_exclusionType = $exclusionType; + } + + /** + * Returns an array of stream numbers. + * + * @return Array + */ + public function getStreamNumbers() + { + return $this->_streamNumbers; + } + + /** + * Sets the array of stream numbers. + * + * @param Array $streamNumbers The array of stream numbers. + */ + public function setStreamNumbers($streamNumbers) + { + $this->_streamNumbers = $streamNumbers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $streamNumbersCount = count($this->_streamNumbers); + + $this->setSize(24 /* for header */ + 18 + $streamNumbersCount * 2); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_exclusionType) + ->writeUInt16LE($streamNumbersCount); + for ($i = 0; $i < $streamNumbersCount; $i++) { + $writer->writeUInt16LE($this->_streamNumbers[$i]); + } + } +} diff --git a/src/Zend/Media/Asf/Object/CodecList.php b/src/Zend/Media/Asf/Object/CodecList.php new file mode 100644 index 0000000..798b406 --- /dev/null +++ b/src/Zend/Media/Asf/Object/CodecList.php @@ -0,0 +1,165 @@ +Codec List Object provides user-friendly information about the + * codecs and formats used to encode the content found in the ASF file. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_CodecList extends Zend_Media_Asf_Object +{ + const VIDEO_CODEC = 0x1; + const AUDIO_CODEC = 0x2; + const UNKNOWN_CODEC = 0xffff; + + /** @var string */ + private $_reserved; + + /** @var Array */ + private $_entries = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_reserved = $this->_reader->readGuid(); + $codecEntriesCount = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $codecEntriesCount; $i++) { + $entry = array('type' => $this->_reader->readUInt16LE()); + $codecNameLength = $this->_reader->readUInt16LE() * 2; + $entry['codecName'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($codecNameLength)); + $codecDescriptionLength = $this->_reader->readUInt16LE() * 2; + $entry['codecDescription'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($codecDescriptionLength)); + $codecInformationLength = $this->_reader->readUInt16LE(); + $entry['codecInformation'] = + $this->_reader->read($codecInformationLength); + $this->_entries[] = $entry; + } + } + + /** + * Returns the array of codec entries. Each record consists of the following + * keys. + * + * o type -- Specifies the type of the codec used. Use one of the + * following values: VIDEO_CODEC, AUDIO_CODEC, or UNKNOWN_CODEC. + * + * o codecName -- Specifies the name of the codec used to create the + * content. + * + * o codecDescription -- Specifies the description of the format used to + * create the content. + * + * o codecInformation -- Specifies an opaque array of information bytes + * about the codec used to create the content. The meaning of these + * bytes is determined by the codec. + * + * @return Array + */ + public function getEntries() + { + return $this->_entries; + } + + /** + * Sets the array of codec entries. Each record must consist of the + * following keys. + * + * o codecName -- Specifies the name of the codec used to create the + * content. + * + * o codecDescription -- Specifies the description of the format used to + * create the content. + * + * o codecInformation -- Specifies an opaque array of information bytes + * about the codec used to create the content. The meaning of these + * bytes is determined by the codec. + * + * @param Array $entries The array of codec entries. + */ + public function setEntries($entries) + { + $this->_entries = $entries; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $codecEntriesCount = count($this->_entries); + $codecEntriesWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $codecEntriesCount; $i++) { + $codecEntriesWriter + ->writeUInt16LE($this->_entries[$i]['type']) + ->writeUInt16LE(strlen($codecName = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_entries[$i]['codecName']) . "\0\0") / 2) + ->writeString16($codecName) + ->writeUInt16LE(strlen($codecDescription = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_entries[$i]['codecDescription']) . "\0\0") / 2) + ->writeString16($codecDescription) + ->writeUInt16LE(strlen($this->_entries[$i]['codecInformation'])) + ->write($this->_entries[$i]['codecInformation']); + } + + $this->setSize + (24 /* for header */ + 20 + $codecEntriesWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_reserved) + ->writeUInt32LE($codecEntriesCount) + ->write($codecEntriesWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Compatibility.php b/src/Zend/Media/Asf/Object/Compatibility.php new file mode 100644 index 0000000..913508a --- /dev/null +++ b/src/Zend/Media/Asf/Object/Compatibility.php @@ -0,0 +1,120 @@ +Compatibility Object is reserved for future use. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Compatibility extends Zend_Media_Asf_Object +{ + /** @var integer */ + private $_profile; + + /** @var integer */ + private $_mode; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_profile = $this->_reader->readUInt8(); + $this->_mode = $this->_reader->readUInt8(); + } + + /** + * Returns the profile field. This field is reserved and is set to 2. + * + * @return integer + */ + public function getProfile() + { + return $this->_profile; + } + + /** + * Returns the profile field. This field is reserved and is set to 2. + * + * @param integer $profile The profile. + */ + public function setProfile($profile) + { + $this->_profile = $profile; + } + + /** + * Returns the mode field. This field is reserved and is set to 1. + * + * @return integer + */ + public function getMode() + { + return $this->_mode; + } + + /** + * Sets the mode field. This field is reserved and is set to 1. + * + * @param integer $mode The mode. + */ + public function setMode($mode) + { + $this->_mode = $mode; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $this->setSize(24 /* for header */ + 2); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt8($this->_profile) + ->writeUInt8($this->_mode); + } +} diff --git a/src/Zend/Media/Asf/Object/Container.php b/src/Zend/Media/Asf/Object/Container.php new file mode 100644 index 0000000..19b9d50 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Container.php @@ -0,0 +1,361 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Asf_Object_Container extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_objects = array(); + + /** + * Reads and constructs the objects found within this object. + */ + protected final function constructObjects($defaultclassnames = array()) + { + while (true) { + $offset = $this->_reader->getOffset(); + if ($offset >= $this->getOffset() + $this->getSize()) { + break; + } + $guid = $this->_reader->readGuid(); + $size = $this->_reader->readInt64LE(); + + $this->_reader->setOffset($offset); + if (isset($defaultclassnames[$guid])) { + if (@fopen($filename = 'Zend/Media/Asf/Object/' . + $defaultclassnames[$guid] . '.php', + 'r', true) !== false) { + require_once($filename); + } + if (class_exists + ($classname = 'Zend_Media_Asf_Object_' . + $defaultclassnames[$guid])) { + $object = new $classname($this->_reader, $this->_options); + } else { + require_once 'Zend/Media/Asf/Object/Unknown.php'; + $object = new Zend_Media_Asf_Object_Unknown + ($this->_reader, $this->_options); + } + } else { + require_once 'Zend/Media/Asf/Object/Unknown.php'; + $object = new Zend_Media_Asf_Object_Unknown + ($this->_reader, $this->_options); + } + $object->setParent($this); + if (!$this->hasObject($object->getIdentifier())) { + $this->_objects[$object->getIdentifier()] = array(); + } + $this->_objects[$object->getIdentifier()][] = $object; + $this->_reader->setOffset($offset + $size); + } + } + + /** + * Checks whether the object with given identifier is present in the file. + * The identifier can either be the object GUID, or name of the constant + * containing the GUID, or the name of the object class. + * + * Returns true if one or more objects are present, + * false otherwise. + * + * @param string $identifier The object GUID, name of the GUID constant, or + * object class name. + * @return boolean + */ + public final function hasObject($identifier) + { + if (defined($constname = get_class($this) . '::' . strtoupper + (preg_replace('/[A-Z]/', '_$0', $identifier)))) { + $objects = $this->getObjectsByIdentifier(constant($constname)); + return isset($objects[0]); + } else { + return isset($this->_objects[$identifier]); + } + } + + /** + * Returns all the objects the file contains as an associate array. The + * object identifiers work as keys having an array of ASF objects as + * associated value. + * + * @return Array + */ + public final function getObjects() + { + return $this->_objects; + } + + /** + * Returns an array of objects matching the given object GUID or an empty + * array if no object matched the identifier. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches + * any single character. + * + * @param string $identifier The object GUID. + * @return Array + */ + public final function getObjectsByIdentifier($identifier) + { + $matches = array(); + $searchPattern = '/^' . + str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; + foreach ($this->_objects as $identifier => $objects) { + if (preg_match($searchPattern, $identifier)) { + foreach ($objects as $object) { + $matches[] = $object; + } + } + } + return $matches; + } + + /** + * Returns an array of objects matching the given object constant name or an + * empty array if no object matched the name. + * + * The object constant name can be given in three forms; either using the + * full name of the constant, the name of the class or the shorthand style + * of the class name having its first letter in lower case. + * + * One may use the shorthand $obj->name to access the first box with the + * name given directly. Shorthands will not work with user defined uuid + * types. + * + * The name may not contain wildcard characters. + * + * @param string $name The object constant name or class name. + * @return Array + */ + public final function getObjectsByName($name) + { + if (defined($constname = get_class($this) . '::' . $name) || + defined($constname = get_class($this) . '::' . strtoupper + (preg_replace + ('/^_/', '', preg_replace('/[A-Z]/', '_$0', $name))))) { + return $this->getObjectsByIdentifier(constant($constname)); + } + return array(); + } + + /** + * Removes any objects matching the given object GUID. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches + * any single character. + * + * One may also use the shorthand unset($obj->name) to achieve the same + * result. Wildcards cannot be used with the shorthand method. + * + * @param string $identifier The object GUID. + */ + public final function removeObjectsByIdentifier($identifier) + { + $searchPattern = '/^' . + str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; + foreach ($this->_objects as $identifier => $objects) { + if (preg_match($searchPattern, $identifier)) { + unset($this->_objects[$identifier]); + } + } + } + + /** + * Removes any objects matching the given object name. + * + * The name can be given in three forms; either using the full name of the + * constant, the name of the class or the shorthand style of the class name + * having its first letter in lower case. + * + * One may also use the shorthand unset($obj->name) to achieve the same + * result. + * + * The name may not contain wildcard characters. + * + * @param string $name The object constant name or class name. + */ + public final function removeObjectsByName($name) + { + if (defined($constname = get_class($this) . '::' . strtoupper + (preg_replace('/[A-Z]/', '_$0', $name)))) { + unset($this->_objects[constant($constname)]); + } + } + + /** + * Adds a new object into the current object and returns it. + * + * @param Zend_Media_Asf_Object $object The object to add + * @return Zend_Media_Asf_Object + */ + public final function addObject($object) + { + $object->setParent($this); + $object->setOptions($this->_options); + if (!$this->hasObject($object->getIdentifier())) { + $this->_objects[$object->getIdentifier()] = array(); + } + return $this->_objects[$object->getIdentifier()][] = $object; + } + + /** + * Removes the object. + * + * @param Zend_Media_Asf_Object $object The object to remove + */ + public final function removeObject($object) + { + if ($this->hasObject($object->getIdentifier())) { + foreach ($this->_objects + [$object->getIdentifier()] as $key => $value) { + if ($object === $value) { + unset($this->_objects[$object->getIdentifier()][$key]); + } + } + } + } + + /** + * Returns the number of objects this container has. + * + * @return integer + */ + public final function getObjectCount() + { + return count($this->_objects); + } + + /** + * Override magic function so that $obj->value will work as expected. + * + * The method first attempts to call the appropriate getter method. If no + * field with given name is found, the method attempts to return the right + * object instead. In other words, calling $obj->value will attempt to + * return the first object returned by + * $this->getObjectsByIdentifier(self::value). If no object is found by the + * given value, a respective class name is tried to instantiate and add to + * the container. + * + * @param string $name The field or object name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func(array($this, 'get' . ucfirst($name))); + } + if (method_exists($this, 'is' . ucfirst($name))) { + return call_user_func(array($this, 'is' . ucfirst($name))); + } + if (defined($constname = get_class($this) . '::' . strtoupper + (preg_replace('/[A-Z]/', '_$0', $name)))) { + $objects = $this->getObjectsByIdentifier(constant($constname)); + if (isset($objects[0])) { + return $objects[0]; + } else { + if (@fopen($filename = 'Zend/Media/Asf/Object/' . + ucfirst($name) . '.php', 'r', true) !== false) { + require_once($filename); + } + if (class_exists + ($classname = 'Zend_Media_Asf_Object_' . ucfirst($name))) { + $obj = new $classname(); + $obj->setIdentifier(constant($constname)); + return $this->addObject($obj); + } + } + } + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Unknown field/object: ' . $name); + } + + /** + * Override magic function so that $obj->value will work as expected. + * + * The method first attempts to call the appropriate setter method. If no + * field with given name is found, the method attempts to set the right + * object instead. In other words, assigning to $obj->value will attempt to + * set the object with given value's identifier. + * + * Please note that using this method will override any prior objects having + * the same object identifier. + * + * @param string $name The field or object name. + * @param string $value The field value or object. + * @return mixed + */ + public function __set($name, $value) + { + if (method_exists($this, 'set' . ucfirst($name))) { + call_user_func(array($this, 'set' . ucfirst($name)), $value); + } + if (defined($constname = get_class($this) . '::' . strtoupper + (preg_replace('/[A-Z]/', '_$0', $name)))) { + $value->setOptions($this->_options); + $this->_objects[constant($constname)] = array($value); + } else { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception + ('Unknown field/object: ' . $name); + } + } + + /** + * Magic function so that isset($obj->value) will work. This method checks + * whether the object by given identifier or name is contained by this + * container. + * + * @param string $name The object identifier or logical name. + * @return boolean + */ + public function __isset($name) + { + return $this->hasObject($name); + } + + /** + * Magic function so that unset($obj->value) will work. This method removes + * all the objects with the given identifier or name. + * + * @param string $name The object identifier or logical name. + */ + public function __unset($name) + { + $this->removeObjectsByName($name); + } +} diff --git a/src/Zend/Media/Asf/Object/ContentBranding.php b/src/Zend/Media/Asf/Object/ContentBranding.php new file mode 100644 index 0000000..e0e9a12 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ContentBranding.php @@ -0,0 +1,203 @@ +Content Branding Object stores branding data for an ASF file, + * including information about a banner image and copyright associated with the + * file. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ContentBranding extends Zend_Media_Asf_Object +{ + /** Indicates that there is no banner */ + const TYPE_NONE = 0; + + /** Indicates that the data represents a bitmap */ + const TYPE_BMP = 1; + + /** Indicates that the data represents a JPEG */ + const TYPE_JPEG = 2; + + /** Indicates that the data represents a GIF */ + const TYPE_GIF = 3; + + /** @var integer */ + private $_bannerImageType; + + /** @var string */ + private $_bannerImageData; + + /** @var string */ + private $_bannerImageUrl; + + /** @var string */ + private $_copyrightUrl; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_bannerImageType = $this->_reader->readUInt32LE(); + $bannerImageDataSize = $this->_reader->readUInt32LE(); + $this->_bannerImageData = $this->_reader->read($bannerImageDataSize); + $bannerImageUrlLength = $this->_reader->readUInt32LE(); + $this->_bannerImageUrl = $this->_reader->read($bannerImageUrlLength); + $copyrightUrlLength = $this->_reader->readUInt32LE(); + $this->_copyrightUrl = $this->_reader->read($copyrightUrlLength); + } + + /** + * Returns the type of data contained in the Banner Image Data. Valid + * values are 0 to indicate that there is no banner image data; 1 to + * indicate that the data represent a bitmap; 2 to indicate that the data + * represents a JPEG; and 3 to indicate that the data represents a GIF. If + * this value is set to 0, then the Banner Image Data Size field is set + * to 0, and the Banner Image Data field is empty. + * + * @return integer + */ + public function getBannerImageType() + { + return $this->_bannerImageType; + } + + /** + * Sets the type of data contained in the Banner Image Data. Valid + * values are 0 to indicate that there is no banner image data; 1 to + * indicate that the data represent a bitmap; 2 to indicate that the data + * represents a JPEG; and 3 to indicate that the data represents a GIF. If + * this value is set to 0, then the Banner Image Data Size field is set + * to 0, and the Banner Image Data field is empty. + * + * @param integer $bannerImageType The type of data. + */ + public function setBannerImageType($bannerImageType) + { + $this->_bannerImageType = $bannerImageType; + } + + /** + * Returns the entire banner image, including the header for the appropriate + * image format. + * + * @return string + */ + public function getBannerImageData() + { + return $this->_bannerImageData; + } + + /** + * Sets the entire banner image, including the header for the appropriate + * image format. + * + * @param string $bannerImageData The entire banner image. + */ + public function setBannerImageData($bannerImageData) + { + $this->_bannerImageData = $bannerImageData; + } + + /** + * Returns, if present, a link to more information about the banner image. + * + * @return string + */ + public function getBannerImageUrl() + { + return $this->_bannerImageUrl; + } + + /** + * Sets a link to more information about the banner image. + * + * @param string $bannerImageUrl The link. + */ + public function setBannerImageUrl($bannerImageUrl) + { + $this->_bannerImageUrl = $bannerImageUrl; + } + + /** + * Returns, if present, a link to more information about the copyright for + * the content. + * + * @return string + */ + public function getCopyrightUrl() + { + return $this->_copyrightUrl; + } + + /** + * Sets a link to more information about the copyright for the content. + * + * @param string $copyrightUrl The copyright link. + */ + public function setCopyrightUrl($copyrightUrl) + { + $this->_copyrightUrl = $copyrightUrl; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $buffer = new Zend_Io_StringWriter(); + $buffer->writeUInt32LE($this->_bannerImageType) + ->writeUInt32LE(count($this->_bannerImageData)) + ->write($this->_bannerImageData) + ->writeUInt32LE(count($this->_bannerImageUrl)) + ->write($this->_bannerImageUrl) + ->writeUInt32LE(count($this->_copyrightUrl)) + ->write($this->_copyrightUrl); + + $this->setSize(24 /* for header */ + $buffer->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->write($buffer->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/ContentDescription.php b/src/Zend/Media/Asf/Object/ContentDescription.php new file mode 100644 index 0000000..c076ad1 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ContentDescription.php @@ -0,0 +1,240 @@ +Content Description Object lets authors record well-known data + * describing the file and its contents. This object is used to store standard + * bibliographic information such as title, author, copyright, description, and + * rating information. This information is pertinent to the entire file. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ContentDescription + extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_title; + + /** @var string */ + private $_author; + + /** @var string */ + private $_copyright; + + /** @var string */ + private $_description; + + /** @var string */ + private $_rating; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $titleLen = $this->_reader->readUInt16LE(); + $authorLen = $this->_reader->readUInt16LE(); + $copyrightLen = $this->_reader->readUInt16LE(); + $descriptionLen = $this->_reader->readUInt16LE(); + $ratingLen = $this->_reader->readUInt16LE(); + + $this->_title = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($titleLen)); + $this->_author = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($authorLen)); + $this->_copyright = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($copyrightLen)); + $this->_description = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($descriptionLen)); + $this->_rating = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($ratingLen)); + } + + /** + * Returns the title information. + * + * @return string + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Sets the title information. + * + * @param string $title The title information. + */ + public function setTitle($title) + { + $this->_title = $title; + } + + /** + * Returns the author information. + * + * @return string + */ + public function getAuthor() + { + return $this->_author; + } + + /** + * Sets the author information. + * + * @param string $author The author information. + */ + public function setAuthor($author) + { + $this->_author = $author; + } + + /** + * Returns the copyright information. + * + * @return string + */ + public function getCopyright() + { + return $this->_copyright; + } + + /** + * Sets the copyright information. + * + * @param string $copyright The copyright information. + */ + public function setCopyright($copyright) + { + $this->_copyright = $copyright; + } + + /** + * Returns the description information. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description information. + * + * @param string $description The description information. + */ + public function setDescription($description) + { + $this->_description = $description; + } + + /** + * Returns the rating information. + * + * @return string + */ + public function getRating() + { + return $this->_rating; + } + + /** + * Sets the rating information. + * + * @param string $rating The rating information. + */ + public function setRating($rating) + { + $this->_rating = $rating; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $title = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_title ? $this->_title . "\0" : ''); + $author = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_author ? $this->_author . "\0" : ''); + $copyright = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_copyright ? $this->_copyright . "\0" : ''); + $description = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_description ? $this->_description . "\0" : ''); + $rating = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_rating ? $this->_rating . "\0" : ''); + + require_once 'Zend/Io/StringWriter.php'; + $buffer = new Zend_Io_StringWriter(); + $buffer->writeUInt16LE(strlen($title)) + ->writeUInt16LE(strlen($author)) + ->writeUInt16LE(strlen($copyright)) + ->writeUInt16LE(strlen($description)) + ->writeUInt16LE(strlen($rating)) + ->writeString16($title) + ->writeString16($author) + ->writeString16($copyright) + ->writeString16($description) + ->writeString16($rating); + + $this->setSize(24 /* for header */ + $buffer->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->write($buffer->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/ContentEncryption.php b/src/Zend/Media/Asf/Object/ContentEncryption.php new file mode 100644 index 0000000..ec49891 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ContentEncryption.php @@ -0,0 +1,189 @@ +Content Encryption Object lets authors protect content by using + * Microsoft® Digital Rights Manager version 1. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ContentEncryption + extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_secretData; + + /** @var string */ + private $_protectionType; + + /** @var string */ + private $_keyId; + + /** @var string */ + private $_licenseUrl; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $secretDataLength = $this->_reader->readUInt32LE(); + $this->_secretData = $this->_reader->read($secretDataLength); + $protectionTypeLength = $this->_reader->readUInt32LE(); + $this->_protectionType = + $this->_reader->readString8($protectionTypeLength); + $keyIdLength = $this->_reader->readUInt32LE(); + $this->_keyId = $this->_reader->readString8($keyIdLength); + $licenseUrlLength = $this->_reader->readUInt32LE(); + $this->_licenseUrl = $this->_reader->readString8($licenseUrlLength); + } + + /** + * Returns the secret data. + * + * @return string + */ + public function getSecretData() + { + return $this->_secretData; + } + + /** + * Sets the secret data. + * + * @param string $secretData The secret data. + */ + public function setSecretData($secretData) + { + $this->_secretData = $secretData; + } + + /** + * Returns the type of protection mechanism used. The value of this field + * is set to 'DRM'. + * + * @return string + */ + public function getProtectionType() + { + return $this->_protectionType; + } + + /** + * Sets the type of protection mechanism used. The value of this field + * is to be set to 'DRM'. + * + * @param string $protectionType The protection mechanism used. + */ + public function setProtectionType($protectionType) + { + $this->_protectionType = $protectionType; + } + + /** + * Returns the key ID used. + * + * @return string + */ + public function getKeyId() + { + return $this->_keyId; + } + + /** + * Sets the key ID used. + * + * @param string $keyId The key ID used. + */ + public function setKeyId($keyId) + { + $this->_keyId = $keyId; + } + + /** + * Returns the URL from which a license to manipulate the content can be + * acquired. + * + * @return string + */ + public function getLicenseUrl() + { + return $this->_licenseUrl; + } + + /** + * Returns the URL from which a license to manipulate the content can be + * acquired. + * + * @param string $licenseUrl The URL from which a license can be acquired. + */ + public function setLicenseUrl($licenseUrl) + { + $this->_licenseUrl = $licenseUrl; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $buffer = new Zend_Io_StringWriter(); + $buffer->writeUInt32LE(strlen($this->_secretData)) + ->write($this->_secretData) + ->writeUInt32LE($len = strlen($this->_protectionType) + 1) + ->writeString8($this->_protectionType, $len) + ->writeUInt32LE($len = strlen($this->_keyId) + 1) + ->writeString8($this->_keyId, $len) + ->writeUInt32LE($len = strlen($this->_licenseUrl) + 1) + ->writeString8($this->_licenseUrl, $len); + + $this->setSize(24 /* for header */ + $buffer->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->write($buffer->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Data.php b/src/Zend/Media/Asf/Object/Data.php new file mode 100644 index 0000000..c08f772 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Data.php @@ -0,0 +1,118 @@ +Data Object contains all of the Data Packets for a file. + * These Data Packets are organized in terms of increasing send times. A Data + * Packet can contain interleaved data from several digital media streams. + * This data can consist of entire objects from one or more streams. + * Alternatively, it can consist of partial objects (fragmentation). + * + * Capabilities provided within the interleave packet definition include: + * o Single or multiple payload types per Data Packet + * o Fixed-size Data Packets + * o Error correction information (optional) + * o Clock information (optional) + * o Redundant sample information, such as presentation time stamp (optional) + * + * Please note that the data packets are not parsed. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Data extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_fileId; + + /** @var integer */ + private $_totalDataPackets; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_fileId = $this->_reader->readGuid(); + $this->_totalDataPackets = $this->_reader->readInt64LE(); + $this->_reader->skip(2); + +// No support for Data Packets as of yet (if ever) +// for ($i = 0; $i < $this->_totalDataPackets; $i++) +// $this->_dataPackets[] = +// new Zend_Media_Asf_Object_Data_Packet($reader); + } + + /** + * Returns the unique identifier for this ASF file. The value of this field + * is changed every time the file is modified in any way. The value of this + * field is identical to the value of the File ID field of the + * Header Object. + * + * @return string + */ + public function getFileId() + { + return $this->_fileId; + } + + /** + * Returns the number of ASF Data Packet entries that exist within the + * Data Object. It must be equal to the Data Packet Count + * field in the File Properties Object. The value of this field is + * invalid if the broadcast flag field of the File Properties Object + * is set to 1. + * + * @return integer + */ + public function getTotalDataPackets() + { + return $this->_totalDataPackets; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/DigitalSignature.php b/src/Zend/Media/Asf/Object/DigitalSignature.php new file mode 100644 index 0000000..ab8a39b --- /dev/null +++ b/src/Zend/Media/Asf/Object/DigitalSignature.php @@ -0,0 +1,125 @@ +Digital Signature Object lets authors sign the portion of their + * header that lies between the end of the File Properties Object and the + * beginning of the Digital Signature Object. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_DigitalSignature extends Zend_Media_Asf_Object +{ + /** @var integer */ + private $_type; + + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_type = $this->_reader->readUInt32LE(); + $dataLength = $this->_reader->readUInt32LE(); + $this->_data = $this->_reader->read($dataLength); + } + + /** + * Returns the type of digital signature used. This field is set to 2. + * + * @return integer + */ + public function getType() + { + return $this->_type; + } + + /** + * Sets the type of digital signature used. This field must be set to 2. + * + + * @param integer $type The type of digital signature used. + */ + public function setType($type) + { + $this->_type = $type; + } + + /** + * Returns the digital signature data. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the digital signature data. + * + * @return string + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $this->setSize(24 /* for header */ + 8 + strlen($this->_data)); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt32LE($this->_type) + ->writeUInt32LE(strlen($this->_data)) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Asf/Object/ErrorCorrection.php b/src/Zend/Media/Asf/Object/ErrorCorrection.php new file mode 100644 index 0000000..e0e2fe0 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ErrorCorrection.php @@ -0,0 +1,136 @@ +Error Correction Object defines the error correction method. This + * enables different error correction schemes to be used during content + * creation. The Error Correction Object contains provisions for opaque + * information needed by the error correction engine for recovery. For example, + * if the error correction scheme were a simple N+1 parity scheme, then the + * value of N would have to be available in this object. + * + + * Note that this does not refer to the same thing as the Error Correction + * Type field in the {@link Zend_Media_Asf_Object_StreamProperties Stream + * Properties Object}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ErrorCorrection extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_type; + + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_type = $this->_reader->readGuid(); + $dataLength = $this->_reader->readUInt32LE(); + $this->_data = $this->_reader->read($dataLength); + } + + /** + * Returns the type of error correction. + * + * @return string + */ + public function getType() + { + return $this->_type; + } + + /** + * Sets the type of error correction. + * + * @param string $type The type of error correction. + */ + public function setType($type) + { + $this->_type = $type; + } + + /** + * Returns the data specific to the error correction scheme. The structure + * for the Error Correction Data field is determined by the value + * stored in the Error Correction Type field. + * + * @return Array + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the data specific to the error correction scheme. The structure for + * the Error Correction Data field is determined by the value stored + * in the Error Correction Type field. + * + * @param Array $data The error correction specific data. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $this->setSize(24 /* for header */ + 20 + strlen($this->_data)); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_type) + ->writeUInt32LE(strlen($this->_data)) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Asf/Object/ExtendedContentDescription.php b/src/Zend/Media/Asf/Object/ExtendedContentDescription.php new file mode 100644 index 0000000..589e467 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ExtendedContentDescription.php @@ -0,0 +1,230 @@ +Extended Content Description Object object implementation. This + * object contains unlimited number of attribute fields giving more information + * about the file. + * + * @todo Implement better handling of various types of attributes + * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ExtendedContentDescription + extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_contentDescriptors = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $contentDescriptorsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $contentDescriptorsCount; $i++) { + $nameLen = $this->_reader->readUInt16LE(); + $name = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($nameLen)); + $valueDataType = $this->_reader->readUInt16LE(); + $valueLen = $this->_reader->readUInt16LE(); + + switch ($valueDataType) { + case 0: // string + $this->_contentDescriptors[$name] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($valueLen)); + break; + case 1: // byte array + $this->_contentDescriptors[$name] = + $this->_reader->read($valueLen); + break; + case 2: // bool + $this->_contentDescriptors[$name] = + $this->_reader->readUInt32LE() == 1 ? true : false; + break; + case 3: // 32-bit integer + $this->_contentDescriptors[$name] = + $this->_reader->readUInt32LE(); + break; + case 4: // 64-bit integer + $this->_contentDescriptors[$name] = + $this->_reader->readInt64LE(); + break; + case 5: // 16-bit integer + $this->_contentDescriptors[$name] = + $this->_reader->readUInt16LE(); + break; + default: + break; + } + } + } + + /** + * Returns the value of the specified descriptor or false if + * there is no such descriptor defined. + * + * @param string $name The name of the descriptor (ie the name of the + * field). + * @return string|false + */ + public function getDescriptor($name) + { + if (isset($this->_contentDescriptors[$name])) { + return $this->_contentDescriptors[$name]; + } + return false; + } + + /** + * Sets the given descriptor a new value. + * + * @param string $name The name of the descriptor. + * @param string $value The value of the field. + * @return string|false + */ + public function setDescriptor($name, $value) + { + $this->_contentDescriptors[$name] = $value; + } + + /** + * Returns an associate array of all the descriptors defined having the + * names of the descriptors as the keys. + * + * @return Array + */ + public function getDescriptors() + { + return $this->_contentDescriptors; + } + + /** + * Sets the content descriptor associate array having the descriptor names + * as array keys and their values as associated value. The descriptor names + * and all string values must be encoded in the default character encoding + * given as an option to {@link Zend_Media_Asf} class. + * + * @param Array $contentDescriptors The content descriptors + */ + public function setDescriptors($contentDescriptors) + { + $this->_contentDescriptors = $contentDescriptors; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $contentDescriptorsCount = count($this->_contentDescriptors); + $contentDescriptorsWriter = new Zend_Io_StringWriter(); + foreach ($this->_contentDescriptors as $name => $value) { + $descriptor = iconv + ($this->getOption('encoding'), 'utf-16le', + $name ? $name . "\0" : ''); + $contentDescriptorsWriter + ->writeUInt16LE(strlen($descriptor)) + ->writeString16($descriptor); + + if (is_string($value)) { + /* There is no way to distinguish byte arrays from unicode + * strings and hence the need for a list of fields of type + * byte array */ + static $byteArray = array ( + "W\0M\0/\0M\0C\0D\0I\0\0\0", + "W\0M\0/\0U\0s\0e\0r\0W\0e\0b\0U\0R\0L\0\0\0", + "W\0M\0/\0L\0y\0r\0i\0c\0s\0_\0S\0y\0n\0c\0h\0r\0o\0n\0i\0s\0e\0d\0\0\0", + "W\0M\0/\0P\0i\0c\0t\0u\0r\0e\0\0\0" + ); // TODO: Add to the list if you encounter one + + if (in_array($descriptor, $byteArray)) { + $contentDescriptorsWriter + ->writeUInt16LE(1) + ->writeUInt16LE(strlen($value)) + ->write($value); + } else { + $value = iconv + ($this->getOption('encoding'), 'utf-16le', $value) . + "\0\0"; + $contentDescriptorsWriter + ->writeUInt16LE(0) + ->writeUInt16LE(strlen($value)) + ->writeString16($value); + } + } else if (is_bool($value)) { + $contentDescriptorsWriter + ->writeUInt16LE(2) + ->writeUInt16LE(4) + ->writeUInt32LE($value ? 1 : 0); + } else if (is_int($value)) { + $contentDescriptorsWriter + ->writeUInt16LE(3) + ->writeUInt16LE(4) + ->writeUInt32LE($value); + } else if (is_float($value)) { + $contentDescriptorsWriter + ->writeUInt16LE(4) + ->writeUInt16LE(8) + ->writeInt64LE($value); + } else { + // Invalid value and there is nothing to be done + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Invalid data type'); + } + } + + $this->setSize + (24 /* for header */ + 2 + $contentDescriptorsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($contentDescriptorsCount) + ->write($contentDescriptorsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/ExtendedContentEncryption.php b/src/Zend/Media/Asf/Object/ExtendedContentEncryption.php new file mode 100644 index 0000000..d18acf7 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ExtendedContentEncryption.php @@ -0,0 +1,101 @@ +Extended Content Encryption Object lets authors protect content by + * using the Windows Media Rights Manager 7 Software Development Kit (SDK). + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ExtendedContentEncryption + extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $dataSize = $this->_reader->readUInt32LE(); + $this->_data = $this->_reader->read($dataSize); + } + + /** + * Returns the array of bytes required by the DRM client to manipulate the + * protected content. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the array of bytes required by the DRM client to manipulate the + * protected content. + * + * @param string $data The data. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $this->setSize(24 /* for header */ + 4 + strlen($this->_data)); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt32LE(strlen($this->_data)) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Asf/Object/ExtendedStreamProperties.php b/src/Zend/Media/Asf/Object/ExtendedStreamProperties.php new file mode 100644 index 0000000..6081a35 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ExtendedStreamProperties.php @@ -0,0 +1,709 @@ +Extended Stream Properties Object defines additional optional + * properties and characteristics of a digital media stream that are not + * described in the Stream Properties Object. + * + * Typically, the basic Stream Properties Object is present in the + * Header Object, and the Extended Stream Properties Object is + * present in the Header Extension Object. Sometimes, however, the + * Stream Properties Object for a stream may be embedded inside the + * Extended Stream Properties Object for that stream. This approach + * facilitates the creation of backward-compatible content. + * + * This object has an optional provision to include application-specific or + * implementation-specific data attached to the payloads of each digital media + * sample stored within a Data Packet. This data can be looked at as + * digital media sample properties and is stored in the Replicated Data + * field of a payload header. The Payload Extension Systems fields of the + * Extended Stream Properties Object describes what this data is and is + * necessary for that data to be parsed, if present. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ExtendedStreamProperties + extends Zend_Media_Asf_Object +{ + /** + * Indicates, if set, that this digital media stream, if sent over a + * network, must be carried over a reliable data communications transport + * mechanism. This should be set for streams that cannot recover after a + * lost media object. + */ + const RELIABLE = 1; + + /** + * This flag should be set only if the stream is seekable, either by using + * an index object or by estimating according to bit rate (as can sometimes + * be done with audio). This flag pertains to this stream only rather than + * to the entire file. + */ + const SEEKABLE = 2; + + /** + * Indicates, if set, that the stream does not contain any cleanpoints. A + * cleanpoint is any point at which playback could begin without having seen + * the previous media objects. For streams that use key frames, the key + * frames would be the cleanpoints. + */ + const NO_CLEANPOINT = 4; + + /** + * Specifies, if set, that when a stream is joined in mid-transmission, all + * information from the most recent cleanpoint up to the current time should + * be sent before normal streaming begins at the current time. The default + * behavior (when this flag is not set) is to send only the data starting at + * the current time. This flag should only be set for streams that are + * coming from a live source. + */ + const RESEND_LIVE_CLEANPOINTS = 8; + + const AUDIO_MEDIA = 'f8699e40-5b4d-11cf-a8fd-00805f5c442b'; + const VIDEO_MEDIA = 'bc19efc0-5b4d-11cf-a8fd-00805f5c442b'; + const COMMAND_MEDIA = '59dacfc0-59e6-11d0-a3ac-00a0c90348f6'; + const JFIF_MEDIA = 'b61be100-5b4e-11cf-a8fD-00805f5c442b'; + const DEGRADABLE_JPEG_MEDIA = '35907dE0-e415-11cf-a917-00805f5c442b'; + const FILE_TRANSFER_MEDIA = '91bd222c-f21c-497a-8b6d-5aa86bfc0185'; + const BINARY_MEDIA = '3afb65e2-47ef-40f2-ac2c-70a90d71d343'; + + const NO_ERROR_CORRECTION = '20fb5700-5b55-11cf-a8fd-00805f5c442b'; + const AUDIO_SPREAD = 'bfc3cd50-618f-11cf-8bb2-00aa00b4e220'; + + const PAYLOAD_EXTENSION_SYSTEM_TIMECODE = + '399595ec-8667-4e2d-8fdb-98814ce76c1e'; + const PAYLOAD_EXTENSION_SYSTEM_FILE_NAME = + 'e165ec0e-19ed-45d7-b4a7-25cbd1e28e9b'; + const PAYLOAD_EXTENSION_SYSTEM_CONTENT_TYPE = + 'd590dc20-07bc-436c-9cf7-f3bbfbf1a4dc'; + const PAYLOAD_EXTENSION_SYSTEM_PIXEL_ASPECT_RATIO = + '1b1ee554-f9ea-4bc8-821a-376b74e4c4b8'; + const PAYLOAD_EXTENSION_SYSTEM_SAMPLE_DURATION = + 'c6bd9450-867f-4907-83a3-c77921b733ad'; + const PAYLOAD_EXTENSION_SYSTEM_ENCRYPTION_SAMPLE_ID = + '6698b84e-0afa-4330-aeb2-1c0a98d7a44d'; + + /** @var integer */ + private $_startTime; + + /** @var integer */ + private $_endTime; + + /** @var integer */ + private $_dataBitrate; + + /** @var integer */ + private $_bufferSize; + + /** @var integer */ + private $_initialBufferFullness; + + /** @var integer */ + private $_alternateDataBitrate; + + /** @var integer */ + private $_alternateBufferSize; + + /** @var integer */ + private $_alternateInitialBufferFullness; + + /** @var integer */ + private $_maximumObjectSize; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_streamNumber; + + /** @var integer */ + private $_streamLanguageIndex; + + /** @var integer */ + private $_averageTimePerFrame; + + /** @var Array */ + private $_streamNames = array(); + + /** @var Array */ + private $_payloadExtensionSystems = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_startTime = $this->_reader->readInt64LE(); + $this->_endTime = $this->_reader->readInt64LE(); + $this->_dataBitrate = $this->_reader->readUInt32LE(); + $this->_bufferSize = $this->_reader->readUInt32LE(); + $this->_initialBufferFullness = $this->_reader->readUInt32LE(); + $this->_alternateDataBitrate = $this->_reader->readUInt32LE(); + $this->_alternateBufferSize = $this->_reader->readUInt32LE(); + $this->_alternateInitialBufferFullness = $this->_reader->readUInt32LE(); + $this->_maximumObjectSize = $this->_reader->readUInt32LE(); + $this->_flags = $this->_reader->readUInt32LE(); + $this->_streamNumber = $this->_reader->readUInt16LE(); + $this->_streamLanguageIndex = $this->_reader->readUInt16LE(); + $this->_averageTimePerFrame = $this->_reader->readInt64LE(); + $streamNameCount = $this->_reader->readUInt16LE(); + $payloadExtensionSystemCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $streamNameCount; $i++) { + $streamName = + array('languageIndex' => $this->_reader->readUInt16LE()); + $streamNameLength = $this->_reader->readUInt16LE(); + $streamName['streamName'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($streamNameLength)); + $this->_streamNames[] = $streamName; + } + for ($i = 0; $i < $payloadExtensionSystemCount; $i++) { + $payloadExtensionSystem = array + ('extensionSystemId' => $this->_reader->readGuid(), + 'extensionDataSize' => $this->_reader->readUInt16LE()); + $extensionSystemInfoLength = $this->_reader->readUInt32LE(); + $payloadExtensionSystem['extensionSystemInfo'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($extensionSystemInfoLength)); + $this->_payloadExtensionSystems[] = $payloadExtensionSystem; + } + } + + /** + * Returns the presentation time of the first object, indicating where this + * digital media stream starts within the context of the timeline of the ASF + * file as a whole. This time value corresponds to presentation times as + * they appear in the data packets (adjusted by the preroll). This field is + * given in units of milliseconds and can optionally be set to 0, in which + * case it will be ignored. + * + * @return integer + */ + public function getStartTime() + { + return $this->_startTime; + } + + /** + * Sets the presentation time of the first object, indicating where this + * digital media stream starts within the context of the timeline of the ASF + * file as a whole. This time value corresponds to presentation times as + * they appear in the data packets (adjusted by the preroll). + * + * The given value must be in units of milliseconds or optionally be set to + * 0, in which case the field will be ignored. + * + * @param integer $startTime The presentation time of the first object. + */ + public function setStartTime($startTime) + { + $this->_startTime = $startTime; + } + + /** + * Returns the presentation time of the last object plus the duration of + * play, indicating where this digital media stream ends within the context + * of the timeline of the ASF file as a whole. This time value corresponds + * to presentation times as they appear in the data packets (adjusted by the + * preroll). This field is given in units of milliseconds and can optionally + * be set to 0, in which case it will be ignored. + * + * @return integer + */ + public function getEndTime() + { + return $this->_endTime; + } + + /** + * Sets the presentation time of the last object plus the duration of play, + * indicating where this digital media stream ends within the context of the + * timeline of the ASF file as a whole. This time value corresponds to + * presentation times as they appear in the data packets (adjusted by the + * preroll). + * + * The given value must be given in units of milliseconds or optionally be + * set to 0, in which case the field will be ignored. + * + * @param integer $endTime The presentation time of the last object plus the + * duration of play. + */ + public function setEndTime($endTime) + { + $this->_endTime = $endTime; + } + + /** + * Returns the leak rate R, in bits per second, of a leaky bucket that + * contains the data portion of the stream without overflowing, excluding + * all ASF Data Packet overhead. The size of the leaky bucket is specified + * by the value of the Buffer Size field. This field has a non-zero + * value. + * + * @return integer + */ + public function getDataBitrate() + { + return $this->_dataBitrate; + } + + /** + * Sets the leak rate R, in bits per second, of a leaky bucket that + * contains the data portion of the stream without overflowing, excluding + * all ASF Data Packet overhead. The size of the leaky bucket is specified + * by the value of the Buffer Size field. + * + * This field must be given a non-zero value. + * + * @param integer $dataBitrate The leak rate. + */ + public function setDataBitrate($dataBitrate) + { + $this->_dataBitrate = $dataBitrate; + } + + /** + * Returns the size B, in milliseconds, of the leaky bucket used in the + * Data Bitrate definition. + * + * @return integer + */ + public function getBufferSize() + { + return $this->_bufferSize; + } + + /** + * Sets the size B, in milliseconds, of the leaky bucket used in the + * Data Bitrate definition. + * + * @param integer $bufferSize The size. + */ + public function setBufferSize($bufferSize) + { + $this->_bufferSize = $bufferSize; + } + + /** + * Returns the initial fullness, in milliseconds, of the leaky bucket used + * in the Data Bitrate definition. This is the fullness of the buffer + * at the instant before the first bit in the stream is dumped into the + * bucket. Typically, this value is set to 0. This value shall not exceed + * the value in the Buffer Size field. + * + * @return integer + */ + public function getInitialBufferFullness() + { + return $this->_initialBufferFullness; + } + + /** + * Sets the initial fullness, in milliseconds, of the leaky bucket used in + * the Data Bitrate definition. This is the fullness of the buffer at + * the instant before the first bit in the stream is dumped into the bucket. + * Typically, this value is set to 0. This value shall not exceed the value + * in the Buffer Size field. + * + * @param integer $initialBufferFullness The initial fullness. + */ + public function setInitialBufferFullness($initialBufferFullness) + { + $this->_initialBufferFullness = $initialBufferFullness; + } + + /** + * Returns the leak rate RAlt, in bits per second, of a leaky bucket that + * contains the data portion of the stream without overflowing, excluding + * all ASF Data Packet overhead. The size of the leaky bucket is + * specified by the value of the Alternate Buffer Size field. This + * value is relevant in most scenarios where the bit rate is not exactly + * constant, but it is especially useful for streams that have highly + * variable bit rates. This field can optionally be set to the same value + * as the Data Bitrate field. + * + * @return integer + */ + public function getAlternateDataBitrate() + { + return $this->_alternateDataBitrate; + } + + /** + * Sets the leak rate RAlt, in bits per second, of a leaky bucket that + * contains the data portion of the stream without overflowing, excluding + * all ASF Data Packet overhead. The size of the leaky bucket is + * specified by the value of the Alternate Buffer Size field. This + * value is relevant in most scenarios where the bit rate is not exactly + * constant, but it is especially useful for streams that have highly + * variable bit rates. This field can optionally be set to the same value + * as the Data Bitrate field. + * + * @param integer $alternateDataBitrate The alternate leak rate. + */ + public function setAlternateDataBitrate($alternateDataBitrate) + { + $this->_alternateDataBitrate = $alternateDataBitrate; + } + + /** + * Returns the size BAlt, in milliseconds, of the leaky bucket used in the + * Alternate Data Bitrate definition. This value is relevant in most + * scenarios where the bit rate is not exactly constant, but it is + * especially useful for streams that have highly variable bit rates. This + * field can optionally be set to the same value as the Buffer Size + * field. + * + * @return integer + */ + public function getAlternateBufferSize() + { + return $this->_alternateBufferSize; + } + + /** + * Sets the size BAlt, in milliseconds, of the leaky bucket used in the + * Alternate Data Bitrate definition. This value is relevant in most + * scenarios where the bit rate is not exactly constant, but it is + * especially useful for streams that have highly variable bit rates. This + * field can optionally be set to the same value as the Buffer Size + * field. + * + * @param integer $alternateBufferSize + */ + public function setAlternateBufferSize($alternateBufferSize) + { + $this->_alternateBufferSize = $alternateBufferSize; + } + + /** + * Returns the initial fullness, in milliseconds, of the leaky bucket used + * in the Alternate Data Bitrate definition. This is the fullness of + * the buffer at the instant before the first bit in the stream is dumped + * into the bucket. Typically, this value is set to 0. This value does not + * exceed the value of the Alternate Buffer Size field. + * + * @return integer + */ + public function getAlternateInitialBufferFullness() + { + return $this->_alternateInitialBufferFullness; + } + + /** + * Sets the initial fullness, in milliseconds, of the leaky bucket used in + * the Alternate Data Bitrate definition. This is the fullness of the + * buffer at the instant before the first bit in the stream is dumped into + * the bucket. Typically, this value is set to 0. This value does not exceed + * the value of the Alternate Buffer Size field. + * + * @param integer $alternateInitialBufferFullness The alternate initial + * fullness. + */ + public function setAlternateInitialBufferFullness + ($alternateInitialBufferFullness) + { + $this->_alternateInitialBufferFullness = + $alternateInitialBufferFullness; + } + + /** + * Returns the maximum size of the largest sample stored in the data packets + * for a stream. A value of 0 means unknown. + * + * @return integer + */ + public function getMaximumObjectSize() + { + return $this->_maximumObjectSize; + } + + /** + * Sets the maximum size of the largest sample stored in the data packets + * for a stream. A value of 0 means unknown. + * + * @param integer $maximumObjectSize The maximum size of the largest sample. + */ + public function setMaximumObjectSize($maximumObjectSize) + { + $this->_maximumObjectSize = $maximumObjectSize; + } + + /** + * Returns the average time duration, measured in 100-nanosecond units, of + * each frame. This number should be rounded to the nearest integer. This + * field can optionally be set to 0 if the average time per frame is unknown + * or unimportant. It is recommended that this field be set for video. + * + * @return integer + */ + public function getAverageTimePerFrame() + { + return $this->_averageTimePerFrame; + } + + /** + * Sets the average time duration, measured in 100-nanosecond units, of + * each frame. This number should be rounded to the nearest integer. This + * field can optionally be set to 0 if the average time per frame is unknown + * or unimportant. It is recommended that this field be set for video. + * + * @param integer $averageTimePerFrame The average time duration. + */ + public function setAverageTimePerFrame($averageTimePerFrame) + { + $this->_averageTimePerFrame = $averageTimePerFrame; + } + + /** + * Returns the number of this stream. 0 is an invalid stream number (that + * is, other Header Objects use stream number 0 to refer to the + * entire file as a whole rather than to a specific media stream within the + * file). Valid values are between 1 and 127. + * + * @return integer + */ + public function getStreamNumber() + { + return $this->_streamNumber; + } + + /** + * Sets the number of this stream. 0 is an invalid stream number (that is, + * other Header Objects use stream number 0 to refer to the entire + * file as a whole rather than to a specific media stream within the file). + * Valid values are between 1 and 127. + * + * @param integer $streamNumber The number of this stream. + */ + public function setStreamNumber($streamNumber) + { + $this->_streamNumber = $streamNumber; + } + + /** + * Returns the language, if any, which the content of the stream uses or + * assumes. Refer to the {@link LanguageList Language List Object} + * description for the details concerning how the Stream Language + * Index and Language Index fields should be used. Note that this + * is an index into the languages listed in the Language List Object + * rather than a language identifier. + * + * @return integer + */ + public function getStreamLanguageIndex() + { + return $this->_streamLanguageIndex; + } + + /** + * Sets the language, if any, which the content of the stream uses or + * assumes. Refer to the {@link LanguageList Language List Object} + * description for the details concerning how the Stream Language + * Index and Language Index fields should be used. Note that this + * is an index into the languages listed in the Language List Object + * rather than a language identifier. + * + * @param integer $streamLanguageIndex The language index. + */ + public function setStreamLanguageIndex($streamLanguageIndex) + { + $this->_streamLanguageIndex = $streamLanguageIndex; + } + + /** + * Returns an array of Stream Names. Each stream name instance is + * potentially localized into a specific language. The Language Index + * field indicates the language in which the Stream Name has been + * written. + * + * The array entry contains the following keys: + * o languageIndex -- The language index + * o streamName -- The localized stream name + * + * @return Array + */ + public function getStreamNames() + { + return $this->_streamNames; + } + + /** + * Sets the array of stream names. Each stream name instance is potentially + * localized into a specific language. The Language Index field + * indicates the language in which the Stream Name has been written. + * + * The array entries are to contain the following keys: + * o languageIndex -- The language index + * o streamName -- The localized stream name + * + * @param Array $streamNames The array of stream names + */ + public function setStreamNames($streamNames) + { + $this->_streamNames = $streamNames; + } + + /** + * Returns an array of payload extension systems. Payload extensions provide + * a way for content creators to specify kinds of data that will appear in + * the payload header for every payload from this stream. This system is + * used when stream properties must be conveyed at the media object level. + * The Replicated Data bytes in the payload header will contain these + * properties in the order in which the Payload Extension Systems + * appear in this object. A Payload Extension System must appear in + * the Extended Stream Properties Object for each type of + * per-media-object properties that will appear with the payloads for this + * stream. + * + * The array entry contains the following keys: + * o extensionSystemId -- Specifies a unique identifier for the extension + * system. + * o extensionDataSize -- Specifies the fixed size of the extension data + * for this system that will appear in the replicated data alongside + * every payload for this stream. If this extension system uses + * variable-size data, then this should be set to 0xffff. Note, however, + * that replicated data length is limited to 255 bytes, which limits the + * total size of all extension systems for a particular stream. + * o extensionSystemInfo -- Specifies additional information to describe + * this extension system (optional). + * + * @return Array + */ + public function getPayloadExtensionSystems() + { + return $this->_payloadExtensionSystems; + } + + /** + * Sets an array of payload extension systems. Payload extensions provide a + * way for content creators to specify kinds of data that will appear in the + * payload header for every payload from this stream. This system is used + * when stream properties must be conveyed at the media object level. The + * Replicated Data bytes in the payload header will contain these + * properties in the order in which the Payload Extension Systems + * appear in this object. A Payload Extension System must appear in + * the Extended Stream Properties Object for each type of + * per-media-object properties that will appear with the payloads for this + * stream. + * + * The array enties are to contain the following keys: + * o extensionSystemId -- Specifies a unique identifier for the extension + * system. + * o extensionDataSize -- Specifies the fixed size of the extension data + * for this system that will appear in the replicated data alongside + * every payload for this stream. If this extension system uses + * variable-size data, then this should be set to 0xffff. Note, however, + * that replicated data length is limited to 255 bytes, which limits the + * total size of all extension systems for a particular stream. + * o extensionSystemInfo -- Specifies additional information to describe + * this extension system (optional). + * + * @param Array $payloadExtensionSystems The array of payload extension + * systems. + */ + public function setPayloadExtensionSystems($payloadExtensionSystems) + { + $this->_payloadExtensionSystems = $payloadExtensionSystems; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + + $streamNameCount = count($this->_streamNames); + $streamNameWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $streamNameCount; $i++) { + $streamNameWriter + ->writeUInt16LE($this->_streamNames['languageIndex']) + ->writeUInt16LE(strlen($streamName = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_streamNames['streamName']) . "\0\0")) + ->writeString16($streamName); + } + + $payloadExtensionSystemCount = count($this->_payloadExtensionSystems); + $payloadExtensionSystemWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $payloadExtensionSystemCount; $i++) { + $payloadExtensionSystemWriter + ->writeGuid($this->_streamNames['extensionSystemId']) + ->writeUInt16LE($this->_streamNames['extensionDataSize']) + ->writeUInt16LE(strlen($extensionSystemInfo = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_streamNames['extensionSystemInfo']) . "\0\0")) + ->writeString16($extensionSystemInfo); + } + + + $this->setSize + (24 /* for header */ + 64 + $streamNameWriter->getSize() + + $payloadExtensionSystemWriter->getSize()); + + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeInt64LE($this->_startTime) + ->writeInt64LE($this->_endTime) + ->writeUInt32LE($this->_dataBitrate) + ->writeUInt32LE($this->_bufferSize) + ->writeUInt32LE($this->_initialBufferFullness) + ->writeUInt32LE($this->_alternateDataBitrate) + ->writeUInt32LE($this->_alternateBufferSize) + ->writeUInt32LE($this->_alternateInitialBufferFullness) + ->writeUInt32LE($this->_maximumObjectSize) + ->writeUInt32LE($this->_flags) + ->writeUInt16LE($this->_streamNumber) + ->writeUInt16LE($this->_streamLanguageIndex) + ->writeInt64LE($this->_averageTimePerFrame) + ->writeUInt16LE($streamNameCount) + ->writeUInt16LE($payloadExtensionSystemCount) + ->write($streamNameWriter->toString()) + ->write($payloadExtensionSystemWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/FileProperties.php b/src/Zend/Media/Asf/Object/FileProperties.php new file mode 100644 index 0000000..360145d --- /dev/null +++ b/src/Zend/Media/Asf/Object/FileProperties.php @@ -0,0 +1,440 @@ +File Properties Object defines the global characteristics of the + * combined digital media streams found within the Data Object. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_FileProperties extends Zend_Media_Asf_Object +{ + /** + * Indicates, if set, that a file is in the process of being created (for + * example, for recording applications), and thus that various values stored + * in the header objects are invalid. It is highly recommended that + * post-processing be performed to remove this condition at the earliest + * opportunity. + */ + const BROADCAST = 1; + + /** + * Indicates, if set, that a file is seekable. Note that for files + * containing a single audio stream and a Minimum Data Packet Size + * field equal to the Maximum Data Packet Size field, this flag shall + * always be set to 1. For files containing a single audio stream and a + * video stream or mutually exclusive video streams, this flag is only set + * to 1 if the file contains a matching Simple Index Object for each + * regular video stream. + */ + const SEEKABLE = 2; + + /** @var string */ + private $_fileId; + + /** @var integer */ + private $_fileSize; + + /** @var integer */ + private $_creationDate; + + /** @var integer */ + private $_dataPacketsCount; + + /** @var integer */ + private $_playDuration; + + /** @var integer */ + private $_sendDuration; + + /** @var integer */ + private $_preroll; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_minimumDataPacketSize; + + /** @var integer */ + private $_maximumDataPacketSize; + + /** @var integer */ + private $_maximumBitrate; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_fileId = $this->_reader->readGuid(); + $this->_fileSize = $this->_reader->readInt64LE(); + $this->_creationDate = $this->_reader->readInt64LE(); + $this->_dataPacketsCount = $this->_reader->readInt64LE(); + $this->_playDuration = $this->_reader->readInt64LE(); + $this->_sendDuration = $this->_reader->readInt64LE(); + $this->_preroll = $this->_reader->readInt64LE(); + $this->_flags = $this->_reader->readUInt32LE(); + $this->_minimumDataPacketSize = $this->_reader->readUInt32LE(); + $this->_maximumDataPacketSize = $this->_reader->readUInt32LE(); + $this->_maximumBitrate = $this->_reader->readUInt32LE(); + } + + /** + * Returns the file id field. + * + * @return integer + */ + public function getFileId() + { + return $this->_fileId; + } + + /** + * Sets the file id field. + * + * @param GUID $fileId The new file id. + */ + public function setFileId($fileId) + { + $this->_fileId = $fileId; + } + + /** + * Returns the size, in bytes, of the entire file. The value of this field + * is invalid if the broadcast flag bit in the flags field is set to 1. + * + * @return integer + */ + public function getFileSize() + { + return $this->_fileSize; + } + + /** + * Sets the size, in bytes, of the entire file. The value of this field is + * invalid if the broadcast flag bit in the flags field is set to 1. + * + * @param integer $fileSize The size of the entire file. + */ + public function setFileSize($fileSize) + { + $this->_fileSize = $fileSize; + } + + /** + * Returns the date and time of the initial creation of the file. The value + * is given as the number of 100-nanosecond intervals since January 1, 1601, + * according to Coordinated Universal Time (Greenwich Mean Time). The value + * of this field may be invalid if the broadcast flag bit in the flags field + * is set to 1. + * + * @return integer + */ + public function getCreationDate() + { + return $this->_creationDate; + } + + /** + * Sets the date and time of the initial creation of the file. The value is + * given as the number of 100-nanosecond intervals since January 1, 1601, + * according to Coordinated Universal Time (Greenwich Mean Time). The value + * of this field may be invalid if the broadcast flag bit in the flags field + * is set to 1. + * + * @param integer $creationDate The date and time of the initial creation of + * the file. + */ + public function setCreationDate($creationDate) + { + $this->_creationDate = $creationDate; + } + + /** + * Returns the number of Data Packet entries that exist within the + * {@link Zend_Media_Asf_Object_Data Data Object}. The value of this field + * is invalid if the broadcast flag bit in the flags field is set to 1. + * + * @return integer + */ + public function getDataPacketsCount() + { + return $this->_dataPacketsCount; + } + + /** + * Sets the number of Data Packet entries that exist within the + * {@link Zend_Media_Asf_Object_Data Data Object}. The value of this field + * is invalid if the broadcast flag bit in the flags field is set to 1. + * + * @param integer $dataPacketsCount The number of Data Packet entries. + */ + public function setDataPacketsCount($dataPacketsCount) + { + $this->_dataPacketsCount = $dataPacketsCount; + } + + /** + * Returns the time needed to play the file in 100-nanosecond units. This + * value should include the duration (estimated, if an exact value is + * unavailable) of the the last media object in the presentation. The value + * of this field is invalid if the broadcast flag bit in the flags field is + * set to 1. + * + * @return integer + */ + public function getPlayDuration() + { + return $this->_playDuration; + } + + /** + * Sets the time needed to play the file in 100-nanosecond units. This + * value should include the duration (estimated, if an exact value is + * unavailable) of the the last media object in the presentation. The value + * of this field is invalid if the broadcast flag bit in the flags field is + * set to 1. + * + * @param integer $playDuration The time needed to play the file. + */ + public function setPlayDuration($playDuration) + { + $this->_playDuration = $playDuration; + } + + /** + * Returns the time needed to send the file in 100-nanosecond units. This + * value should include the duration of the last packet in the content. The + * value of this field is invalid if the broadcast flag bit in the flags + * field is set to 1. + * + * @return integer + */ + public function getSendDuration() + { + return $this->_sendDuration; + } + + /** + * Sets the time needed to send the file in 100-nanosecond units. This + * value should include the duration of the last packet in the content. The + * value of this field is invalid if the broadcast flag bit in the flags + * field is set to 1. + * + * @param integer $sendDuration The time needed to send the file. + */ + public function setSendDuration($sendDuration) + { + $this->_sendDuration = $sendDuration; + } + + /** + * Returns the amount of time to buffer data before starting to play the + * file, in millisecond units. If this value is nonzero, the Play + * Duration field and all of the payload Presentation Time fields + * have been offset by this amount. Therefore, player software must subtract + * the value in the preroll field from the play duration and presentation + * times to calculate their actual values. + * + * @return integer + */ + public function getPreroll() + { + return $this->_preroll; + } + + /** + * Sets the amount of time to buffer data before starting to play the file, + * in millisecond units. If this value is nonzero, the Play Duration + * field and all of the payload Presentation Time fields have been + * offset by this amount. Therefore, player software must subtract the value + * in the preroll field from the play duration and presentation times to + * calculate their actual values. + * + * @param integer $preroll The amount of time to buffer data. + */ + public function setPreroll($preroll) + { + $this->_preroll = $preroll; + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the flags field. + * + * @return integer + */ + public function getFlags() + { + return $this->_flags; + } + + /** + * Sets the flags field. + * + * @param integer $flags The flags field. + */ + public function setFlags($flags) + { + $this->_flags = $flags; + } + + /** + * Returns the minimum Data Packet size in bytes. In general, the + * value of this field is invalid if the broadcast flag bit in the flags + * field is set to 1. However, the values for the Minimum Data Packet + * Size and Maximum Data Packet Size fields shall be set to the + * same value, and this value should be set to the packet size, even when + * the broadcast flag in the flags field is set to 1. + * + * @return integer + */ + public function getMinimumDataPacketSize() + { + return $this->_minimumDataPacketSize; + } + + /** + * Sets the minimum Data Packet size in bytes. In general, the value + * of this field is invalid if the broadcast flag bit in the flags field is + * set to 1. However, the values for the Minimum Data Packet Size and + * Maximum Data Packet Size fields shall be set to the same value, + * and this value should be set to the packet size, even when the broadcast + * flag in the flags field is set to 1. + * + * @param integer $minimumDataPacketSize The minimum Data Packet size + * in bytes. + */ + public function setMinimumDataPacketSize($minimumDataPacketSize) + { + $this->_minimumDataPacketSize = $minimumDataPacketSize; + } + + /** + * Returns the maximum Data Packet size in bytes. In general, the + * value of this field is invalid if the broadcast flag bit in the flags + * field is set to 1. However, the values for the Minimum Data Packet + * Size and Maximum Data Packet Size fields shall be set to the + * same value, and this value should be set to the packet size, even when + * the broadcast flag in the flags field is set to 1. + * + * @return integer + */ + public function getMaximumDataPacketSize() + { + return $this->_maximumDataPacketSize; + } + + /** + * Sets the maximum Data Packet size in bytes. In general, the value + * of this field is invalid if the broadcast flag bit in the flags field is + * set to 1. However, the values for the Minimum Data Packet Size and + * Maximum Data Packet Size fields shall be set to the same value, + * and this value should be set to the packet size, even when the broadcast + * flag in the flags field is set to 1. + * + * @param integer $maximumDataPacketSize The maximum Data Packet size + * in bytes + */ + public function setMaximumDataPacketSize($maximumDataPacketSize) + { + $this->_maximumDataPacketSize = $maximumDataPacketSize; + } + + /** + * Returns the maximum instantaneous bit rate in bits per second for the + * entire file. This is equal the sum of the bit rates of the individual + * digital media streams. + * + * @return integer + */ + public function getMaximumBitrate() + { + return $this->_maximumBitrate; + } + + /** + * Sets the maximum instantaneous bit rate in bits per second for the + * entire file. This is equal the sum of the bit rates of the individual + * digital media streams. + * + * @param integer $maximumBitrate The maximum instantaneous bit rate in bits + * per second. + */ + public function setMaximumBitrate($maximumBitrate) + { + $this->_maximumBitrate = $maximumBitrate; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $this->setSize(24 /* for header */ + 80); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_fileId) + ->writeInt64LE($this->_fileSize) + ->writeInt64LE($this->_creationDate) + ->writeInt64LE($this->_dataPacketsCount) + ->writeInt64LE($this->_playDuration) + ->writeInt64LE($this->_sendDuration) + ->writeInt64LE($this->_preroll) + ->writeUInt32LE($this->_flags) + ->writeUInt32LE($this->_minimumDataPacketSize) + ->writeUInt32LE($this->_maximumDataPacketSize) + ->writeUInt32LE($this->_maximumBitrate); + } +} diff --git a/src/Zend/Media/Asf/Object/GroupMutualExclusion.php b/src/Zend/Media/Asf/Object/GroupMutualExclusion.php new file mode 100644 index 0000000..3397620 --- /dev/null +++ b/src/Zend/Media/Asf/Object/GroupMutualExclusion.php @@ -0,0 +1,162 @@ +Group Mutual Exclusion Object is used to describe mutual exclusion + * relationships between groups of streams. This object is organized in terms of + * records, each containing one or more streams, where a stream in record N + * cannot coexist with a stream in record M for N != M (however, streams in the + * same record can coexist). This mutual exclusion object would be used + * typically for the purpose of language mutual exclusion, and a record would + * consist of all streams for a particular language. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_GroupMutualExclusion + extends Zend_Media_Asf_Object +{ + const MUTEX_LANGUAGE = 'd6e22a00-35da-11d1-9034-00a0c90349be'; + const MUTEX_BITRATE = 'd6e22a01-35da-11d1-9034-00a0c90349be'; + const MUTEX_UNKNOWN = 'd6e22a02-35da-11d1-9034-00a0c90349be'; + + /** @var string */ + private $_exclusionType; + + /** @var Array */ + private $_records = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_exclusionType = $this->_reader->readGuid(); + $recordCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $recordCount; $i++) { + $streamNumbersCount = $this->_reader->readUInt16LE(); + $streamNumbers = array(); + for ($j = 0; $j < $streamNumbersCount; $j++) { + $streamNumbers[] = array + ('streamNumbers' => $this->_reader->readUInt16LE()); + } + $this->_records[] = $streamNumbers; + } + } + + /** + * Returns the nature of the mutual exclusion relationship. + * + * @return string + */ + public function getExclusionType() + { + return $this->_exclusionType; + } + + /** + * Sets the nature of the mutual exclusion relationship. + * + * @param string $exclusionType The exclusion type. + */ + public function setExclusionType($exclusionType) + { + $this->_exclusionType = $exclusionType; + } + + /** + * Returns an array of records. Each record consists of the following keys. + * + * o streamNumbers -- Specifies the stream numbers for this record. Valid + * values are between 1 and 127. + * + * @return Array + */ + public function getRecords() + { + return $this->_records; + } + + /** + * Sets an array of records. Each record is to consist of the following + * keys. + * + * o streamNumbers -- Specifies the stream numbers for this record. Valid + * values are between 1 and 127. + * + * @param Array $records The array of records + */ + public function setRecords($records) + { + $this->_records = $records; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + + $recordCount = count($this->_records); + $recordWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $recordCount; $i++) { + $recordWriter + ->writeUInt16LE + ($streamNumbersCount = count($this->_records[$i])); + for ($j = 0; $j < $streamNumbersCount; $j++) { + $recordWriter->writeUInt16LE + ($this->_records[$i][$j]['streamNumbers']); + } + } + + $this->setSize(24 /* for header */ + $recordWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_exclusionType) + ->writeUInt16LE($recordCount) + ->write($recordWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Header.php b/src/Zend/Media/Asf/Object/Header.php new file mode 100644 index 0000000..9f30899 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Header.php @@ -0,0 +1,131 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Header extends Zend_Media_Asf_Object_Container +{ + /** @var integer */ + private $_reserved1; + + /** @var integer */ + private $_reserved2; + + /** + * Constructs the class with given parameters and options. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_reader->skip(4); + $this->_reserved1 = $this->_reader->readInt8(); + $this->_reserved2 = $this->_reader->readInt8(); + $this->constructObjects + (array + (self::FILE_PROPERTIES => 'FileProperties', + self::STREAM_PROPERTIES => 'StreamProperties', + self::HEADER_EXTENSION => 'HeaderExtension', + self::CODEC_LIST => 'CodecList', + self::SCRIPT_COMMAND => 'ScriptCommand', + self::MARKER => 'Marker', + self::BITRATE_MUTUAL_EXCLUSION => 'BitrateMutualExclusion', + self::ERROR_CORRECTION => 'ErrorCorrection', + self::CONTENT_DESCRIPTION => 'ContentDescription', + self::EXTENDED_CONTENT_DESCRIPTION => + 'ExtendedContentDescription', + self::CONTENT_BRANDING => 'ContentBranding', + self::STREAM_BITRATE_PROPERTIES => 'StreamBitrateProperties', + self::CONTENT_ENCRYPTION => 'ContentEncryption', + self::EXTENDED_CONTENT_ENCRYPTION => + 'ExtendedContentEncryption', + self::DIGITAL_SIGNATURE => 'DigitalSignature', + self::PADDING => 'Padding')); + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $objectsWriter = new Zend_Io_StringWriter(); + foreach ($this->getObjects() as $objects) { + foreach ($objects as $object) { + $object->write($objectsWriter); + } + } + + $this->setSize + (24 /* for header */ + 6 + $objectsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt32LE($this->getObjectCount()) + ->writeInt8($this->_reserved1) + ->writeInt8($this->_reserved2) + ->write($objectsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/HeaderExtension.php b/src/Zend/Media/Asf/Object/HeaderExtension.php new file mode 100644 index 0000000..66f9abe --- /dev/null +++ b/src/Zend/Media/Asf/Object/HeaderExtension.php @@ -0,0 +1,110 @@ +Header Extension Object allows additional functionality to be + * added to an ASF file while maintaining backward compatibility. The Header + * Extension Object is a container containing zero or more additional extended + * header objects. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_HeaderExtension + extends Zend_Media_Asf_Object_Container +{ + /** @var string */ + private $_reserved1; + + /** @var integer */ + private $_reserved2; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_reserved1 = $this->_reader->readGuid(); + $this->_reserved2 = $this->_reader->readUInt16LE(); + $this->_reader->skip(4); + $this->constructObjects + (array + (self::EXTENDED_STREAM_PROPERTIES => 'ExtendedStreamProperties', + self::ADVANCED_MUTUAL_EXCLUSION => 'AdvancedMutualExclusion', + self::GROUP_MUTUAL_EXCLUSION => 'GroupMutualExclusion', + self::STREAM_PRIORITIZATION => 'StreamPrioritization', + self::BANDWIDTH_SHARING => 'BandwidthSharing', + self::LANGUAGE_LIST => 'LanguageList', + self::METADATA => 'Metadata', + self::METADATA_LIBRARY => 'MetadataLibrary', + self::INDEX_PARAMETERS => 'IndexParameters', + self::MEDIA_OBJECT_INDEX_PARAMETERS => + 'MediaObjectIndexParameters', + self::TIMECODE_INDEX_PARAMETERS => 'TimecodeIndexParameters', + self::COMPATIBILITY => 'Compatibility', + self::ADVANCED_CONTENT_ENCRYPTION => + 'AdvancedContentEncryption', + self::PADDING => 'Padding')); + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $objectsWriter = new Zend_Io_StringWriter(); + foreach ($this->getObjects() as $objects) { + foreach ($objects as $object) { + $object->write($objectsWriter); + } + } + + $this->setSize + (24 /* for header */ + 22 + $objectsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_reserved1) + ->writeUInt16LE($this->_reserved2) + ->writeUInt32LE($objectsWriter->getSize()) + ->write($objectsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Index.php b/src/Zend/Media/Asf/Object/Index.php new file mode 100644 index 0000000..c519b9c --- /dev/null +++ b/src/Zend/Media/Asf/Object/Index.php @@ -0,0 +1,193 @@ +Index Object are in terms of presentation times. The + * corresponding Offset field values of the Index Entry byte + * offsets that, when combined with the Block Position value of the + * Index Block, indicate the starting location in bytes of an ASF Data + * Packet relative to the start of the first ASF Data Packet in the file. + * + * An offset value of 0xFFFFFFFF is used to indicate an invalid offset value. + * Invalid offsets signify that this particular index entry does not identify a + * valid indexible point. Invalid offsets may occur for the initial index + * entries of a digital media stream whose first ASF Data Packet has a non-zero + * send time. Invalid offsets may also occur in the case where a digital media + * stream has a large gap in the presentation time of successive objects. + * + * The Index Object is not recommended for use with files where the + * Send Time of the first Data Packet within the Data + * Object has a Send Time value significantly greater than zero + * (otherwise the index itself will be sparse and inefficient). + * + * Any ASF file containing an Index Object does also contain an Index + * Parameters Object in its {@link Zend_Media_Asf_Object_Header ASF Header}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Index extends Zend_Media_Asf_Object +{ + /** + * Indicates that the index type is Nearest Past Data Packet. The Nearest + * Past Data Packet indexes point to the data packet whose presentation time + * is closest to the index entry time. + */ + const NEAREST_PAST_DATA_PACKET = 1; + + /** + * Indicates that the index type is Nearest Past Media. The Nearest Past + * Object indexes point to the closest data packet containing an entire + * object or first fragment of an object. + */ + const NEAREST_PAST_MEDIA = 2; + + /** + * Indicates that the index type is Nearest Past Cleanpoint. The Nearest + * Past Cleanpoint indexes point to the closest data packet containing an + * entire object (or first fragment of an object) that has the Cleanpoint + * Flag set. + * + * Nearest Past Cleanpoint is the most common type of index. + */ + const NEAREST_PAST_CLEANPOINT = 3; + + /** @var integer */ + private $_indexEntryTimeInterval; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** @var Array */ + private $_indexBlocks = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_indexEntryTimeInterval = $this->_reader->readUInt32LE(); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + $indexBlocksCount = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + for ($i = 0; $i < $indexBlocksCount; $i++) { + $indexEntryCount = $this->_reader->readUInt32LE(); + $blockPositions = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $blockPositions[] = $this->_reader->readInt64LE(); + } + $offsets = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $offsets[] = $this->_reader->readUInt32LE(); + } + $this->_indexBlocks[] = array + ('blockPositions' => $blockPositions, + 'indexEntryOffsets' => $offsets); + } + } + + /** + * Returns the time interval between each index entry in ms. + * + * @return integer + */ + public function getIndexEntryTimeInterval() + { + return $this->_indexEntryTimeInterval; + } + + /** + * Returns an array of index specifiers. Each entry consists of the + * following keys. + * + * o streamNumber -- Specifies the stream number that the Index + * Specifiers refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o blockPositions -- Specifies a list of byte offsets of the beginnings + * of the blocks relative to the beginning of the first Data Packet (for + * example, the beginning of the Data Object + 50 bytes). + * + * o indexEntryOffsets -- Specifies the offset. An offset value of + * 0xffffffff indicates an invalid offset value. + * + * @return Array + */ + public function getIndexBlocks() + { + return $this->_indexBlocks; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/IndexParameters.php b/src/Zend/Media/Asf/Object/IndexParameters.php new file mode 100644 index 0000000..4699653 --- /dev/null +++ b/src/Zend/Media/Asf/Object/IndexParameters.php @@ -0,0 +1,125 @@ +Index Parameters Object supplies information about those streams + * that are actually indexed (there must be at least one stream in an index) by + * the {@link Zend_Media_Asf_Object_Index Index Object} and how they are being + * indexed. This object shall be present in the + * {@link Zend_Media_Asf_Object_Header Header Object} if there is an + * {@link Zend_Media_Asf_Object_Index Index Object} present in the file. + * + + * An Index Specifier is required for each stream that will be indexed by the + * {@link Zend_Media_Asf_Object_Index Index Object}. These specifiers must + * exactly match those in the {@link Zend_Media_Asf_Object_Index Index Object}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_IndexParameters extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_indexEntryTimeInterval; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_indexEntryTimeInterval = $this->_reader->readUInt32LE(); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + } + + /** + * Returns the time interval between index entries in milliseconds. This + * value cannot be 0. + * + * @return integer + */ + public function getIndexEntryTimeInterval() + { + return $this->_indexEntryTimeInterval; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o streamNumber -- Specifies the stream number that the Index Specifiers + * refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. Values are as follows: + * 1 = Nearest Past Data Packet, + * 2 = Nearest Past Media Object, and + * 3 = Nearest Past Cleanpoint. + * The Nearest Past Data Packet indexes point to the data packet whose + * presentation time is closest to the index entry time. The Nearest + * Past Object indexes point to the closest data packet containing an + * entire object or first fragment of an object. The Nearest Past + * Cleanpoint indexes point to the closest data packet containing an + * entire object (or first fragment of an object) that has the + * Cleanpoint Flag set. Nearest Past Cleanpoint is the most common type + * of index. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/LanguageList.php b/src/Zend/Media/Asf/Object/LanguageList.php new file mode 100644 index 0000000..fd13abb --- /dev/null +++ b/src/Zend/Media/Asf/Object/LanguageList.php @@ -0,0 +1,116 @@ +Language List Object contains an array of Unicode-based language + * IDs. All other header objects refer to languages through zero-based positions + * in this array. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_LanguageList extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_languages = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $languageIdRecordsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $languageIdRecordsCount; $i++) { + $languageIdLength = $this->_reader->readInt8(); + $languageId = $this->_reader->readString16($languageIdLength); + $this->_languages[] = iconv + ('utf-16le', $this->getOption('encoding'), $languageId); + } + } + + /** + * Returns the array of language ids. + * + * @return Array + */ + public function getLanguages() + { + return $this->_languages; + } + + /** + * Sets the array of language ids. + * + * @param Array $languages The array of language ids. + */ + public function setLanguages($languages) + { + $this->_languages = $languages; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $languageIdRecordsCount = count($this->_languages); + $languageIdRecordsWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $languageIdRecordsCount; $i++) { + $languageIdRecordsWriter + ->writeInt8(strlen($languageId = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_languages[$i]) . "\0\0")) + ->writeString16($languageId); + } + + $this->setSize + (24 /* for header */ + 2 + $languageIdRecordsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($languageIdRecordsCount) + ->write($languageIdRecordsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Marker.php b/src/Zend/Media/Asf/Object/Marker.php new file mode 100644 index 0000000..e4d99ef --- /dev/null +++ b/src/Zend/Media/Asf/Object/Marker.php @@ -0,0 +1,197 @@ +Marker Object class. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Marker extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_reserved1; + + /** @var integer */ + private $_reserved2; + + /** @var string */ + private $_name; + + /** @var Array */ + private $_markers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_reserved1 = $this->_reader->readGuid(); + $markersCount = $this->_reader->readUInt32LE(); + $this->_reserved2 = $this->_reader->readUInt16LE(); + $nameLength = $this->_reader->readUInt16LE(); + $this->_name = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($nameLength)); + for ($i = 0; $i < $markersCount; $i++) { + $marker = array + ('offset' => $this->_reader->readInt64LE(), + 'presentationTime' => $this->_reader->readInt64LE()); + $this->_reader->skip(2); + $marker['sendTime'] = $this->_reader->readUInt32LE(); + $marker['flags'] = $this->_reader->readUInt32LE(); + $descriptionLength = $this->_reader->readUInt32LE(); + $marker['description'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($descriptionLength)); + $this->_markers[] = $marker; + } + } + + /** + * Returns the name of the Marker Object. + * + * @return Array + */ + public function getName() + { + return $this->_name; + } + + /** + * Returns the name of the Marker Object. + * + * @param string $name The name. + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns an array of markers. Each entry consists of the following keys. + * + * o offset -- Specifies a byte offset into the Data Object to the + * actual position of the marker in the Data Object. ASF parsers + * must seek to this position to properly display data at the specified + * marker Presentation Time. + * + * o presentationTime -- Specifies the presentation time of the marker, in + * 100-nanosecond units. + * + * o sendTime -- Specifies the send time of the marker entry, in + * milliseconds. + * + * o flags -- Flags are reserved and should be set to 0. + * + * o description -- Specifies a description of the marker entry. + * + * @return Array + */ + public function getMarkers() + { + return $this->_markers; + } + + /** + * Sets the array of markers. Each entry is to consist of the following + * keys. + * + * o offset -- Specifies a byte offset into the Data Object to the + * actual position of the marker in the Data Object. ASF parsers + * must seek to this position to properly display data at the specified + * marker Presentation Time. + * + * o presentationTime -- Specifies the presentation time of the marker, in + * 100-nanosecond units. + * + * o sendTime -- Specifies the send time of the marker entry, in + * milliseconds. + * + * o flags -- Flags are reserved and should be set to 0. + * + * o description -- Specifies a description of the marker entry. + * + * @param Array $markers The array of markers. + */ + public function setMarkers($markers) + { + $this->_markers = $markers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + + $name = iconv + ($this->getOption('encoding'), 'utf-16le', $this->_name) . "\0\0"; + $markersCount = count($this->_markers); + $markersWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $markersCount; $i++) { + $markersWriter + ->writeInt64LE($this->_markers[$i]['offset']) + ->writeInt64LE($this->_markers[$i]['presentationTime']) + ->writeUInt16LE + (12 + ($descriptionLength = strlen($description = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_markers[$i]['description']) . "\0\0"))) + ->writeUInt32LE($this->_markers[$i]['sendTime']) + ->writeUInt32LE($this->_markers[$i]['flags']) + ->writeUInt32LE($descriptionLength) + ->writeString16($description); + } + + $this->setSize + (24 /* for header */ + 24 + strlen($name) + + $markersWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_reserved1) + ->writeUInt32LE($markersCount) + ->writeUInt16LE($this->_reserved2) + ->writeUInt16LE(strlen($name)) + ->writeString16($name) + ->write($markersWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/MediaObjectIndex.php b/src/Zend/Media/Asf/Object/MediaObjectIndex.php new file mode 100644 index 0000000..03f3ff0 --- /dev/null +++ b/src/Zend/Media/Asf/Object/MediaObjectIndex.php @@ -0,0 +1,186 @@ +Media Object Index Object are in terms of media + * object numbers, with the first frame for a given stream in the ASF file + * corresponding to entry 0 in the Media Object Index Object. The + * corresponding Offset field values of the Index Entry are byte + * offsets that, when combined with the Block Position value of the + * Index Block, indicate the starting location in bytes of an ASF Data Packet + * relative to the start of the first ASF Data Packet in the file. + * + + * Any ASF file containing a Media Object Index Object shall also contain + * a Media Object Index Parameters Object in its + * {@link Zend_Media_Asf_Object_Header ASF Header}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_MediaObjectIndex extends Zend_Media_Asf_Object +{ + /** + * Indicates that the index type is Nearest Past Data Packet. The Nearest + * Past Data Packet indexes point to the data packet whose presentation time + * is closest to the index entry time. + */ + const NEAREST_PAST_DATA_PACKET = 1; + + /** + * Indicates that the index type is Nearest Past Media. The Nearest Past + * Object indexes point to the closest data packet containing an entire + * object or first fragment of an object. + */ + const NEAREST_PAST_MEDIA = 2; + + /** + * Indicates that the index type is Nearest Past Cleanpoint. The Nearest + * Past Cleanpoint indexes point to the closest data packet containing an + * entire object (or first fragment of an object) that has the Cleanpoint + * Flag set. + * + * Nearest Past Cleanpoint is the most common type of index. + */ + const NEAREST_PAST_CLEANPOINT = 3; + + /** @var integer */ + private $_indexEntryCountInterval; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** @var Array */ + private $_indexBlocks = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + $indexBlocksCount = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + for ($i = 0; $i < $indexBlocksCount; $i++) { + $indexEntryCount = $this->_reader->readUInt32LE(); + $blockPositions = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $blockPositions[] = $this->_reader->readInt64LE(); + } + $offsets = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $offsets[] = $this->_reader->readUInt32LE(); + } + $this->_indexBlocks[] = array + ('blockPositions' => $blockPositions, + 'indexEntryOffsets' => $offsets); + } + } + + /** + * Returns the interval between each index entry in number of media objects. + * + * @return integer + */ + public function getIndexEntryCountInterval() + { + return $this->_indexEntryCountInterval; + } + + /** + * Returns an array of index specifiers. Each entry consists of the + * following keys. + * + * o streamNumber -- Specifies the stream number that the Index + * Specifiers refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o blockPositions -- Specifies a list of byte offsets of the beginnings + * of the blocks relative to the beginning of the first Data Packet (for + * example, the beginning of the Data Object + 50 bytes). + * + * o indexEntryOffsets -- Specifies the offset. An offset value of + * 0xffffffff indicates an invalid offset value. + * + * @return Array + */ + public function getIndexBlocks() + { + return $this->_indexBlocks; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/MediaObjectIndexParameters.php b/src/Zend/Media/Asf/Object/MediaObjectIndexParameters.php new file mode 100644 index 0000000..1cf12ea --- /dev/null +++ b/src/Zend/Media/Asf/Object/MediaObjectIndexParameters.php @@ -0,0 +1,133 @@ +Media Object Index Parameters Object supplies information about + * those streams that actually indexed (there must be at least one stream in an + * index) by media objects. This object shall be present in the + * {@link Zend_Media_Asf_Object_Header Header Object} if there is a + * {@link Zend_Media_Asf_Object_MediaObjectIndex Media Object Index Object} + * present in the file. + * + * An Index Specifier is required for each stream that will be indexed by the + * {@link Zend_Media_Asf_Object_MediaObjectIndex Media Object Index Object}. + * These specifiers must exactly match those in the + * {@link Zend_Media_Asf_Object_MediaObjectIndex Media Object Index Object}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_MediaObjectIndexParameters + extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_indexEntryCountInterval; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + } + + /** + * Returns the interval between each index entry by the number of media + * objects. This value cannot be 0. + * + * @return integer + */ + public function getIndexEntryCountInterval() + { + return $this->_indexEntryCountInterval; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o streamNumber -- Specifies the stream number that the Index Specifiers + * refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. Values are defined as + * follows: + * 1 = Nearest Past Data Packet, + * 2 = Nearest Past Media Object, + * 3 = Nearest Past Cleanpoint, + * 0xff = Frame Number Offset. + * For a video stream, the Nearest Past Media Object and Nearest Past + * Data Packet indexes point to the closest data packet containing an + * entire video frame or first fragment of a video frame; Nearest Past + * Cleanpoint indexes point to the closest data packet containing an + * entire video frame (or first fragment of a video frame) that is a key + * frame; and Frame Number Offset indicates how many more frames need to + * be read for the given stream, starting with the first frame in the + * packet pointed to by the index entry, in order to get to the + * requested frame. Nearest Past Media Object is the most common value. + * Because ASF payloads do not contain the full frame number, there is + * often a Frame Number Offset index alongside one of the other types of + * indexes to allow the user to identify the exact frame being seeked + * to. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/Metadata.php b/src/Zend/Media/Asf/Object/Metadata.php new file mode 100644 index 0000000..f7144c8 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Metadata.php @@ -0,0 +1,218 @@ +Metadata Object permits authors to store stream-based metadata in + * a file. This object supports the same types of metadata information as the + * Extended Content Description Object except that it also allows a + * stream number to be specified. + * + * @todo Implement better handling of various types of attributes + * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Metadata extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_descriptionRecords = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $descriptionRecordsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $descriptionRecordsCount; $i++) { + $this->_reader->skip(2); + $descriptionRecord = + array('streamNumber' => $this->_reader->readUInt16LE()); + $nameLength = $this->_reader->readUInt16LE(); + $dataType = $this->_reader->readUInt16LE(); + $dataLength = $this->_reader->readUInt32LE(); + $descriptionRecord['name'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($nameLength)); + switch ($dataType) { + case 0: // Unicode string + $descriptionRecord['data'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($dataLength)); + break; + case 1: // BYTE array + $descriptionRecord['data'] = $this->_reader->read($dataLength); + break; + case 2: // BOOL + $descriptionRecord['data'] = $this->_reader->readUInt16LE() == 1; + break; + case 3: // DWORD + $descriptionRecord['data'] = $this->_reader->readUInt32LE(); + break; + case 4: // QWORD + $descriptionRecord['data'] = $this->_reader->readInt64LE(); + break; + case 5: // WORD + $descriptionRecord['data'] = $this->_reader->readUInt16LE(); + break; + default: + break; + } + $this->_descriptionRecords[] = $descriptionRecord; + } + } + + /** + * Returns the array of description records. Each record consists of the + * following keys. + * + * o streamNumber -- Specifies the stream number. Valid values are between + * 1 and 127. + * + * o name -- Specifies the name that uniquely identifies the attribute + * being described. Names are case-sensitive. + * + * o data -- Specifies the actual metadata being stored. + * + * @return Array + */ + public function getDescriptionRecords() + { + return $this->_descriptionRecords; + } + + /** + * Sets the array of description records. Each record must consist of the + * following keys. + * + * o streamNumber -- Specifies the stream number. Valid values are between + * 1 and 127. + * + * o name -- Specifies the name that uniquely identifies the attribute + * being described. Names are case-sensitive. + * + * o data -- Specifies the actual metadata being stored. + * + * @param Array $descriptionRecords The array of description records. + */ + public function setDescriptionRecords($descriptionRecords) + { + $this->_descriptionRecords = $descriptionRecords; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $descriptionRecordsCount = count($this->_descriptionRecords); + $descriptionRecordsWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $descriptionRecordsCount; $i++) { + $descriptionRecordsWriter + ->writeUInt16LE(0) + ->writeUInt16LE($this->_descriptionRecords[$i]['streamNumber']) + ->writeUInt16LE(strlen($name = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_descriptionRecords[$i]['name']) . "\0\0")); + if (is_string($this->_descriptionRecords[$i]['data'])) { + /* There is no way to distinguish byte arrays from unicode + * strings and hence the need for a list of fields of type byte + * array */ + static $byteArray = array ( + '' + ); // TODO: Add to the list if you encounter one + + if (in_array($name, $byteArray)) { + $descriptionRecordsWriter + ->writeUInt16LE(1) + ->writeUInt32LE + (strlen($this->_descriptionRecords[$i]['data'])) + ->write($name) + ->write($this->_descriptionRecords[$i]['data']); + } else { + $value = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_descriptionRecords[$i]['data']); + $value = ($value ? $value . "\0\0" : ''); + $descriptionRecordsWriter + ->writeUInt16LE(0) + ->writeUInt32LE(strlen($value)) + ->write($name) + ->writeString16($value); + } + } else if (is_bool($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(2) + ->writeUInt32LE(2) + ->write($name) + ->writeUInt16LE + ($this->_descriptionRecords[$i]['data'] ? 1 : 0); + } else if (is_int($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(3) + ->writeUInt32LE(4) + ->write($name) + ->writeUInt32LE($this->_descriptionRecords[$i]['data']); + } else if (is_float($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(4) + ->writeUInt32LE(8) + ->write($name) + ->writeInt64LE($this->_descriptionRecords[$i]['data']); + } else { + // Invalid value and there is nothing to be done + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Invalid data type'); + } + } + + $this->setSize + (24 /* for header */ + 2 + $descriptionRecordsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($descriptionRecordsCount) + ->write($descriptionRecordsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/MetadataLibrary.php b/src/Zend/Media/Asf/Object/MetadataLibrary.php new file mode 100644 index 0000000..2d06eec --- /dev/null +++ b/src/Zend/Media/Asf/Object/MetadataLibrary.php @@ -0,0 +1,256 @@ +Metadata Library Object lets authors store stream-based, + * language-attributed, multiply defined, and large metadata attributes in a + * file. + * + * This object supports the same types of metadata as the + * {@link Zend_Media_Asf_Object_Metadata Metadata Object}, as well as + * attributes with language IDs, attributes that are defined more than once, + * large attributes, and attributes with the GUID data type. + * + * @todo Implement better handling of various types of attributes + * according to http://msdn.microsoft.com/en-us/library/aa384495(VS.85).aspx + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_MetadataLibrary extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_descriptionRecords = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $descriptionRecordsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $descriptionRecordsCount; $i++) { + $descriptionRecord = array + ('languageIndex' => $this->_reader->readUInt16LE(), + 'streamNumber' => $this->_reader->readUInt16LE()); + $nameLength = $this->_reader->readUInt16LE(); + $dataType = $this->_reader->readUInt16LE(); + $dataLength = $this->_reader->readUInt32LE(); + $descriptionRecord['name'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($nameLength)); + switch ($dataType) { + case 0: // Unicode string + $descriptionRecord['data'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($dataLength)); + break; + case 1: // BYTE array + $descriptionRecord['data'] = + $this->_reader->read($dataLength); + break; + case 2: // BOOL + $descriptionRecord['data'] = + $this->_reader->readUInt16LE() == 1; + break; + case 3: // DWORD + $descriptionRecord['data'] = $this->_reader->readUInt32LE(); + break; + case 4: // QWORD + $descriptionRecord['data'] = $this->_reader->readInt64LE(); + break; + case 5: // WORD + $descriptionRecord['data'] = $this->_reader->readUInt16LE(); + break; + case 6: // GUID + $descriptionRecord['data'] = $this->_reader->readGuid(); + break; + default: + break; + } + $this->_descriptionRecords[] = $descriptionRecord; + } + } + + /** + * Returns an array of description records. Each record consists of the + * following keys. + * + * o languageIndex -- Specifies the index into the + * {@link LanguageList Language List Object} that identifies the + * language of this attribute. If there is no Language List + * Object present, this field is zero. + * + * o streamNumber -- Specifies whether the entry applies to a specific + * digital media stream or whether it applies to the whole file. A value + * of 0 in this field indicates that it applies to the whole file; + * otherwise, the entry applies only to the indicated stream number. + * Valid values are between 1 and 127. + * + * o name -- Specifies the name that identifies the attribute being + * described. + * + * o data -- Specifies the actual metadata being stored. + * + * @return Array + */ + public function getDescriptionRecords() + { + return $this->_descriptionRecords; + } + + /** + * Sets an array of description records. Each record must consist of the + * following keys. + * + * o languageIndex -- Specifies the index into the Language List + * Object that identifies the language of this attribute. If there + * is no Language List Object present, this field is zero. + * + * o streamNumber -- Specifies whether the entry applies to a specific + * digital media stream or whether it applies to the whole file. A value + * of 0 in this field indicates that it applies to the whole file; + * otherwise, the entry applies only to the indicated stream number. + * Valid values are between 1 and 127. + * + * o name -- Specifies the name that identifies the attribute being + * described. + * + * o data -- Specifies the actual metadata being stored. + * + * @return Array + */ + public function setDescriptionRecords($descriptionRecords) + { + $this->_descriptionRecords = $descriptionRecords; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $descriptionRecordsCount = count($this->_descriptionRecords); + $descriptionRecordsWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $descriptionRecordsCount; $i++) { + $descriptionRecordsWriter + ->writeUInt16LE + ($this->_descriptionRecords[$i]['languageIndex']) + ->writeUInt16LE + ($this->_descriptionRecords[$i]['streamNumber']) + ->writeUInt16LE(strlen($name = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_descriptionRecords[$i]['name']) . "\0\0")); + if (is_string($this->_descriptionRecords[$i]['data'])) { + $chunks = array(); + if (preg_match + ("/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{1" . + "2}$/i", $this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(6) + ->writeUInt32LE(16) + ->write($name) + ->writeGuid($this->_descriptionRecords[$i]['data']); + } else { + /* There is no way to distinguish byte arrays from unicode + * strings and hence the need for a list of fields of type + * byte array */ + static $byteArray = array ( + "W\0M\0/\0L\0y\0r\0i\0c\0s\0_\0S\0y\0n\0c\0h\0r\0o\0n\0i\0s\0e\0d\0\0\0", + "W\0M\0/\0P\0i\0c\0t\0u\0r\0e\0\0\0" + ); // TODO: Add to the list if you encounter one + + if (in_array($name, $byteArray)) { + $descriptionRecordsWriter + ->writeUInt16LE(1) + ->writeUInt32LE + (strlen($this->_descriptionRecords[$i]['data'])) + ->write($name) + ->write($this->_descriptionRecords[$i]['data']); + } else { + $value = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_descriptionRecords[$i]['data']); + $value = ($value ? $value . "\0\0" : ''); + $descriptionRecordsWriter + ->writeUInt16LE(0) + ->writeUInt32LE(strlen($value)) + ->write($name) + ->writeString16($value); + } + } + } else if (is_bool($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(2) + ->writeUInt32LE(2) + ->write($name) + ->writeUInt16LE + ($this->_descriptionRecords[$i]['data'] ? 1 : 0); + } else if (is_int($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(3) + ->writeUInt32LE(4) + ->write($name) + ->writeUInt32LE($this->_descriptionRecords[$i]['data']); + } else if (is_float($this->_descriptionRecords[$i]['data'])) { + $descriptionRecordsWriter + ->writeUInt16LE(4) + ->writeUInt32LE(8) + ->write($name) + ->writeInt64LE($this->_descriptionRecords[$i]['data']); + } else { + // Invalid value and there is nothing to be done + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Invalid data type'); + } + } + + $this->setSize + (24 /* for header */ + 2 + $descriptionRecordsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($descriptionRecordsCount) + ->write($descriptionRecordsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/Padding.php b/src/Zend/Media/Asf/Object/Padding.php new file mode 100644 index 0000000..85c47f7 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Padding.php @@ -0,0 +1,77 @@ +Padding Object is a dummy object that is used to pad the size of + * the Header Object. This object enables the size of any object stored + * in the Header Object to grow or shrink without having to rewrite the + * entire Data Object and Index Object sections of the ASF file. + * For instance, if entries in the Content Description Object or + * Extended Content Description Object need to be removed or shortened, + * the size of the Padding Object can be increased to compensate for the + * reduction in size of the Content Description Object. The ASF file can + * then be updated by overwriting the previous Header Object with the + * edited Header Object of identical size, without having to move or + * rewrite the data contained in the Data Object. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Padding extends Zend_Media_Asf_Object +{ + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + if ($this->getSize() == 0) { + $this->setSize(24); + } + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->write(str_pad('', $this->getSize() - 24 /* header */, "\0")); + } +} diff --git a/src/Zend/Media/Asf/Object/ScriptCommand.php b/src/Zend/Media/Asf/Object/ScriptCommand.php new file mode 100644 index 0000000..7496351 --- /dev/null +++ b/src/Zend/Media/Asf/Object/ScriptCommand.php @@ -0,0 +1,183 @@ +Script Command Object provides a list of type/parameter pairs of + * strings that are synchronized to the ASF file's timeline. Types can include + * URL or FILENAME values. Other type values may also be freely defined and + * used. The semantics and treatment of this set of types are defined by the + * local implementations. The parameter value is specific to the type field. You + * can use this type/parameter pairing for many purposes, including sending URLs + * to be launched by a client into an HTML frame (in other words, the URL type) + * or launching another ASF file for the chained continuous play of audio or + * video presentations (in other words, the FILENAME type). This object is also + * used as a method to stream text, as well as to provide script commands that + * you can use to control elements within the client environment. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_ScriptCommand extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_reserved; + + /** @var Array */ + private $_commands = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_reserved = $this->_reader->readGuid(); + $commandsCount = $this->_reader->readUInt16LE(); + $commandTypesCount = $this->_reader->readUInt16LE(); + $commandTypes = array(); + for ($i = 0; $i < $commandTypesCount; $i++) { + $commandTypeNameLength = $this->_reader->readUInt16LE(); + $commandTypes[] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($commandTypeNameLength * 2)); + } + for ($i = 0; $i < $commandsCount; $i++) { + $command = array + ('presentationTime' => $this->_reader->readUInt32LE(), + 'type' => $commandTypes[$this->_reader->readUInt16LE()]); + $commandNameLength = $this->_reader->readUInt16LE(); + $command['name'] = iconv + ('utf-16le', $this->getOption('encoding'), + $this->_reader->readString16($commandNameLength * 2)); + $this->_commands[] = $command; + } + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o presentationTime -- Specifies the presentation time of the command, + * in milliseconds. + * + * o type -- Specifies the type of this command. + * + * o name -- Specifies the name of this command. + * + * @return Array + */ + public function getCommands() + { + return $this->_commands; + } + + /** + * Sets the array of index entries. Each entry is to consist of the + * following keys. + * + * o presentationTime -- Specifies the presentation time of the command, + * in milliseconds. + * + * o type -- Specifies the type of this command. + * + * o name -- Specifies the name of this command. + * + * @param Array $commands The array of index entries. + */ + public function setCommands($commands) + { + $this->_commands = $commands; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + + $commandTypes = array(); + foreach ($this->_commands as $command) { + if (!in_array($command['type'], $commandTypes)) { + $commandTypes[] = $command['type']; + } + } + + $commandTypesCount = count($commandTypes); + $commandTypesWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $commandTypesCount; $i++) { + $commandTypesWriter + ->writeUInt16LE + (strlen($commandType = iconv + ($this->getOption('encoding'), 'utf-16le', + $commandTypes[$i])) / 2) + ->write($commandType); + } + + $commandsCount = count($this->_commands); + $commandsWriter = new Zend_Io_StringWriter(); + for ($i = 0; $i < $commandsCount; $i++) { + $commandsWriter + ->writeUInt32LE($this->_commands[$i]['presentationTime']) + ->writeUInt16LE + (array_search($this->_commands[$i]['type'], $commandTypes)) + ->writeUInt16LE + (strlen($command = iconv + ($this->getOption('encoding'), 'utf-16le', + $this->_commands[$i]['name'])) / 2) + ->write($command); + } + + $this->setSize + (24 /* for header */ + 20 + $commandTypesWriter->getSize() + + $commandsWriter->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_reserved) + ->writeUInt16LE($commandsCount) + ->writeUInt16LE($commandTypesCount) + ->write($commandTypesWriter->toString()) + ->write($commandsWriter->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/SimpleIndex.php b/src/Zend/Media/Asf/Object/SimpleIndex.php new file mode 100644 index 0000000..b936634 --- /dev/null +++ b/src/Zend/Media/Asf/Object/SimpleIndex.php @@ -0,0 +1,150 @@ +Simple Index Object. Additionally, the instances of the Simple + * Index Object shall be ordered by stream number. + * + * Index entries in the Simple Index Object are in terms of + * Presentation Times. The corresponding Packet Number field + * values (of the Index Entry, see below) indicate the packet number of + * the ASF Data Packet with the closest past key frame. Note that for + * video streams that contain both key frames and non-key frames, the Packet + * Number field will always point to the closest past key frame. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_SimpleIndex extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_fileId; + + /** @var integer */ + private $_indexEntryTimeInterval; + + /** @var integer */ + private $_maximumPacketCount; + + /** @var Array */ + private $_indexEntries = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_fileId = $this->_reader->readGuid(); + $this->_indexEntryTimeInterval = $this->_reader->readInt64LE(); + $this->_maximumPacketCount = $this->_reader->readUInt32LE(); + $indexEntriesCount = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $indexEntriesCount; $i++) { + $this->_indexEntries[] = array + ('packetNumber' => $this->_reader->readUInt32LE(), + 'packetCount' => $this->_reader->readUInt16LE()); + } + } + + /** + * Returns the unique identifier for this ASF file. The value of this field + * should be changed every time the file is modified in any way. The value + * of this field may be set to 0 or set to be identical to the value of the + * File ID field of the Data Object and the Header + * Object. + * + * @return string + */ + public function getFileId() + { + return $this->_fileId; + } + + /** + * Returns the time interval between each index entry in 100-nanosecond units. + * The most common value is 10000000, to indicate that the index entries are + * in 1-second intervals, though other values can be used as well. + * + * @return integer + */ + public function getIndexEntryTimeInterval() + { + return $this->_indexEntryTimeInterval; + } + + /** + * Returns the maximum Packet Count value of all Index Entries. + * + * @return integer + */ + public function getMaximumPacketCount() + { + return $this->_maximumPacketCount; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o packetNumber -- Specifies the number of the Data Packet associated + * with this index entry. Note that for video streams that contain both + * key frames and non-key frames, this field will always point to the + * closest key frame prior to the time interval. + * + * o packetCount -- Specifies the number of Data Packets to send at + * this index entry. If a video key frame has been fragmented into two + * Data Packets, the value of this field will be equal to 2. + * + * @return Array + */ + public function getIndexEntries() + { + return $this->_indexEntries; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/StreamBitrateProperties.php b/src/Zend/Media/Asf/Object/StreamBitrateProperties.php new file mode 100644 index 0000000..2e3046f --- /dev/null +++ b/src/Zend/Media/Asf/Object/StreamBitrateProperties.php @@ -0,0 +1,134 @@ +Stream Bitrate Properties Object defines the average bit rate of + * each digital media stream. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_StreamBitrateProperties + extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_bitrateRecords = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $bitrateRecordsCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $bitrateRecordsCount; $i++) { + $this->_bitrateRecords[] = array + ('streamNumber' => + ($tmp = $this->_reader->readInt16LE()) & 0x1f, + 'flags' => $tmp >> 5, + 'averageBitrate' => $this->_reader->readUInt32LE()); + } + } + + /** + * Returns an array of bitrate records. Each record consists of the + * following keys. + * + * o streamNumber -- Specifies the number of this stream described by this + * record. 0 is an invalid stream. Valid values are between 1 and 127. + * + * o flags -- These bits are reserved and should be set to 0. + * + * o averageBitrate -- Specifies the average bit rate of the stream in + * bits per second. This value should include an estimate of ASF packet + * and payload overhead associated with this stream. + * + * @return Array + */ + public function getBitrateRecords() + { + return $this->_bitrateRecords; + } + + /** + * Sets an array of bitrate records. Each record consists of the following + * keys. + * + * o streamNumber -- Specifies the number of this stream described by this + * record. 0 is an invalid stream. Valid values are between 1 and 127. + * + * o flags -- These bits are reserved and should be set to 0. + * + * o averageBitrate -- Specifies the average bit rate of the stream in bits + * per second. This value should include an estimate of ASF packet and + * payload overhead associated with this stream. + * + * @param Array $bitrateRecords The array of bitrate records. + */ + public function setBitrateRecords($bitrateRecords) + { + $this->_bitrateRecords = $bitrateRecords; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $bitrateRecordsCount = count($this->_bitrateRecords); + + $this->setSize + (24 /* for header */ + 2 + $bitrateRecordsCount * 6); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($bitrateRecordsCount); + for ($i = 0; $i < $bitrateRecordsCount; $i++) { + $writer->writeUInt16LE + (($this->_bitrateRecords[$i]['flags'] << 5) | + ($this->_bitrateRecords[$i]['streamNumber'] & 0x1f)) + ->writeUInt32LE + ($this->_bitrateRecords[$i]['averageBitrate']); + } + } +} diff --git a/src/Zend/Media/Asf/Object/StreamPrioritization.php b/src/Zend/Media/Asf/Object/StreamPrioritization.php new file mode 100644 index 0000000..bf7c1f2 --- /dev/null +++ b/src/Zend/Media/Asf/Object/StreamPrioritization.php @@ -0,0 +1,132 @@ +Stream Prioritization Object indicates the author's intentions as + * to which streams should or should not be dropped in response to varying + * network congestion situations. There may be special cases where this + * preferential order may be ignored (for example, the user hits the 'mute' + * button). Generally it is expected that implementations will try to honor the + * author's preference. + * + * The priority of each stream is indicated by how early in the list that + * stream's stream number is listed (in other words, the list is ordered in + * terms of decreasing priority). + * + * The Mandatory flag field shall be set if the author wants that stream kept + * 'regardless'. If this flag is not set, then that indicates that the stream + * should be dropped in response to network congestion situations. Non-mandatory + * streams must never be assigned a higher priority than mandatory streams. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_StreamPrioritization + extends Zend_Media_Asf_Object +{ + /** @var Array */ + private $_priorityRecords = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $priorityRecordCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $priorityRecordCount; $i++) { + $this->_priorityRecords[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'flags' => $this->_reader->readUInt16LE()); + } + } + + /** + * Returns an array of records. Each record consists of the following keys. + * + * o streamNumber -- Specifies the stream number. Valid values are between + * 1 and 127. + * + * o flags -- Specifies the flags. The mandatory flag is the bit 1 (LSB). + * + * @return Array + */ + public function getPriorityRecords() + { + return $this->_priorityRecords; + } + + /** + * Sets the array of records. Each record consists of the following keys. + * + * o streamNumber -- Specifies the stream number. Valid values are between + * 1 and 127. + * + * o flags -- Specifies the flags. The mandatory flag is the bit 1 (LSB). + * + * @param Array $priorityRecords The array of records. + */ + public function setPriorityRecords($priorityRecords) + { + $this->_priorityRecords = $priorityRecords; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $priorityRecordCount = count($this->_priorityRecords); + + $this->setSize + (24 /* for header */ + 2 + $priorityRecordCount * 4); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeUInt16LE($priorityRecordCount); + for ($i = 0; $i < $priorityRecordCount; $i++) { + $writer->writeUInt16LE($this->_priorityRecords[$i]['streamNumber']) + ->writeUInt16LE($this->_priorityRecords[$i]['flags']); + } + } +} diff --git a/src/Zend/Media/Asf/Object/StreamProperties.php b/src/Zend/Media/Asf/Object/StreamProperties.php new file mode 100644 index 0000000..b341efa --- /dev/null +++ b/src/Zend/Media/Asf/Object/StreamProperties.php @@ -0,0 +1,534 @@ +Stream Properties Object defines the specific properties and + * characteristics of a digital media stream. This object defines how a digital + * media stream within the Data Object is interpreted, as well as the + * specific format (of elements) of the Data Packet itself. + * + * Whereas every stream in an ASF presentation, including each stream in a + * mutual exclusion relationship, must be represented by a Stream Properties + * Object, in certain cases, this object might be found embedded in the + * Extended Stream Properties Object. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_StreamProperties extends Zend_Media_Asf_Object +{ + /** + * Indicates, if set, that the data contained in this stream is encrypted + * and will be unreadable unless there is a way to decrypt the stream. + */ + const ENCRYPTED_CONTENT = 0x8000; + + const AUDIO_MEDIA = 'f8699e40-5b4d-11cf-a8fd-00805f5c442b'; + const VIDEO_MEDIA = 'bc19efc0-5b4d-11cf-a8fd-00805f5c442b'; + const COMMAND_MEDIA = '59dacfc0-59e6-11d0-a3ac-00a0c90348f6'; + const JFIF_MEDIA = 'b61be100-5b4e-11cf-a8fD-00805f5c442b'; + const DEGRADABLE_JPEG_MEDIA = '35907dE0-e415-11cf-a917-00805f5c442b'; + const FILE_TRANSFER_MEDIA = '91bd222c-f21c-497a-8b6d-5aa86bfc0185'; + const BINARY_MEDIA = '3afb65e2-47ef-40f2-ac2c-70a90d71d343'; + + const NO_ERROR_CORRECTION = '20fb5700-5b55-11cf-a8fd-00805f5c442b'; + const AUDIO_SPREAD = 'bfc3cd50-618f-11cf-8bb2-00aa00b4e220'; + + /** @var string */ + private $_streamType; + + /** @var string */ + private $_errorCorrectionType; + + /** @var integer */ + private $_timeOffset; + + /** @var integer */ + private $_flags; + + /** @var integer */ + private $_reserved; + + /** @var Array */ + private $_typeSpecificData = array(); + + /** @var Array */ + private $_errorCorrectionData = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_streamType = $this->_reader->readGuid(); + $this->_errorCorrectionType = $this->_reader->readGuid(); + $this->_timeOffset = $this->_reader->readInt64LE(); + $typeSpecificDataLength = $this->_reader->readUInt32LE(); + $errorCorrectionDataLength = $this->_reader->readUInt32LE(); + $this->_flags = $this->_reader->readUInt16LE(); + $this->_reserved = $this->_reader->readUInt32LE(); + + switch ($this->_streamType) { + case self::AUDIO_MEDIA: + $this->_typeSpecificData = array + ('codecId' => $this->_reader->readUInt16LE(), + 'numberOfChannels' => $this->_reader->readUInt16LE(), + 'samplesPerSecond' => $this->_reader->readUInt32LE(), + 'avgNumBytesPerSecond' => $this->_reader->readUInt32LE(), + 'blockAlignment' => $this->_reader->readUInt16LE(), + 'bitsPerSample' => $this->_reader->readUInt16LE()); + $codecSpecificDataSize = $this->_reader->readUInt16LE(); + $this->_typeSpecificData['codecSpecificData'] = + $this->_reader->read($codecSpecificDataSize); + break; + case self::VIDEO_MEDIA: + $this->_typeSpecificData = array + ('encodedImageWidth' => $this->_reader->readUInt32LE(), + 'encodedImageHeight' => $this->_reader->readUInt32LE(), + 'reservedFlags' => $this->_reader->readInt8()); + $this->_reader->skip(2); + $formatDataSize = $this->_reader->readUInt32LE(); + $this->_typeSpecificData = array_merge + ($this->_typeSpecificData, array + ('imageWidth' => $this->_reader->readUInt32LE(), + 'imageHeight' => $this->_reader->readUInt32LE(), + 'reserved' => $this->_reader->readUInt16LE(), + 'bitsPerPixelCount' => $this->_reader->readUInt16LE(), + 'compressionId' => $this->_reader->readUInt32LE(), + 'imageSize' => $this->_reader->readUInt32LE(), + 'horizontalPixelsPerMeter' => + $this->_reader->readUInt32LE(), + 'verticalPixelsPerMeter' => + $this->_reader->readUInt32LE(), + 'colorsUsedCount' => $this->_reader->readUInt32LE(), + 'importantColorsCount' => $this->_reader->readUInt32LE(), + 'codecSpecificData' => + $this->_reader->read($formatDataSize - 38))); + break; + case self::JFIF_MEDIA: + $this->_typeSpecificData = array + ('imageWidth' => $this->_reader->readUInt32LE(), + 'imageHeight' => $this->_reader->readUInt32LE(), + 'reserved' => $this->_reader->readUInt32LE()); + break; + case self::DEGRADABLE_JPEG_MEDIA: + $this->_typeSpecificData = array + ('imageWidth' => $this->_reader->readUInt32LE(), + 'imageHeight' => $this->_reader->readUInt32LE(), + $this->_reader->readUInt16LE(), + $this->_reader->readUInt16LE(), + $this->_reader->readUInt16LE()); + $interchangeDataSize = $this->_reader->readUInt16LE(); + if ($interchangeDataSize == 0) { + $interchangeDataSize++; + } + $this->_typeSpecificData['interchangeData'] = + $this->_reader->read($interchangeDataSize); + break; + case self::FILE_TRANSFER_MEDIA: + // break intentionally omitted + case self::BINARY_MEDIA: + $this->_typeSpecificData = array + ('majorMediaType' => $this->_reader->getGUID(), + 'mediaSubtype' => $this->_reader->getGUID(), + 'fixedSizeSamples' => $this->_reader->readUInt32LE(), + 'temporalCompression' => $this->_reader->readUInt32LE(), + 'sampleSize' => $this->_reader->readUInt32LE(), + 'formatType' => $this->_reader->getGUID()); + $formatDataSize = $this->_reader->readUInt32LE(); + $this->_typeSpecificData['formatData'] = + $this->_reader->read($formatDataSize); + break; + case self::COMMAND_MEDIA: + // break intentionally omitted + default: + $this->_reader->skip($typeSpecificDataLength); + break; + } + switch ($this->_errorCorrectionType) { + case self::AUDIO_SPREAD: + $this->_errorCorrectionData = array + ('span' => $this->_reader->readInt8(), + 'virtualPacketLength' => $this->_reader->readUInt16LE(), + 'virtualChunkLength' => $this->_reader->readUInt16LE()); + $silenceDataSize = $this->_reader->readUInt16LE(); + $this->_errorCorrectionData['silenceData'] = + $this->_reader->read($silenceDataSize); + break; + case self::NO_ERROR_CORRECTION: + // break intentionally omitted + default: + $this->_reader->skip($errorCorrectionDataLength); + break; + } + } + + /** + * Returns the number of this stream. 0 is an invalid stream. Valid values + * are between 1 and 127. The numbers assigned to streams in an ASF + * presentation may be any combination of unique values; parsing logic must + * not assume that streams are numbered sequentially. + * + * @return integer + */ + public function getStreamNumber() + { + return $this->_flags & 0x3f; + } + + /** + * Returns the number of this stream. 0 is an invalid stream. Valid values + * are between 1 and 127. The numbers assigned to streams in an ASF + * presentation may be any combination of unique values; parsing logic must + * not assume that streams are numbered sequentially. + * + * @param integer $streamNumber The number of this stream. + */ + public function setStreamNumber($streamNumber) + { + if ($streamNumber < 1 || $streamNumber > 127) { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Invalid argument'); + } + $this->_flags = ($this->_flags & 0xffc0) | ($streamNumber & 0x3f); + } + + /** + * Returns the type of the stream (for example, audio, video, and so on). + * + * @return string + */ + public function getStreamType() + { + return $this->_streamType; + } + + /** + * Sets the type of the stream (for example, audio, video, and so on). + * + * @param integer $streamType The type of the stream. + */ + public function setStreamType($streamType) + { + $this->_streamType = $streamType; + } + + /** + * Returns the error correction type used by this digital media stream. For + * streams other than audio, this value should be set to + * NO_ERROR_CORRECTION. For audio streams, this value should be set to + * AUDIO_SPREAD. + * + * @return string + */ + public function getErrorCorrectionType() + { + return $this->_errorCorrectionType; + } + + /** + * Sets the error correction type used by this digital media stream. For + * streams other than audio, this value should be set to + * NO_ERROR_CORRECTION. For audio streams, this value should be set to + * AUDIO_SPREAD. + * + * @param integer $errorCorrectionType The error correction type used by + * this digital media stream. + */ + public function setErrorCorrectionType($errorCorrectionType) + { + $this->_errorCorrectionType = $errorCorrectionType; + } + + /** + * Returns the presentation time offset of the stream in 100-nanosecond + * units. The value of this field is added to all of the timestamps of the + * samples in the stream. This value shall be equal to the send time of the + * first interleaved packet in the data section. The value of this field is + * typically 0. It is non-zero in the case when an ASF file is edited and it + * is not possible for the editor to change the presentation times and send + * times of ASF packets. Note that if more than one stream is present in an + * ASF file the offset values of all stream properties objects must be + * equal. + * + * @return integer + */ + public function getTimeOffset() + { + return $this->_timeOffset; + } + + /** + * Sets the presentation time offset of the stream in 100-nanosecond units. + * The value of this field is added to all of the timestamps of the samples + * in the stream. This value shall be equal to the send time of the first + * interleaved packet in the data section. The value of this field is + * typically 0. It is non-zero in the case when an ASF file is edited and it + * is not possible for the editor to change the presentation times and send + * times of ASF packets. Note that if more than one stream is present in an + * ASF file the offset values of all stream properties objects must be + * equal. + * + * @param integer $timeOffset The presentation time offset of the stream. + */ + public function setTimeOffset($timeOffset) + { + $this->_timeOffset = $timeOffset; + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the flags field. + * + * @return integer + */ + public function getFlags() + { + return $this->_flags; + } + + /** + * Sets the flags field. + * + * @param integer $flags The flags field. + */ + public function setFlags($flags) + { + $this->_flags = $flags; + } + + /** + * Returns type-specific format data. The structure for the Type-Specific + * Data field is determined by the value stored in the Stream + * Type field. + * + * The type-specific data is returned as key-value pairs of an associate + * array. + * + * @return Array + */ + public function getTypeSpecificData() + { + return $this->_typeSpecificData; + } + + /** + * Sets type-specific format data. The structure for the Type-Specific + * Data field is determined by the value stored in the Stream Type + * field. + * + * @param Array $typeSpecificData The type-specific data as key-value pairs + * of an associate array. + */ + public function setTypeSpecificData($typeSpecificData) + { + $this->_typeSpecificData = $typeSpecificData; + } + + /** + * Returns data specific to the error correction type. The structure for the + * Error Correction Data field is determined by the value stored in + * the Error Correction Type field. For example, an audio data stream + * might need to know how codec chunks were redistributed, or it might need + * a sample of encoded silence. + * + * The error correction type-specific data is returned as key-value pairs of + * an associate array. + * + * @return integer + */ + public function getErrorCorrectionData() + { + return $this->_errorCorrectionData; + } + + /** + * Sets data specific to the error correction type. The structure for the + * Error Correction Data field is determined by the value stored in + * the Error Correction Type field. For example, an audio data stream + * might need to know how codec chunks were redistributed, or it might need + * a sample of encoded silence. + * + * @param Array $errorCorrectionData The error correction type-specific data + * as key-value pairs of an associate array. + */ + public function setErrorCorrectionData($errorCorrectionData) + { + $this->_errorCorrectionData = $errorCorrectionData; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Io/StringWriter.php'; + $typeSpecificData = new Zend_Io_StringWriter(); + switch ($this->_streamType) { + case self::AUDIO_MEDIA: + $typeSpecificData + ->writeUInt16LE($this->_typeSpecificData['codecId']) + ->writeUInt16LE + ($this->_typeSpecificData['numberOfChannels']) + ->writeUInt32LE + ($this->_typeSpecificData['samplesPerSecond']) + ->writeUInt32LE + ($this->_typeSpecificData['avgNumBytesPerSecond']) + ->writeUInt16LE($this->_typeSpecificData['blockAlignment']) + ->writeUInt16LE($this->_typeSpecificData['bitsPerSample']) + ->writeUInt16LE + (strlen($this->_typeSpecificData['codecSpecificData'])) + ->write($this->_typeSpecificData['codecSpecificData']); + break; + case self::VIDEO_MEDIA: + $typeSpecificData + ->writeUInt32LE + ($this->_typeSpecificData['encodedImageWidth']) + ->writeUInt32LE + ($this->_typeSpecificData['encodedImageHeight']) + ->writeInt8($this->_typeSpecificData['reservedFlags']) + ->writeUInt16LE(0) // Reserved + ->writeUInt32LE + (38 + + strlen($this->_typeSpecificData['codecSpecificData'])) + ->writeUInt32LE($this->_typeSpecificData['imageWidth']) + ->writeUInt32LE($this->_typeSpecificData['imageHeight']) + ->writeUInt16LE($this->_typeSpecificData['reserved']) + ->writeUInt16LE + ($this->_typeSpecificData['bitsPerPixelCount']) + ->writeUInt32LE($this->_typeSpecificData['compressionId']) + ->writeUInt32LE($this->_typeSpecificData['imageSize']) + ->writeUInt32LE + ($this->_typeSpecificData['horizontalPixelsPerMeter']) + ->writeUInt32LE + ($this->_typeSpecificData['verticalPixelsPerMeter']) + ->writeUInt32LE($this->_typeSpecificData['colorsUsedCount']) + ->writeUInt32LE + ($this->_typeSpecificData['importantColorsCount']) + ->write($this->_typeSpecificData['codecSpecificData']); + break; + case self::JFIF_MEDIA: + $typeSpecificData + ->writeUInt32LE($this->_typeSpecificData['imageWidth']) + ->writeUInt32LE($this->_typeSpecificData['imageHeight']) + ->writeUInt32LE(0); + break; + case self::DEGRADABLE_JPEG_MEDIA: + $typeSpecificData + ->writeUInt32LE($this->_typeSpecificData['imageWidth']) + ->writeUInt32LE($this->_typeSpecificData['imageHeight']) + ->writeUInt16LE(0) + ->writeUInt16LE(0) + ->writeUInt16LE(0); + $interchangeDataSize = strlen + ($this->_typeSpecificData['interchangeData']); + if ($interchangeDataSize == 1) + $interchangeDataSize = 0; + $typeSpecificData + ->writeUInt16LE($interchangeDataSize) + ->write($this->_typeSpecificData['interchangeData']); + break; + case self::FILE_TRANSFER_MEDIA: + // break intentionally omitted + case self::BINARY_MEDIA: + $typeSpecificData + ->writeGuid($this->_typeSpecificData['majorMediaType']) + ->writeGuid($this->_typeSpecificData['mediaSubtype']) + ->writeUInt32LE($this->_typeSpecificData['fixedSizeSamples']) + ->writeUInt32LE + ($this->_typeSpecificData['temporalCompression']) + ->writeUInt32LE($this->_typeSpecificData['sampleSize']) + ->writeGuid($this->_typeSpecificData['formatType']) + ->writeUInt32LE(strlen($this->_typeSpecificData['formatData'])) + ->write($this->_typeSpecificData['formatData']); + break; + case self::COMMAND_MEDIA: + // break intentionally omitted + default: + break; + } + + $errorCorrectionData = new Zend_Io_StringWriter(); + switch ($this->_errorCorrectionType) { + case self::AUDIO_SPREAD: + $errorCorrectionData + ->writeInt8($this->_errorCorrectionData['span']) + ->writeUInt16LE + ($this->_errorCorrectionData['virtualPacketLength']) + ->writeUInt16LE + ($this->_errorCorrectionData['virtualChunkLength']) + ->writeUInt16LE + (strlen($this->_errorCorrectionData['silenceData'])) + ->write($this->_errorCorrectionData['silenceData']); + break; + case self::NO_ERROR_CORRECTION: + // break intentionally omitted + default: + break; + } + + $this->setSize + (24 /* for header */ + 54 + $typeSpecificData->getSize() + + $errorCorrectionData->getSize()); + + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->writeGuid($this->_streamType) + ->writeGuid($this->_errorCorrectionType) + ->writeInt64LE($this->_timeOffset) + ->writeUInt32LE($typeSpecificData->getSize()) + ->writeUInt32LE($errorCorrectionData->getSize()) + ->writeUInt16LE($this->_flags) + ->writeUInt32LE($this->_reserved) + ->write($typeSpecificData->toString()) + ->write($errorCorrectionData->toString()); + } +} diff --git a/src/Zend/Media/Asf/Object/TimecodeIndex.php b/src/Zend/Media/Asf/Object/TimecodeIndex.php new file mode 100644 index 0000000..6e15e23 --- /dev/null +++ b/src/Zend/Media/Asf/Object/TimecodeIndex.php @@ -0,0 +1,189 @@ +Timecode Index Object + * is used, it is recommended that timecodes be stored as a Payload Extension + * System on the appropriate stream. It is also recommended that every + * timecode appearing in the ASF file have a corresponging index entry. + * + * The index is designed to be broken into blocks to facilitate storage that is + * more space-efficient by using 32-bit offsets relative to a 64-bit base. That + * is, each index block has a full 64-bit offset in the block header that is + * added to the 32-bit offsets found in each index entry. If a file is larger + * than 2^32 bytes, then multiple index blocks can be used to fully index the + * entire large file while still keeping index entry offsets at 32 bits. + * + * To locate an object with a particular timecode in an ASF file, one would + * typically look through the Timecode Index Object in blocks of the + * appropriate range and try to locate the nearest possible timecode. The + * corresponding Offset field values of the Index Entry are byte + * offsets that, when combined with the Block Position value of the Index + * Block, indicate the starting location in bytes of an ASF Data Packet relative + * to the start of the first ASF Data Packet in the file. + * + * Any ASF file containing a Timecode Index Object shall also contain a + * Timecode Index Parameters Object in its + * {@link Zend_Media_Asf_Object_Header ASF Header}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_TimecodeIndex extends Zend_Media_Asf_Object +{ + /** + * Indicates that the index type is Nearest Past Data Packet. The Nearest + * Past Data Packet indexes point to the data packet whose presentation time + * is closest to the index entry time. + */ + const NEAREST_PAST_DATA_PACKET = 1; + + /** + * Indicates that the index type is Nearest Past Media. The Nearest Past + * Object indexes point to the closest data packet containing an entire + * object or first fragment of an object. + */ + const NEAREST_PAST_MEDIA = 2; + + /** + * Indicates that the index type is Nearest Past Cleanpoint. The Nearest + * Past Cleanpoint indexes point to the closest data packet containing an + * entire object (or first fragment of an object) that has the Cleanpoint + * Flag set. + * + * Nearest Past Cleanpoint is the most common type of index. + */ + const NEAREST_PAST_CLEANPOINT = 3; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** @var Array */ + private $_indexBlocks = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_reader->skip(4); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + $indexBlocksCount = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + for ($i = 0; $i < $indexBlocksCount; $i++) { + $indexEntryCount = $this->_reader->readUInt32LE(); + $timecodeRange = $this->_reader->readUInt16LE(); + $blockPositions = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $blockPositions[] = $this->_reader->readInt64LE(); + } + $indexEntries = array(); + for ($i = 0; $i < $indexEntryCount; $i++) { + $timecode = $this->_reader->readUInt32LE(); + $offsets = array(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $offsets[] = $this->_reader->readUInt32LE(); + } + $indexEntries[] = array + ('timecode' => $timecode, + 'offsets' => $offsets); + } + $this->_indexBlocks[] = array + ('timecodeRange' => $timecodeRange, + 'blockPositions' => $blockPositions, + 'indexEntries' => $indexEntries); + } + } + + /** + * Returns an array of index specifiers. Each entry consists of the + * following keys. + * + * o streamNumber -- Specifies the stream number that the Index + * Specifiers refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o timecodeRange -- Specifies the timecode range for this block. + * Subsequent blocks must contain range numbers greater than or equal to + * this one. + * + * o blockPositions -- Specifies a list of byte offsets of the beginnings + * of the blocks relative to the beginning of the first Data Packet (for + * example, the beginning of the Data Object + 50 bytes). + * + * o indexEntries -- An array that consists of the following keys + * o timecode -- This is the 4-byte timecode for these entries. + * o offsets -- Specifies the offset. An offset value of 0xffffffff + * indicates an invalid offset value. + * + * @return Array + */ + public function getIndexBlocks() + { + return $this->_indexBlocks; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/TimecodeIndexParameters.php b/src/Zend/Media/Asf/Object/TimecodeIndexParameters.php new file mode 100644 index 0000000..f74c17c --- /dev/null +++ b/src/Zend/Media/Asf/Object/TimecodeIndexParameters.php @@ -0,0 +1,129 @@ +Timecode Index Parameters Object supplies information about those + * streams that are actually indexed (there must be at least one stream in an + * index) by timecodes. All streams referred to in the + * {@link Zend_Media_Asf_Object_TimecodeIndexParameters Timecode Index + * Parameters Object} must have timecode Payload Extension Systems associated + * with them in the + * {@link Zend_Media_Asf_Object_ExtendedStreamProperties Extended Stream + * Properties Object}. This object shall be present in the + * {@link Zend_Media_Asf_Object_Header Header Object} if there is a + * {@link Zend_Media_Asf_Object_TimecodeIndex Timecode Index Object} present in + * the file. + * + * An Index Specifier is required for each stream that will be indexed by the + * {@link Zend_Media_Asf_Object_TimecodeIndex Timecode Index Object}. These + * specifiers must exactly match those in the + * {@link Zend_Media_Asf_Object_TimecodeIndex Timecode Index Object}. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_TimecodeIndexParameters + extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_indexEntryCountInterval; + + /** @var Array */ + private $_indexSpecifiers = array(); + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_indexEntryCountInterval = $this->_reader->readUInt32LE(); + $indexSpecifiersCount = $this->_reader->readUInt16LE(); + for ($i = 0; $i < $indexSpecifiersCount; $i++) { + $this->_indexSpecifiers[] = array + ('streamNumber' => $this->_reader->readUInt16LE(), + 'indexType' => $this->_reader->readUInt16LE()); + } + } + + /** + * Returns the interval between each index entry by the number of media + * objects. This value cannot be 0. + * + * @return integer + */ + public function getIndexEntryCountInterval() + { + return $this->_indexEntryCountInterval; + } + + /** + * Returns an array of index entries. Each entry consists of the following + * keys. + * + * o streamNumber -- Specifies the stream number that the Index Specifiers + * refer to. Valid values are between 1 and 127. + * + * o indexType -- Specifies the type of index. Values are defined as + * follows: + * 2 = Nearest Past Media Object, + * 3 = Nearest Past Cleanpoint (1 is not a valid value). + * For a video stream, The Nearest Past Media Object indexes point to + * the closest data packet containing an entire video frame or the first + * fragment of a video frame, and the Nearest Past Cleanpoint indexes + * point to the closest data packet containing an entire video frame (or + * first fragment of a video frame) that is a key frame. Nearest Past + * Media Object is the most common value. + * + * @return Array + */ + public function getIndexSpecifiers() + { + return $this->_indexSpecifiers; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + require_once 'Zend/Media/Asf/Exception.php'; + throw new Zend_Media_Asf_Exception('Operation not supported'); + } +} diff --git a/src/Zend/Media/Asf/Object/Unknown.php b/src/Zend/Media/Asf/Object/Unknown.php new file mode 100644 index 0000000..a544b87 --- /dev/null +++ b/src/Zend/Media/Asf/Object/Unknown.php @@ -0,0 +1,71 @@ +Unknown Object represents objects that are not known to the + * library. + * + * @category Zend + * @package Zend_Media + * @subpackage ASF + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Asf_Object_Unknown extends Zend_Media_Asf_Object +{ + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and reads object related data + * from the ASF file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_data = $this->_reader->read + ($this->getSize() - 24 /* for header */); + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $writer->writeGuid($this->getIdentifier()) + ->writeInt64LE($this->getSize()) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Exception.php b/src/Zend/Media/Exception.php new file mode 100644 index 0000000..bb68741 --- /dev/null +++ b/src/Zend/Media/Exception.php @@ -0,0 +1,39 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Exception extends Zend_Exception +{} diff --git a/src/Zend/Media/Id3/DateFrame.php b/src/Zend/Media/Id3/DateFrame.php new file mode 100644 index 0000000..a6d198c --- /dev/null +++ b/src/Zend/Media/Id3/DateFrame.php @@ -0,0 +1,111 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_DateFrame + extends Zend_Media_Id3_TextFrame +{ + private $_format; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + * @param string $format Rule for formatting output. If null the default + * ISO 8601 date format is used. + */ + public function __construct + ($reader = null, &$options = array(), $format = null) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + + $this->_format = $format; + + if ($this->_reader === null) { + return; + } + + $this->_reader->skip(1); + $this->setText($this->_reader->readString8($this->_reader->getSize())); + } + + /** + * Returns the date. + * + * @return Zend_Date + */ + public function getDate() + { + require_once 'Zend/Date.php'; + $date = new Zend_Date(0); + $date->setTimezone('UTC'); + $date->set + ($this->getText(), + $this->_format ? $this->_format : Zend_Date::ISO_8601); + return $date; + } + + /** + * Sets the date. If called with null value the current time is entered. + * + * @param Zend_Date $date The date. + */ + public function setDate($date = null) + { + require_once 'Zend/Date.php'; + if ($date === null) { + $date = Zend_Date::now(); + } + $date->setTimezone('UTC'); + $this->setText($date->toString(Zend_Date::ISO_8601)); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + parent::_writeData($writer); + } +} diff --git a/src/Zend/Media/Id3/Encoding.php b/src/Zend/Media/Id3/Encoding.php new file mode 100644 index 0000000..45de538 --- /dev/null +++ b/src/Zend/Media/Id3/Encoding.php @@ -0,0 +1,82 @@ +Encoding interface implies that the implementing ID3v2 frame + * supports content encoding. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +interface Zend_Media_Id3_Encoding +{ + /** The ISO-8859-1 encoding. */ + const ISO88591 = 0; + + /** The UTF-16 Unicode encoding with BOM. */ + const UTF16 = 1; + + /** The UTF-16LE Unicode encoding without BOM. */ + const UTF16LE = 4; + + /** The UTF-16BE Unicode encoding without BOM. */ + const UTF16BE = 2; + + /** The UTF-8 Unicode encoding. */ + const UTF8 = 3; + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding(); + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding); +} diff --git a/src/Zend/Media/Id3/Exception.php b/src/Zend/Media/Id3/Exception.php new file mode 100644 index 0000000..c67df87 --- /dev/null +++ b/src/Zend/Media/Id3/Exception.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Id3_Exception extends Zend_Media_Exception +{} diff --git a/src/Zend/Media/Id3/ExtendedHeader.php b/src/Zend/Media/Id3/ExtendedHeader.php new file mode 100644 index 0000000..6282f6e --- /dev/null +++ b/src/Zend/Media/Id3/ExtendedHeader.php @@ -0,0 +1,348 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_ExtendedHeader extends Zend_Media_Id3_Object +{ + /** + * A flag to denote that the present tag is an update of a tag found earlier + * in the present file or stream. If frames defined as unique are found in + * the present tag, they are to override any corresponding ones found in the + * earlier tag. This flag has no corresponding data. + * + * @since ID3v2.4.0 + */ + const UPDATE = 64; + + /** + * @since ID3v2.4.0 A flag to denote that a CRC-32 data is included in the + * extended header. The CRC is calculated on all the data between the header + * and footer as indicated by the header's tag length field, minus the + * extended header. Note that this includes the padding (if there is any), + * but excludes the footer. The CRC-32 is stored as an 35 bit synchsafe + * integer, leaving the upper four bits always zeroed. + * + * @since ID3v2.3.0 The CRC is calculated before unsynchronisation on the + * data between the extended header and the padding, i.e. the frames and + * only the frames. + */ + const CRC32 = 32; + + /** + * A flag to denote whether or not the tag has restrictions applied on it. + * + * @since ID3v2.4.0 + */ + const RESTRICTED = 16; + + /** @var integer */ + private $_size; + + /** @var integer */ + private $_flags = 0; + + /** @var integer */ + private $_padding; + + /** @var integer */ + private $_crc; + + /** @var integer */ + private $_restrictions = 0; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) + return; + + $offset = $this->_reader->getOffset(); + $this->_size = $this->_reader->readUInt32BE(); + + /* ID3v2.3.0 ExtendedHeader */ + if ($this->getOption('version', 4) < 4) { + if ($this->_reader->readUInt16BE() == 0x8000) { + $this->_flags = self::CRC32; + } + $this->_padding = $this->_reader->readUInt32BE(); + if ($this->hasFlag(self::CRC32)) { + $this->_crc = $this->_reader->readUInt32BE(); + } + } + + /* ID3v2.4.0 ExtendedHeader */ + else { + $this->_size = $this->_decodeSynchsafe32($this->_size); + $this->_reader->skip(1); + $this->_flags = $this->_reader->readInt8(); + if ($this->hasFlag(self::UPDATE)) { + $this->_reader->skip(1); + } + if ($this->hasFlag(self::CRC32)) { + $this->_reader->skip(1); + $this->_crc = + $this->_reader->readInt8() * (0xfffffff + 1) + + _decodeSynchsafe32($this->_reader->readUInt32BE()); + } + if ($this->hasFlag(self::RESTRICTED)) { + $this->_reader->skip(1); + $this->_restrictions = $this->_reader->readInt8(); + } + } + } + + /** + * Returns the extended header size in bytes. + * + * @return integer + */ + public function getSize() + { + return $this->_size; + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the flags byte. + * + * @return integer + */ + public function getFlags($flags) + { + return $this->_flags; + } + + /** + * Sets the flags byte. + * + * @param integer $flags The flags byte. + */ + public function setFlags($flags) + { + $this->_flags = $flags; + } + + /** + * Returns the CRC-32 data. + * + * @return integer + */ + public function getCrc() + { + if ($this->hasFlag(self::CRC32)) { + return $this->_crc; + } + return false; + } + + /** + * Sets whether the CRC-32 should be generated upon tag write. + * + * @param boolean $useCrc Whether CRC-32 should be generated. + */ + public function useCrc($useCrc) + { + if ($useCrc) { + $this->setFlags($this->getFlags() | self::CRC32); + } else { + $this->setFlags($this->getFlags() & ~self::CRC32); + } + } + + /** + * Sets the CRC-32. The CRC-32 value is calculated of all the frames in the + * tag and includes padding. + * + * @param integer $crc The 32-bit CRC value. + */ + public function setCrc($crc) + { + if (is_bool($crc)) { + $this->useCrc($crc); + } else { + $this->_crc = $crc; + } + } + + /** + * Returns the restrictions. For some applications it might be desired to + * restrict a tag in more ways than imposed by the ID3v2 specification. Note + * that the presence of these restrictions does not affect how the tag is + * decoded, merely how it was restricted before encoding. If this flag is + * set the tag is restricted as follows: + * + *
    +     * Restrictions %ppqrrstt
    +     *
    +     * p - Tag size restrictions
    +     *
    +     *   00   No more than 128 frames and 1 MB total tag size.
    +     *   01   No more than 64 frames and 128 KB total tag size.
    +     *   10   No more than 32 frames and 40 KB total tag size.
    +     *   11   No more than 32 frames and 4 KB total tag size.
    +     *
    +     * q - Text encoding restrictions
    +     *
    +     *   0    No restrictions
    +     *   1    Strings are only encoded with ISO-8859-1 or UTF-8.
    +     *
    +     * r - Text fields size restrictions
    +     *
    +     *   00   No restrictions
    +     *   01   No string is longer than 1024 characters.
    +     *   10   No string is longer than 128 characters.
    +     *   11   No string is longer than 30 characters.
    +     *
    +     *   Note that nothing is said about how many bytes is used to represent
    +     *   those characters, since it is encoding dependent. If a text frame
    +     *   consists of more than one string, the sum of the strungs is restricted
    +     *   as stated.
    +     *
    +     * s - Image encoding restrictions
    +     *
    +     *   0   No restrictions
    +     *   1   Images are encoded only with PNG [PNG] or JPEG [JFIF].
    +     *
    +     * t - Image size restrictions
    +     *
    +     *   00  No restrictions
    +     *   01  All images are 256x256 pixels or smaller.
    +     *   10  All images are 64x64 pixels or smaller.
    +     *   11  All images are exactly 64x64 pixels, unless required otherwise.
    +     * 
    + * + * @return integer + */ + public function getRestrictions() + { + return $this->_restrictions; + } + + /** + * Sets the restrictions byte. See {@link #getRestrictions} for more. + * + * @param integer $restrictions The restrictions byte. + */ + public function setRestrictions($restrictions) + { + $this->_restrictions = $restrictions; + } + + /** + * Returns the total padding size, or simply the total tag size excluding + * the frames and the headers. + * + * @return integer + * @deprecated ID3v2.3.0 + */ + public function getPadding() + { + return $this->_padding; + } + + /** + * Sets the total padding size, or simply the total tag size excluding the + * frames and the headers. + * + * @param integer $padding The padding size. + * @deprecated ID3v2.3.0 + */ + public function setPadding($padding) + { + return $this->_padding = $padding; + } + + /** + * Writes the header data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + /* ID3v2.3.0 ExtendedHeader */ + if ($this->getOption('version', 4) < 4) { + $writer->writeUInt32BE($this->_size) + ->writeUInt16BE($this->hasFlag(self::CRC32) ? 0x8000 : 0) + ->writeUInt32BE($this->_padding); + if ($this->hasFlag(self::CRC32)) { + $writer->writeUInt32BE($this->_crc); + } + } + + /* ID3v2.4.0 ExtendedHeader */ + else { + $writer->writeUInt32BE($this->_encodeSynchsafe32($this->_size)) + ->writeInt8(1) + ->writeInt8($this->_flags); + if ($this->hasFlag(self::UPDATE)) { + $writer->write("\0"); + } + if ($this->hasFlag(self::CRC32)) { + $writer->writeInt8(5) + ->writeInt8 + ($this->_crc & 0xf0000000 >> 28 & 0xf /*eq >>> 28*/) + ->writeUInt32BE($this->_encodeSynchsafe32($this->_crc)); + } + if ($this->hasFlag(self::RESTRICTED)) { + $writer->writeInt8(1) + ->writeInt8($this->_restrictions); + } + } + } +} diff --git a/src/Zend/Media/Id3/Frame.php b/src/Zend/Media/Id3/Frame.php new file mode 100644 index 0000000..f6fd4d6 --- /dev/null +++ b/src/Zend/Media/Id3/Frame.php @@ -0,0 +1,326 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_Frame extends Zend_Media_Id3_Object +{ + /** + * This flag tells the tag parser what to do with this frame if it + * unknown and the tag is altered in any way. This applies to all kinds of + * alterations, including adding more padding and reordering the frames. + */ + const DISCARD_ON_TAGCHANGE = 16384; + + /** + * This flag tells the tag parser what to do with this frame if it is + * unknown and the file, excluding the tag, is altered. This does not apply + * when the audio is completely replaced with other audio data. + */ + const DISCARD_ON_FILECHANGE = 8192; + + /** + * This flag, if set, tells the software that the contents of this frame are + * intended to be read only. Changing the contents might break something, + * e.g. a signature. + */ + const READ_ONLY = 4096; + + /** + * This flag indicates whether or not this frame belongs in a group with + * other frames. If set, a group identifier byte is added to the frame. + * Every frame with the same group identifier belongs to the same group. + */ + const GROUPING_IDENTITY = 32; + + /** + * This flag indicates whether or not the frame is compressed. A Data + * Length Indicator byte is included in the frame. + * + * @see DATA_LENGTH_INDICATOR + */ + const COMPRESSION = 8; + + /** + * This flag indicates whether or not the frame is encrypted. If set, one + * byte indicating with which method it was encrypted will be added to the + * frame. See description of the {@link Zend_Media_Id3_Frame_Encr ENCR} + * frame for more information about encryption method registration. + * Encryption should be done after compression. Whether or not setting this + * flag requires the presence of a Data Length Indicator depends on + * the specific algorithm used. + * + * @see DATA_LENGTH_INDICATOR + */ + const ENCRYPTION = 4; + + /** + * This flag indicates whether or not unsynchronisation was applied to this + * frame. + * + * @since ID3v2.4.0 + */ + const UNSYNCHRONISATION = 2; + + /** + * This flag indicates that a data length indicator has been added to the + * frame. + * + * @since ID3v2.4.0 + */ + const DATA_LENGTH_INDICATOR = 1; + + /** @var integer */ + private $_identifier; + + /** @var integer */ + private $_size = 0; + + /** @var integer */ + private $_flags = 0; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * Replaces the reader instance with a string reader object instance that + * can be used to further process the data in the frame sub class. + * + * @todo Only limited subset of flags are processed. + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + $this->_identifier = strtoupper(substr(get_class($this), -4)); + } else { + $this->_identifier = + strtoupper($this->_reader->readString8(4, " ")); + + /* ID3v2.3.0 size and flags; convert flags to 2.4.0 format */ + if ($this->getOption('version', 4) < 4) { + $this->_size = $this->_reader->readUInt32BE(); + $flags = $this->_reader->readUInt16BE(); + if (($flags & 0x8000) == 0x8000) { + $this->_flags |= self::DISCARD_ON_TAGCHANGE; + } + if (($flags & 0x4000) == 0x4000) { + $this->_flags |= self::DISCARD_ON_FILECHANGE; + } + if (($flags & 0x2000) == 0x2000) { + $this->_flags |= self::READ_ONLY; + } + if (($flags & 0x80) == 0x80) { + $this->_flags |= self::COMPRESSION; + } + if (($flags & 0x40) == 0x40) { + $this->_flags |= self::ENCRYPTION; + } + if (($flags & 0x20) == 0x20) { + $this->_flags |= self::GROUPING_IDENTITY; + } + } + + /* ID3v2.4.0 size and flags */ + else { + $this->_size = + $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); + $this->_flags = $this->_reader->readUInt16BE(); + } + + $dataLength = $this->_size; + if ($this->hasFlag(self::DATA_LENGTH_INDICATOR)) { + $dataLength = + $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); + $this->_size -= 4; + } + + $data = $this->_reader->read($this->_size); + $this->_size = $dataLength; + + if ($this->hasFlag(self::UNSYNCHRONISATION) || + $this->getOption('unsynchronisation', false) === true) { + $data = $this->_decodeUnsynchronisation($data); + } + + $this->_reader = new Zend_Io_StringReader($data); + } + } + + /** + * Returns the frame identifier string. + * + * @return string + */ + public final function getIdentifier() + { + return $this->_identifier; + } + + /** + * Sets the frame identifier. + * + * @param string $identifier The identifier. + */ + public final function setIdentifier($identifier) + { + $this->_identifier = $identifier; + } + + /** + * Returns the size of the data in the final frame, after encryption, + * compression and unsynchronisation. The size is excluding the frame + * header. + * + * @return integer + */ + public final function getSize() + { + return $this->_size; + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public final function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the frame flags byte. + * + * @return integer + */ + public final function getFlags($flags) + { + return $this->_flags; + } + + /** + * Sets the frame flags byte. + * + * @param string $flags The flags byte. + */ + public final function setFlags($flags) + { + $this->_flags = $flags; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + abstract protected function _writeData($writer); + + /** + * Writes the frame data with the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + /* ID3v2.3.0 Flags; convert from 2.4.0 format */ + if ($this->getOption('version', 4) < 4) { + $flags = 0; + if ($this->hasFlag(self::DISCARD_ON_TAGCHANGE)) { + $flags = $flags | 0x8000; + } + if ($this->hasFlag(self::DISCARD_ON_FILECHANGE)) { + $flags = $flags | 0x4000; + } + if ($this->hasFlag(self::READ_ONLY)) { + $flags = $flags | 0x2000; + } + if ($this->hasFlag(self::COMPRESSION)) { + $flags = $flags | 0x80; + } + if ($this->hasFlag(self::ENCRYPTION)) { + $flags = $flags | 0x40; + } + if ($this->hasFlag(self::GROUPING_IDENTITY)) { + $flags = $flags | 0x20; + } + } + + /* ID3v2.4.0 Flags */ + else { + $flags = $this->_flags; + } + + $this->_writeData($buffer = new Zend_Io_StringWriter()); + $data = $buffer->toString(); + $size = $this->_size = strlen($data); + + // ID3v2.4.0 supports frame level unsynchronisation. The corresponding + // option is set to true when any of the frames use the + // unsynchronisation scheme. The usage is denoted by + // Zend_Media_Id3_Header flag that is set accordingly upon file write. + if ($this->getOption('version', 4) >= 4) { + $data = $this->_encodeUnsynchronisation($data); + if (($dataLength = strlen($data)) != $size) { + $size = 4 + $dataLength; + $flags |= self::DATA_LENGTH_INDICATOR | self::UNSYNCHRONISATION; + $this->setOption('unsynchronisation', true); + } else { + $flags &= ~(self::DATA_LENGTH_INDICATOR | + self::UNSYNCHRONISATION); + } + } + + $writer->writeString8(substr($this->_identifier, 0, 4), 4, " ") + ->writeUInt32BE($this->_encodeSynchsafe32($size)) + ->writeUInt16BE($flags); + + if (($flags & self::DATA_LENGTH_INDICATOR) == + self::DATA_LENGTH_INDICATOR) { + $writer->writeUInt32BE($this->_encodeSynchsafe32($this->_size)); + } + $writer->write($data); + } +} diff --git a/src/Zend/Media/Id3/Frame/Aenc.php b/src/Zend/Media/Id3/Frame/Aenc.php new file mode 100644 index 0000000..12c27f1 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Aenc.php @@ -0,0 +1,178 @@ +Audio encryption indicates if the actual audio stream is + * encrypted, and by whom. + * + * The identifier is a URL containing an email address, or a link to a location + * where an email address can be found, that belongs to the organisation + * responsible for this specific encrypted audio file. Questions regarding the + * encrypted audio should be sent to the email address specified. There may be + * more than one AENC frame in a tag, but only one with the same owner + * identifier. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Aenc extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var integer */ + private $_previewStart; + + /** @var integer */ + private $_previewLength; + + /** @var string */ + private $_encryptionInfo; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list($this->_owner) = $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(strlen($this->_owner) + 1); + $this->_previewStart = $this->_reader->readUInt16BE(); + $this->_previewLength = $this->_reader->readUInt16BE(); + $this->_encryptionInfo = + $this->_reader->read($this->_reader->getSize()); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + $this->_owner = $owner; + } + + /** + * Returns the pointer to an unencrypted part of the audio in frames. + * + * @return integer + */ + public function getPreviewStart() + { + return $this->_previewStart; + } + + /** + * Sets the pointer to an unencrypted part of the audio in frames. + * + * @param integer $previewStart The pointer to an unencrypted part. + */ + public function setPreviewStart($previewStart) + { + $this->_previewStart = $previewStart; + } + + /** + * Returns the length of the preview in frames. + * + * @return integer + */ + public function getPreviewLength() + { + return $this->_previewLength; + } + + /** + * Sets the length of the preview in frames. + * + * @param integer $previewLength The length of the preview. + */ + public function setPreviewLength($previewLength) + { + $this->_previewLength = $previewLength; + } + + /** + * Returns the encryption info. + * + * @return string + */ + public function getEncryptionInfo() + { + return $this->_encryptionInfo; + } + + /** + * Sets the encryption info binary string. + * + * @param string $encryptionInfo The data string. + */ + public function setEncryptionInfo($encryptionInfo) + { + $this->_encryptionInfo = $encryptionInfo; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->writeUInt16BE($this->_previewStart) + ->writeUInt16BE($this->_previewLength) + ->write($this->_encryptionInfo); + } +} diff --git a/src/Zend/Media/Id3/Frame/Apic.php b/src/Zend/Media/Id3/Frame/Apic.php new file mode 100644 index 0000000..3fc4f24 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Apic.php @@ -0,0 +1,290 @@ +Attached picture frame contains a picture directly related to the + * audio file. Image format is the MIME type and subtype for the image. + * + * There may be several pictures attached to one file, each in their individual + * APIC frame, but only one with the same content descriptor. There may only + * be one picture with the same picture type. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Apic extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** + * The list of image types. + * + * @var Array + */ + public static $types = array + ('Other', '32x32 pixels file icon (PNG only)', 'Other file icon', + 'Cover (front)', 'Cover (back)', 'Leaflet page', + 'Media (e.g. label side of CD)', 'Lead artist/lead performer/soloist', + 'Artist/performer', 'Conductor', 'Band/Orchestra', 'Composer', + 'Lyricist/text writer', 'Recording Location', 'During recording', + 'During performance', 'Movie/video screen capture', + 'A bright coloured fish', 'Illustration', 'Band/artist logotype', + 'Publisher/Studio logotype'); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_mimeType = 'image/unknown'; + + /** @var integer */ + private $_imageType = 0; + + /** @var string */ + private $_description; + + /** @var string */ + private $_imageData; + + /** @var integer */ + private $_imageSize = 0; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @todo There is the possibility to put only a link to the image file by + * using the MIME type '-->' and having a complete URL instead of picture + * data. Support for such needs design considerations. + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + list($this->_mimeType) = $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(1 + strlen($this->_mimeType) + 1); + $this->_imageType = $this->_reader->readUInt8(); + + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list ($this->_description, $this->_imageData) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + break; + case self::UTF8: + // break intentionally omitted + default: + list ($this->_description, $this->_imageData) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + break; + } + $this->_description = + $this->_convertString($this->_description, $encoding); + $this->_imageSize = strlen($this->_imageData); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the MIME type. The MIME type is always ISO-8859-1 encoded. + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) + { + $this->_mimeType = $mimeType; + } + + /** + * Returns the image type. + * + * @return integer + */ + public function getImageType() + { + return $this->_imageType; + } + + /** + * Sets the image type code. + * + * @param integer $imageType The image type code. + */ + public function setImageType($imageType) + { + $this->_imageType = $imageType; + } + + /** + * Returns the file description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = null) + { + $this->_description = $description; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Returns the embedded image data. + * + * @return string + */ + public function getImageData() + { + return $this->_imageData; + } + + /** + * Sets the embedded image data. Also updates the image size field to + * correspond the new data. + * + * @param string $imageData The image data. + */ + public function setImageData($imageData) + { + $this->_imageData = $imageData; + $this->_imageSize = strlen($imageData); + } + + /** + * Returns the size of the embedded image data. + * + * @return integer + */ + public function getImageSize() + { + return $this->_imageSize; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->writeString8($this->_mimeType, 1) + ->writeUInt8($this->_imageType); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1); + break; + default: + $writer->writeString8($this->_description, 1); + break; + } + $writer->writeString8($this->_imageData); + } +} diff --git a/src/Zend/Media/Id3/Frame/Aspi.php b/src/Zend/Media/Id3/Frame/Aspi.php new file mode 100644 index 0000000..c729de2 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Aspi.php @@ -0,0 +1,160 @@ +Audio seek point index or + * ASPI frame makes seeking easier by providing a list a seek points within the + * audio file. The seek points are a fractional offset within the audio data, + * providing a starting point from which to find an appropriate point to start + * decoding. The presence of an ASPI frame requires the existence of a + * {@link Zend_Media_Id3_Frame_Tlen TLEN} frame, indicating the duration of the + * file in milliseconds. There may only be one audio seek point index frame in + * a tag. + * + * @todo Data parsing and write support + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Aspi extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_dataStart; + + /** @var integer */ + private $_dataLength; + + /** @var integer */ + private $_size; + + /** @var Array */ + private $_fractions = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Write not supported yet'); + } + + $this->_dataStart = $this->_reader->readInt32BE(); + $this->_dataLength = $this->_reader->readInt32BE(); + $this->_size = $this->_reader->readInt16BE(); + + $bitsPerPoint = $this->_reader->readInt8($this->_data[10]); + /*for ($i = 0, $offset = 11; $i < $this->_size; $i++) { + if ($bitsPerPoint == 16) { + $this->_fractions[$i] = substr($this->_data, $offset, 2); + $offset += 2; + } else { + $this->_fractions[$i] = substr($this->_data, $offset, 1); + $offset ++; + } + }*/ + } + + /** + * Returns the byte offset from the beginning of the file. + * + * @return integer + */ + public function getDataStart() + { + return $this->_dataStart; + } + + /** + * Sets the byte offset from the beginning of the file. + * + * @param integer $dataStart The offset. + */ + public function setDataStart($dataStart) + { + $this->_dataStart = $dataStart; + } + + /** + * Returns the byte length of the audio data being indexed. + * + * @return integer + */ + public function getDataLength() + { + return $this->_dataLength; + } + + /** + * Sets the byte length of the audio data being indexed. + * + * @param integer $dataLength The length. + */ + public function setDataLength($dataLength) + { + $this->_dataLength = $dataLength; + } + + /** + * Returns the number of index points in the frame. + * + * @return integer + */ + public function getSize() + { + return count($this->_fractions); + } + + /** + * Returns the numerator of the fraction representing a relative position in + * the data or false if index not defined. The denominator is 2 + * to the power of b. + * + * @param integer $index The fraction numerator. + * @return integer + */ + public function getFractionAt($index) + { + if (isset($this->_fractions[$index])) { + return $this->_fractions[$index]; + } + return false; + } +} diff --git a/src/Zend/Media/Id3/Frame/Comm.php b/src/Zend/Media/Id3/Frame/Comm.php new file mode 100644 index 0000000..83cbdb3 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Comm.php @@ -0,0 +1,155 @@ +Comments frame is intended for any kind of full text information + * that does not fit in any other frame. It consists of a frame header followed + * by encoding, language and content descriptors and is ended with the actual + * comment as a text string. Newline characters are allowed in the comment text + * string. There may be more than one comment frame in each tag, but only one + * with the same language and content descriptor. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Comm extends Zend_Media_Id3_LanguageTextFrame +{ + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_language = strtolower($this->_reader->read(3)); + if ($this->_language == 'xxx') { + $this->_language = 'und'; + } + + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($this->_description, $this->_text) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_description = + $this->_convertString($this->_description, $encoding); + $this->_text = + $this->_convertString($this->_text, $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + list($this->_description, $this->_text) = $this->_convertString + ($this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2), + $encoding); + break; + } + } + + /** + * Returns the short content description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription + ($description, $language = null, $encoding = null) + { + $this->_description = $description; + if ($language !== null) { + $this->setLanguage($language); + } + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_language); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1) + ->writeString16 + ($this->_text,Zend_Io_Writer::LITTLE_ENDIAN_ORDER); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1) + ->writeString16($this->_text); + break; + default: + $writer->writeString8($this->_description, 1) + ->writeString8($this->_text); + break; + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Comr.php b/src/Zend/Media/Id3/Frame/Comr.php new file mode 100644 index 0000000..8c81cab --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Comr.php @@ -0,0 +1,490 @@ +Commercial frame enables several competing offers in the same tag + * by bundling all needed information. That makes this frame rather complex but + * it's an easier solution than if one tries to achieve the same result with + * several frames. + * + * There may be more than one commercial frame in a tag, but no two may be + * identical. + * + * @todo The use of Zend_Currency requires design considerations. + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Comr extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** + * The delivery types. + * + * @var Array + */ + public static $types = array + ('Other', 'Standard CD album with other songs', + 'Compressed audio on CD', 'File over the Internet', + 'Stream over the Internet', 'As note sheets', + 'As note sheets in a book with other sheets', 'Music on other media', + 'Non-musical merchandise'); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_currency = 'EUR'; + + /** @var string */ + private $_price; + + /** @var string */ + private $_date; + + /** @var string */ + private $_contact; + + /** @var integer */ + private $_delivery = 0; + + /** @var string */ + private $_seller; + + /** @var string */ + private $_description; + + /** @var string */ + private $_mimeType = false; + + /** @var string */ + private $_imageData; + + /** @var integer */ + private $_imageSize = 0; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_currency = strtoupper($this->_reader->read(3)); + $offset = $this->_reader->getOffset(); + list ($this->_price) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset($offset + strlen($this->_price) + 1); + $this->_date = $this->_reader->read(8); + $offset = $this->_reader->getOffset(); + list($this->_contact) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset($offset + strlen($this->_contact) + 1); + $this->_delivery = $this->_reader->readUInt8(); + $offset = $this->_reader->getOffset(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list ($this->_seller, $this->_description) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 3); + $this->_reader->setOffset + ($offset + strlen($this->_seller) + + strlen($this->_description) + 4); + break; + case self::UTF8: + // break intentionally omitted + default: + list ($this->_seller, $this->_description) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 3); + $this->_reader->setOffset + ($offset + strlen($this->_seller) + + strlen($this->_description) + 2); + break; + } + $this->_seller = $this->_convertString($this->_seller, $encoding); + $this->_description = $this->_convertString($this->_description, $encoding); + + if (!$this->_reader->available()) + return; + + list($this->_mimeType, $this->_imageData) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_imageSize = strlen($this->_imageData); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the currency code, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @return string + */ + public function getCurrency() + { + return $this->_currency; + } + + /** + * Sets the currency used in transaction, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @param string $currency The currency code. + */ + public function setCurrency($currency) + { + $this->_currency = strtoupper($currency); + } + + /** + * Returns the first price. + * + * @return double + */ + public function getPrice() + { + $array = explode('/', $this->_price); + return doubleval($array[0]); + } + + /** + * Returns the price array. + * + * @return Array + */ + public function getPrices() + { + $array = explode('/', $this->_price); + foreach ($array as $key => $value) { + $array[$key] = doubleval($value); + } + return $array; + } + + /** + * Sets the default price. Multiple prices can be given in the form of an + * array but there may only be one currency of each type. + * + * @param double $price The price. + */ + public function setPrice($price) + { + $this->setPrices($price); + } + + /** + * Sets the default price. Multiple prices can be given in the form of an + * array but there may only be one currency of each type. + * + * @param double|Array $prices The prices. + */ + public function setPrices($prices) + { + if (!is_array($prices)) { + $prices = array($prices); + } + $this->_price = implode('/', $prices); + } + + /** + * Returns the date describing for how long the price is valid. + * + * @internal The ID3v2 standard does not declare the time zone to be used + * in the date. Date must thus be expressed as GMT/UTC. + * @return Zend_Date + */ + public function getDate() + { + require_once 'Zend/Date.php'; + $date = new Zend_Date(0); + $date->setTimezone('UTC'); + $date->set($this->_date, 'yyyyMMdd'); + return $date; + } + + /** + * Sets the date describing for how long the price is valid for. + * + * @internal The ID3v2 standard does not declare the time zone to be used + * in the date. Date must thus be expressed as GMT/UTC. + * @param Zend_Date $date The date. + */ + public function setDate($date) + { + require_once 'Zend/Date.php'; + if ($date === null) { + $date = Zend_Date::now(); + } + $date->setTimezone('UTC'); + $this->_date = $date->toString('yyyyMMdd'); + } + + /** + * Returns the contact URL, with which the user can contact the seller. + * + * @return string + */ + public function getContact() + { + return $this->_contact; + } + + /** + * Sets the contact URL, with which the user can contact the seller. + * + * @param string $contact The contact URL. + */ + public function setContact($contact) + { + $this->_contact = $contact; + } + + /** + * Returns the delivery type with whitch the audio was delivered when + * bought. + * + * @return integer + */ + public function getDelivery() + { + return $this->_delivery; + } + + /** + * Sets the delivery type with whitch the audio was delivered when bought. + * + * @param integer $delivery The delivery type code. + */ + public function setDelivery($delivery) + { + $this->_delivery = $delivery; + } + + /** + * Returns the name of the seller. + * + * @return string + */ + public function getSeller() + { + return $this->_seller; + } + + /** + * Sets the name of the seller using given encoding. The seller text + * encoding must be that of the description text. + * + * @param string $seller The name of the seller. + * @param integer $encoding The text encoding. + */ + public function setSeller($seller, $encoding = null) + { + $this->_seller = $seller; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Returns the short description of the product. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. The description + * encoding must be that of the seller text. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = null) + { + $this->_description = $description; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Returns the MIME type of the seller's company logo, if attached, or + * false otherwise. Currently only 'image/png' and 'image/jpeg' + * are allowed. + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Sets the MIME type. Currently only 'image/png' and 'image/jpeg' are + * allowed. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) + { + $this->_mimeType = $mimeType; + } + + /** + * Returns the embedded image binary data. + * + * @return string + */ + public function getImageData() + { + return $this->_imageData; + } + + /** + * Sets the embedded image data. Also updates the image size to correspond + * the new data. + * + * @param string $imageData The image data. + */ + public function setImageData($imageData) + { + $this->_imageData = $imageData; + $this->_imageSize = strlen($imageData); + } + + /** + * Returns the size of the embedded image data. + * + * @return integer + */ + public function getImageSize() + { + return $this->_imageSize; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_currency) + ->writeString8($this->_price, 1) + ->write($this->_date) + ->writeString8($this->_contact, 1) + ->writeUInt8($this->_delivery); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_seller, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1) + ->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_seller, null, 1) + ->writeString16($this->_description, null, 1); + break; + default: + $writer->writeString8($this->_seller, 1) + ->writeString8($this->_description, 1); + break; + } + if ($this->_mimeType) { + $writer->writeString8($this->_mimeType, 1) + ->write($this->_imageData); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Encr.php b/src/Zend/Media/Id3/Frame/Encr.php new file mode 100644 index 0000000..8289ab2 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Encr.php @@ -0,0 +1,165 @@ +Encryption method + * registration frame. + * + * The owner identifier a URL containing an email address, or a link to a + * location where an email address can be found, that belongs to the + * organisation responsible for this specific encryption method. Questions + * regarding the encryption method should be sent to the indicated email + * address. + * + * The method symbol contains a value that is associated with this method + * throughout the whole tag, in the range 0x80-0xF0. All other values are + * reserved. The method symbol may optionally be followed by encryption + * specific data. + * + * There may be several ENCR frames in a tag but only one containing the same + * symbol and only one containing the same owner identifier. The method must be + * used somewhere in the tag. See {@link Zend_Media_Id3_Frame#ENCRYPTION} for + * more information. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Encr extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var integer */ + private $_method; + + /** @var string */ + private $_encryptionData; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list($this->_owner, ) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(strlen($this->_owner) + 1); + $this->_method = $this->_reader->readInt8(); + $this->_encryptionData = + $this->_reader->read($this->_reader->getSize()); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + $this->_owner = $owner; + } + + /** + * Returns the method symbol. + * + * @return integer + */ + public function getMethod() + { + return $this->_method; + } + + /** + * Sets the method symbol. + * + * @param integer $method The method symbol byte. + */ + public function setMethod($method) + { + $this->_method = $method; + } + + /** + * Returns the encryption data. + * + * @return string + */ + public function getEncryptionData() + { + return $this->_encryptionData; + } + + /** + * Sets the encryption data. + * + * @param string $encryptionData The encryption data string. + */ + public function setEncryptionData($encryptionData) + { + $this->_encryptionData = $encryptionData; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->writeInt8($this->_method) + ->write($this->_encryptionData); + } +} diff --git a/src/Zend/Media/Id3/Frame/Equ2.php b/src/Zend/Media/Id3/Frame/Equ2.php new file mode 100644 index 0000000..2945d7a --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Equ2.php @@ -0,0 +1,195 @@ +Equalisation (2) is another subjective, alignment frame. It allows + * the user to predefine an equalisation curve within the audio file. There may + * be more than one EQU2 frame in each tag, but only one with the same + * identification string. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Equ2 extends Zend_Media_Id3_Frame +{ + /** + * Interpolation type that defines that no interpolation is made. A jump + * from one adjustment level to another occurs in the middle between two + * adjustment points. + */ + const BAND = 0; + + /** + * Interpolation type that defines that interpolation between adjustment + * points is linear. + */ + const LINEAR = 1; + + /** @var integer */ + private $_interpolation; + + /** @var string */ + private $_device; + + /** @var Array */ + private $_adjustments = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_interpolation = $this->_reader->readInt8(); + list ($this->_device) = $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(1 + strlen($this->_device) + 1); + while ($this->_reader->available()) { + $this->_adjustments + [(int)($this->_reader->readUInt16BE() / 2)] = + $this->_reader->readInt16BE() / 512.0; + } + ksort($this->_adjustments); + } + + /** + * Returns the interpolation method. The interpolation method describes + * which method is preferred when an interpolation between the adjustment + * point that follows. + * + * @return integer + */ + public function getInterpolation() + { + return $this->_interpolation; + } + + /** + * Sets the interpolation method. The interpolation method describes which + * method is preferred when an interpolation between the adjustment point + * that follows. + * + * @param integer $interpolation The interpolation method code. + */ + public function setInterpolation($interpolation) + { + $this->_interpolation = $interpolation; + } + + /** + * Returns the device where the adjustments should apply. + * + * @return string + */ + public function getDevice() + { + return $this->_device; + } + + /** + * Sets the device where the adjustments should apply. + * + * @param string $device The device. + */ + public function setDevice($device) + { + $this->_device = $device; + } + + /** + * Returns the array containing adjustments having frequencies as keys and + * their corresponding adjustments as values. + * + * Adjustment points are ordered by frequency. + * + * @return Array + */ + public function getAdjustments() + { + return $this->_adjustments; + } + + /** + * Adds a volume adjustment setting for given frequency. The frequency can + * have a value from 0 to 32767 Hz, and the adjustment +/- 64 dB with a + * precision of 0.001953125 dB. + * + * @param integer $frequency The frequency, in hertz. + * @param integer $adjustment The adjustment, in dB. + */ + public function addAdjustment($frequency, $adjustment) + { + $this->_adjustments[$frequency] = $adjustment; + ksort($this->_adjustments); + } + + /** + * Sets the adjustments array. The array must have frequencies as keys and + * their corresponding adjustments as values. The frequency can have a value + * from 0 to 32767 Hz, and the adjustment +/- 64 dB with a precision of + * 0.001953125 dB. One frequency should only be described once in the frame. + * + * @param Array $adjustments The adjustments array. + */ + public function setAdjustments($adjustments) + { + $this->_adjustments = $adjustments; + ksort($this->_adjustments); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeInt8($this->_interpolation) + ->writeString8($this->_device, 1); + foreach ($this->_adjustments as $frequency => $adjustment) { + $writer->writeUInt16BE($frequency * 2) + ->writeInt16BE($adjustment * 512); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Equa.php b/src/Zend/Media/Id3/Frame/Equa.php new file mode 100644 index 0000000..0d86490 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Equa.php @@ -0,0 +1,133 @@ +Equalisation frame is another subjective, alignment frame. It + * allows the user to predefine an equalisation curve within the audio file. + * There may only be one EQUA frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Equa extends Zend_Media_Id3_Frame +{ + /** @var Array */ + private $_adjustments; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $adjustmentBits = $this->_reader->readInt8(); + if ($adjustmentBits <= 8 || $adjustmentBits > 16) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('Unsupported adjustment bit size of: ' . $adjustmentBits); + } + + while ($this->_reader->available()) { + $frequency = $this->_reader->readUInt16BE(); + $this->_adjustments[($frequency & 0x7fff)] = + ($frequency & 0x8000) == 0x8000 ? + $this->_reader->readUInt16BE() : + -$this->_reader->readUInt16BE(); + } + ksort($this->_adjustments); + } + + /** + * Returns the array containing adjustments having frequencies as keys and + * their corresponding adjustments as values. + * + * @return Array + */ + public function getAdjustments() + { + return $this->_adjustments; + } + + /** + * Adds a volume adjustment setting for given frequency. The frequency can + * have a value from 0 to 32767 Hz. + * + * @param integer $frequency The frequency, in hertz. + * @param integer $adjustment The adjustment, in dB. + */ + public function addAdjustment($frequency, $adjustment) + { + $this->_adjustments[$frequency] = $adjustment; + ksort($this->_adjustments); + } + + /** + * Sets the adjustments array. The array must have frequencies as keys and + * their corresponding adjustments as values. The frequency can have a value + * from 0 to 32767 Hz. One frequency should only be described once in the + * frame. + * + * @param Array $adjustments The adjustments array. + */ + public function setAdjustments($adjustments) + { + $this->_adjustments = $adjustments; + ksort($this->_adjustments); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeInt8(16); + foreach ($this->_adjustments as $frequency => $adjustment) { + $writer->writeUInt16BE + ($adjustment > 0 ? $frequency | 0x8000 : $frequency & ~0x8000) + ->writeUInt16BE(abs($adjustment)); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Etco.php b/src/Zend/Media/Id3/Frame/Etco.php new file mode 100644 index 0000000..7cda37a --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Etco.php @@ -0,0 +1,168 @@ +Event timing codes allows synchronisation with key events in the + * audio. + * + * The events are an array of timestamp and type pairs. The time stamp is set to + * zero if directly at the beginning of the sound or after the previous event. + * All events are sorted in chronological order. + * + * The events 0xe0-ef are for user events. You might want to synchronise your + * music to something, like setting off an explosion on-stage, activating a + * screensaver etc. + * + * There may only be one ETCO frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Etco extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Timing +{ + /** + * The list of event types. + * + * @var Array + */ + public static $types = array + ('Padding', 'End of initial silence', 'Intro start', 'Main part start', + 'Outro start', 'Outro end', 'Verse start','Refrain start', + 'Interlude start', 'Theme start', 'Variation start', 'Key change', + 'Time change', 'Momentary unwanted noise', 'Sustained noise', + 'Sustained noise end', 'Intro end', 'Main part end', 'Verse end', + 'Refrain end', 'Theme end', 'Profanity', 'Profanity end', + + 0xe0 => 'User event', 'User event', 'User event', 'User event', + 'User event', 'User event', 'User event', 'User event', 'User event', + 'User event', 'User event', 'User event', 'User event', 'User event', + + 0xfd => 'Audio end (start of silence)', 'Audio file ends', + 'One more byte of events follows'); + + /** @var integer */ + private $_format = Zend_Media_Id3_Timing::MPEG_FRAMES; + + /** @var Array */ + private $_events = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_format = $this->_reader->readUInt8(); + while ($this->_reader->available()) { + $data = $this->_reader->readUInt8(); + $this->_events[$this->_reader->readUInt32BE()] = $data; + if ($data == 0xff) { + break; + } + } + ksort($this->_events); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() + { + return $this->_format; + } + + /** + * Sets the timing format. + * + * @see Zend_Media_Id3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) + { + $this->_format = $format; + } + + /** + * Returns the events as an associated array having the timestamps as keys + * and the event types as values. + * + * @return Array + */ + public function getEvents() + { + return $this->_events; + } + + /** + * Sets the events using given format. The value must be an associated array + * having the timestamps as keys and the event types as values. + * + * @param Array $events The events array. + * @param integer $format The timing format. + */ + public function setEvents($events, $format = null) + { + $this->_events = $events; + if ($format !== null) { + $this->setFormat($format); + } + ksort($this->_events); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_format); + foreach ($this->_events as $timestamp => $type) { + $writer->writeUInt8($type) + ->writeUInt32BE($timestamp); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Geob.php b/src/Zend/Media/Id3/Frame/Geob.php new file mode 100644 index 0000000..0ba46c5 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Geob.php @@ -0,0 +1,264 @@ +General encapsulated object frame any type of file can be + * encapsulated. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Geob extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_mimeType; + + /** @var string */ + private $_filename; + + /** @var string */ + private $_description; + + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + list($this->_mimeType) = $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(1 + strlen($this->_mimeType) + 1); + + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list ($this->_filename, $this->_description, + $this->_data) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 3); + break; + case self::UTF8: + // break intentionally omitted + default: + list ($this->_filename, $this->_description, + $this->_data) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 3); + break; + } + $this->_filename = + $this->_convertString($this->_filename, $encoding); + $this->_description = + $this->_convertString($this->_description, $encoding); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the MIME type. The MIME type is always encoded with ISO-8859-1. + * + * @return string + */ + public function getMimeType() + { + return $this->_mimeType; + } + + /** + * Sets the MIME type. The MIME type is always ISO-8859-1 encoded. + * + * @param string $mimeType The MIME type. + */ + public function setMimeType($mimeType) + { + $this->_mimeType = $mimeType; + } + + /** + * Returns the file name. + * + * @return string + */ + public function getFilename() + { + return $this->_filename; + } + + /** + * Sets the file name using given encoding. The file name encoding must be + * that of the description text. + * + * @param string $description The file description text. + * @param integer $encoding The text encoding. + */ + public function setFilename($filename, $encoding = null) + { + $this->_filename = $filename; + if ($encoding !== null) { + $this->_encoding = $encoding; + } + } + + /** + * Returns the file description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the file description text using given encoding. The description + * encoding must be that of the file name. + * + * @param string $description The file description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = null) + { + $this->_description = $description; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Returns the embedded object binary data. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the embedded object binary data. + * + * @param string $data The object data. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->writeString8($this->_mimeType, 1); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_filename, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1) + ->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_filename, null, 1) + ->writeString16($this->_description, null, 1); + break; + default: + $writer->writeString8($this->_filename, 1) + ->writeString8($this->_description, 1); + break; + } + $writer->write($this->_data); + } +} diff --git a/src/Zend/Media/Id3/Frame/Grid.php b/src/Zend/Media/Id3/Frame/Grid.php new file mode 100644 index 0000000..7cb2a7b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Grid.php @@ -0,0 +1,160 @@ +Group identification registration frame enables grouping of + * otherwise unrelated frames. This can be used when some frames are to be + * signed. To identify which frames belongs to a set of frames a group + * identifier must be registered in the tag with this frame. + * + * The owner identifier is a URL containing an email address, or a link to a + * location where an email address can be found, that belongs to the + * organisation responsible for this grouping. Questions regarding the grouping + * should be sent to the indicated email address. + * + * The group symbol contains a value that associates the frame with this group + * throughout the whole tag, in the range 0x80-0xf0. All other values are + * reserved. The group symbol may optionally be followed by some group specific + * data, e.g. a digital signature. There may be several GRID frames in a tag + * but only one containing the same symbol and only one containing the same + * owner identifier. The group symbol must be used somewhere in the tag. See + * {@link Zend_Media_Id3_Frame#GROUPING_IDENTITY} for more information. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Grid extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var integer */ + private $_group; + + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list($this->_owner) = $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(strlen($this->_owner) + 1); + $this->_group = $this->_reader->readUInt8(); + $this->_data = $this->_reader->read($this->_reader->getSize()); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + $this->_owner = $owner; + } + + /** + * Returns the group symbol. + * + * @return integer + */ + public function getGroup() + { + return $this->_group; + } + + /** + * Sets the group symbol. + * + * @param integer $group The group symbol. + */ + public function setGroup($group) + { + $this->_group = $group; + } + + /** + * Returns the group dependent data. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the group dependent data. + * + * @param string $data The data. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->writeUInt8($this->_group) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Id3/Frame/Ipls.php b/src/Zend/Media/Id3/Frame/Ipls.php new file mode 100644 index 0000000..0f8c263 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Ipls.php @@ -0,0 +1,200 @@ +Involved people list is a frame containing the names of those + * involved, and how they were involved. There may only be one IPLS frame in + * each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Ipls extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var Array */ + private $_people = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $data = array(); + $encoding = $this->_reader->readUInt8(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $data = $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize())); + foreach ($data as &$str) + $str = $this->_convertString($str, $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + $data = $this->_convertString + ($this->_explodeString8 + ($this->_reader->read($this->_reader->getSize())), + $encoding); + break; + } + + for ($i = 0; $i < count($data) - 1; $i += 2) { + $this->_people[] = array($data[$i] => @$data[$i + 1]); + } + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the involved people list as an array. For each person, the array + * contains an entry, which too is an associate array with involvement as + * its key and involvee as its value. + * + * @return Array + */ + public function getPeople() + { + return $this->_people; + } + + /** + * Adds a person with his involvement. + * + * @return string + */ + public function addPerson($involvement, $person) + { + $this->_people[] = array($involvement => $person); + } + + /** + * Sets the involved people list array. For each person, the array must + * contain an associate array with involvement as its key and involvee as + * its value. + * + * @param Array $people The involved people list. + */ + public function setPeople($people) + { + $this->_people = $people; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding); + foreach ($this->_people as $entry) { + foreach ($entry as $key => $val) { + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($key, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1) + ->writeString16 + ($val, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($key, null, 1) + ->writeString16($val, null, 1); + break; + default: + $writer->writeString8($key, 1) + ->writeString8($val, 1); + break; + } + } + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Link.php b/src/Zend/Media/Id3/Frame/Link.php new file mode 100644 index 0000000..a7ecf50 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Link.php @@ -0,0 +1,188 @@ +Linked information frame is used to keep information duplication + * as low as possible by linking information from another ID3v2 tag that might + * reside in another audio file or alone in a binary file. It is recommended + * that this method is only used when the files are stored on a CD-ROM or other + * circumstances when the risk of file separation is low. + * + * Data should be retrieved from the first tag found in the file to which this + * link points. There may be more than one LINK frame in a tag, but only one + * with the same contents. + * + * A linked frame is to be considered as part of the tag and has the same + * restrictions as if it was a physical part of the tag (i.e. only one + * {@link Zend_Media_Id3_Frame_Rvrb RVRB} frame allowed, whether it's linked or + * not). + * + * Frames that may be linked and need no additional data are + * {@link Zend_Media_Id3_Frame_Aspi ASPI}, + * {@link Zend_Media_Id3_Frame_Etco ETCO}, + * {@link Zend_Media_Id3_Frame_Equ2 EQU2}, + * {@link Zend_Media_Id3_Frame_Mcdi MCDI}, + * {@link Zend_Media_Id3_Frame_Mllt MLLT}, + * {@link Zend_Media_Id3_Frame_Owne OWNE}, + * {@link Zend_Media_Id3_Frame_Rva2 RVA2}, + * {@link Zend_Media_Id3_Frame_Rvrb RVRB}, + * {@link Zend_Media_Id3_Frame_Sytc SYTC}, the text information frames (ie + * frames descendats of {@link Zend_Media_Id3_TextFrame}) and the URL + * link frames (ie frames descendants of + * {@link Zend_Media_Id3_LinkFrame}). + * + * The {@link Zend_Media_Id3_Frame_Aenc AENC}, + * {@link Zend_Media_Id3_Frame_Apic APIC}, + * {@link Zend_Media_Id3_Frame_Geob GEOB} + * and {@link Zend_Media_Id3_Frame_Txxx TXXX} frames may be linked with the + * content descriptor as additional ID data. + * + * The {@link Zend_Media_Id3_Frame_User USER} frame may be linked with the + * language field as additional ID data. + * + * The {@link Zend_Media_Id3_Frame_Priv PRIV} frame may be linked with the owner + * identifier as additional ID data. + * + * The {@link Zend_Media_Id3_Frame_Comm COMM}, + * {@link Zend_Media_Id3_Frame_Sylt SYLT} and + * {@link Zend_Media_Id3_Frame_Uslt USLT} frames may be linked with three bytes + * of language descriptor directly followed by a content descriptor as + * additional ID data. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Link extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_target; + + /** @var string */ + private $_url; + + /** @var string */ + private $_qualifier; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_target = $this->_reader->read(4); + list($this->_url, $this->_qualifier) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + } + + /** + * Returns the target tag identifier. + * + * @return string + */ + public function getTarget() + { + return $this->_target; + } + + /** + * Sets the target tag identifier. + * + * @param string $target The target tag identifier. + */ + public function setTarget($target) + { + $this->_target = $target; + } + + /** + * Returns the target tag URL. + * + * @return string + */ + public function getUrl() + { + return $this->_url; + } + + /** + * Sets the target tag URL. + * + * @param string $url The target URL. + */ + public function setUrl($url) + { + $this->_url = $url; + } + + /** + * Returns the additional data to identify further the tag. + * + * @return string + */ + public function getQualifier() + { + return $this->_qualifier; + } + + /** + * Sets the additional data to be used in tag identification. + * + * @param string $identifier The qualifier. + */ + public function setQualifier($qualifier) + { + $this->_qualifier = $qualifier; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8(substr($this->_target, 0, 4), 4) + ->writeString8($this->_url, 1) + ->writeString8($this->_qualifier); + } +} diff --git a/src/Zend/Media/Id3/Frame/Mcdi.php b/src/Zend/Media/Id3/Frame/Mcdi.php new file mode 100644 index 0000000..5a2e01e --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Mcdi.php @@ -0,0 +1,102 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Mcdi extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_data = $this->_reader->read($this->_reader->getSize()); + } + + /** + * Returns the CD TOC binary dump. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the CD TOC binary dump. + * + * @param string $data The CD TOC binary dump string. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->write($this->_data); + } +} diff --git a/src/Zend/Media/Id3/Frame/Mllt.php b/src/Zend/Media/Id3/Frame/Mllt.php new file mode 100644 index 0000000..b72d76a --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Mllt.php @@ -0,0 +1,187 @@ +MPEG location lookup table frame includes references that the + * software can use to calculate positions in the file. + * + * The MPEG frames between reference describes how much the frame counter should + * be increased for every reference. If this value is two then the first + * reference points out the second frame, the 2nd reference the 4th frame, the + * 3rd reference the 6th frame etc. In a similar way the bytes between reference + * and milliseconds between reference points out bytes and milliseconds + * respectively. + * + * Each reference consists of two parts; a certain number of bits that describes + * the difference between what is said in bytes between reference and the + * reality and a certain number of bits that describes the difference between + * what is said in milliseconds between reference and the reality. + * + * There may only be one MLLT frame in each tag. + * + * @todo Data parsing and write support + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Mllt extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_frames; + + /** @var integer */ + private $_bytes; + + /** @var integer */ + private $_milliseconds; + + /** @var Array */ + private $_deviation = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Write not supported yet'); + } + + $this->_frames = Transform::fromInt16BE(substr($this->_data, 0, 2)); + $this->_bytes = Transform::fromInt32BE(substr($this->_data, 2, 3)); + $this->_milliseconds = Transform::fromInt32BE(substr($this->_data, 5, 3)); + + $byteDevBits = Transform::fromInt8($this->_data[8]); + $millisDevBits = Transform::fromInt8($this->_data[9]); + + // $data = substr($this->_data, 10); + } + + /** + * Returns the number of MPEG frames between reference. + * + + * @return integer + */ + public function getFrames() + { + return $this->_frames; + } + + /** + * Sets the number of MPEG frames between reference. + * + + * @param integer $frames The number of MPEG frames. + */ + public function setFrames($frames) + { + $this->_frames = $frames; + } + + /** + * Returns the number of bytes between reference. + * + + * @return integer + */ + public function getBytes() + { + return $this->_bytes; + } + + /** + * Sets the number of bytes between reference. + * + + * @param integer $bytes The number of bytes. + */ + public function setBytes($bytes) + { + $this->_bytes = $bytes; + } + + /** + * Returns the number of milliseconds between references. + * + + * @return integer + */ + public function getMilliseconds() + { + return $this->_milliseconds; + } + + /** + * Sets the number of milliseconds between references. + * + + * @param integer $milliseconds The number of milliseconds. + */ + public function setMilliseconds($milliseconds) + { + return $this->_milliseconds; + } + + /** + * Returns the deviations as an array. Each value is an array containing two + * values, ie the deviation in bytes, and the deviation in milliseconds, + * respectively. + * + + * @return Array + */ + public function getDeviation() + { + return $this->_deviation; + } + + /** + * Sets the deviations array. The array must consist of arrays, each of + * which having two values, the deviation in bytes, and the deviation in + * milliseconds, respectively. + * + + * @param Array $deviation The deviations array. + */ + public function setDeviation($deviation) + { + $this->_deviation = $deviation; + } +} diff --git a/src/Zend/Media/Id3/Frame/Owne.php b/src/Zend/Media/Id3/Frame/Owne.php new file mode 100644 index 0000000..7fc3540 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Owne.php @@ -0,0 +1,258 @@ +Ownership frame might be used as a reminder of a made transaction + * or, if signed, as proof. Note that the {@link Zend_Media_Id3_Frame_User USER} + * and {@link Zend_Media_Id3_Frame_Town TOWN} frames are good to use in + * conjunction with this one. + * + * There may only be one OWNE frame in a tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Owne extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_currency = 'EUR'; + + /** @var string */ + private $_price; + + /** @var string */ + private $_date; + + /** @var string */ + private $_seller; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_currency = strtoupper($this->_reader->read(3)); + $offset = $this->_reader->getOffset(); + list ($this->_price) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset($offset + strlen($this->_price) + 1); + $this->_date = $this->_reader->read(8); + $this->_seller = $this->_convertString + ($this->_reader->read($this->_reader->getSize()), $encoding); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the currency code, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @return string + */ + public function getCurrency() + { + return $this->_currency; + } + + /** + * Sets the currency used in transaction, encoded according to + * {@link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm + * ISO 4217} alphabetic currency code. + * + * @param string $currency The currency code. + */ + public function setCurrency($currency) + { + $this->_currency = strtoupper($currency); + } + + /** + * Returns the price. + * + * @return double + */ + public function getPrice() + { + return doubleval($this->_price); + } + + /** + * Sets the price. + * + * @param integer $price The price. + */ + public function setPrice($price) + { + $this->_price = number_format($price, 2, '.', ''); + } + + /** + * Returns the date describing for how long the price is valid. + * + * @internal The ID3v2 standard does not declare the time zone to be used + * in the date. Date must thus be expressed as GMT/UTC. + * @return Zend_Date + */ + public function getDate() + { + require_once 'Zend/Date.php'; + $date = new Zend_Date(0); + $date->setTimezone('UTC'); + $date->set($this->_date, 'yyyyMMdd'); + return $date; + } + + /** + * Sets the date describing for how long the price is valid for. + * + * @internal The ID3v2 standard does not declare the time zone to be used + * in the date. Date must thus be expressed as GMT/UTC. + * @param Zend_Date $date The date. + */ + public function setDate($date) + { + require_once 'Zend/Date.php'; + if ($date === null) { + $date = Zend_Date::now(); + } + $date->setTimezone('UTC'); + $this->_date = $date->toString('yyyyMMdd'); + } + + /** + * Returns the name of the seller. + * + * @return string + */ + public function getSeller() + { + return $this->_seller; + } + + /** + * Sets the name of the seller using given encoding. + * + * @param string $seller The name of the seller. + * @param integer $encoding The text encoding. + */ + public function setSeller($seller, $encoding = null) + { + $this->_seller = $seller; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_currency) + ->writeString8($this->_price, 1) + ->write($this->_date); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_seller, Zend_Io_Writer::LITTLE_ENDIAN_ORDER); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_seller); + break; + default: + $writer->writeString8($this->_seller); + break; + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Pcnt.php b/src/Zend/Media/Id3/Frame/Pcnt.php new file mode 100644 index 0000000..250c39c --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Pcnt.php @@ -0,0 +1,110 @@ +Play counter is simply a counter of the number of times a file has + * been played. The value is increased by one every time the file begins to + * play. There may only be one PCNT frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Pcnt extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_counter = 0; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + if ($this->_reader->getSize() > 4) { + $this->_counter = $this->_reader->readInt64BE(); // UInt64 + } else { + $this->_counter = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns the counter. + * + * @return integer + */ + public function getCounter() + { + return $this->_counter; + } + + /** + * Adds counter by one. + */ + public function addCounter() + { + $this->_counter++; + } + + /** + * Sets the counter value. + * + * @param integer $counter The counter value. + */ + public function setCounter($counter) + { + $this->_counter = $counter; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + if ($this->_counter > 4294967295) { + $writer->writeInt64BE($this->_counter); // UInt64 + } else { + $writer->writeUInt32BE($this->_counter); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Popm.php b/src/Zend/Media/Id3/Frame/Popm.php new file mode 100644 index 0000000..4d8d04f --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Popm.php @@ -0,0 +1,176 @@ +Popularimeter frame is to specify how good an audio + * file is. Many interesting applications could be found to this frame such as a + * playlist that features better audio files more often than others or it could + * be used to profile a person's taste and find other good files by comparing + * people's profiles. The frame contains the email address to the user, one + * rating byte and a four byte play counter, intended to be increased with one + * for every time the file is played. + * + * The rating is 1-255 where 1 is worst and 255 is best. 0 is unknown. If no + * personal counter is wanted it may be omitted. When the counter reaches all + * one's, one byte is inserted in front of the counter thus making the counter + * eight bits bigger in the same away as the play counter + * {@link Zend_Media_Id3_Frame_Pcnt PCNT}. There may be more than one POPM frame + * in each tag, but only one with the same email address. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Popm extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var integer */ + private $_rating = 0; + + /** @var integer */ + private $_counter = 0; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list ($this->_owner) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(strlen($this->_owner) + 1); + $this->_rating = $this->_reader->readUInt8(); + + if ($this->_reader->getSize() - strlen($this->_owner) - 2 > 4) { + $this->_counter = + $this->_reader->readInt64BE(); // UInt64 + } else if ($this->_reader->available() > 0) { + $this->_counter = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + return $this->_owner = $owner; + } + + /** + * Returns the user rating. + * + * @return integer + */ + public function getRating() + { + return $this->_rating; + } + + /** + * Sets the user rating. + * + * @param integer $rating The user rating. + */ + public function setRating($rating) + { + $this->_rating = $rating; + } + + /** + * Returns the counter. + * + * @return integer + */ + public function getCounter() + { + return $this->_counter; + } + + /** + * Adds counter by one. + */ + public function addCounter() + { + $this->_counter++; + } + + /** + * Sets the counter value. + * + * @param integer $counter The counter value. + */ + public function setCounter($counter) + { + $this->_counter = $counter; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->writeInt8($this->_rating); + if ($this->_counter > 0xffffffff) { + $writer->writeInt64BE($this->_counter); + } else if ($this->_counter > 0) { + $writer->writeUInt32BE($this->_counter); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Poss.php b/src/Zend/Media/Id3/Frame/Poss.php new file mode 100644 index 0000000..265f9f7 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Poss.php @@ -0,0 +1,129 @@ +Position synchronisation frame delivers information to the + * listener of how far into the audio stream he picked up; in effect, it states + * the time offset from the first frame in the stream. There may only be one + * POSS frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Poss extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Timing +{ + /** @var integer */ + private $_format = Zend_Media_Id3_Timing::MPEG_FRAMES; + + /** @var integer */ + private $_position; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_format = $this->_reader->readUInt8(); + $this->_position = $this->_reader->readUInt32BE(); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() + { + return $this->_format; + } + + /** + * Sets the timing format. + * + * @see Zend_Media_Id3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) + { + $this->_format = $format; + } + + /** + * Returns the position where in the audio the listener starts to receive, + * i.e. the beginning of the next frame. + * + * @return integer + */ + public function getPosition() + { + return $this->_position; + } + + /** + * Sets the position where in the audio the listener starts to receive, + * i.e. the beginning of the next frame, using given format. + * + * @param integer $position The position. + * @param integer $format The timing format. + */ + public function setPosition($position, $format = null) + { + $this->_position = $position; + if ($format !== null) { + $this->setFormat($format); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_format) + ->writeUInt32BE($this->_position); + } +} diff --git a/src/Zend/Media/Id3/Frame/Priv.php b/src/Zend/Media/Id3/Frame/Priv.php new file mode 100644 index 0000000..9cffd28 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Priv.php @@ -0,0 +1,125 @@ +Private frame is used to contain information from a software + * producer that its program uses and does not fit into the other frames. The + * frame consists of an owner identifier string and the binary data. The owner + * identifier is URL containing an email address, or a link to a location where + * an email address can be found, that belongs to the organisation responsible + * for the frame. Questions regarding the frame should be sent to the indicated + * email address. The tag may contain more than one PRIV frame but only with + * different contents. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Priv extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var string */ + private $_data; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list($this->_owner, $this->_data) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + $this->_owner = $owner; + } + + /** + * Returns the private binary data associated with the frame. + * + * @return string + */ + public function getData() + { + return $this->_data; + } + + /** + * Sets the private binary data associated with the frame. + * + * @param string $data The private binary data string. + */ + public function setData($data) + { + $this->_data = $data; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->write($this->_data); + } +} diff --git a/src/Zend/Media/Id3/Frame/Rbuf.php b/src/Zend/Media/Id3/Frame/Rbuf.php new file mode 100644 index 0000000..c5046ad --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Rbuf.php @@ -0,0 +1,190 @@ +Recommended buffer size frame. If the embedded info + * flag is set then this indicates that an ID3 tag with the maximum size + * described in buffer size may occur in the audio stream. In such case the tag + * should reside between two MPEG frames, if the audio is MPEG encoded. If the + * position of the next tag is known, offset to next tag may be used. The offset + * is calculated from the end of tag in which this frame resides to the first + * byte of the header in the next. This field may be omitted. Embedded tags are + * generally not recommended since this could render unpredictable behaviour + * from present software/hardware. + * + * For applications like streaming audio it might be an idea to embed tags into + * the audio stream though. If the clients connects to individual connections + * like HTTP and there is a possibility to begin every transmission with a tag, + * then this tag should include a recommended buffer size frame. If the client + * is connected to a arbitrary point in the stream, such as radio or multicast, + * then the recommended buffer size frame should be included in every tag. + * + * The buffer size should be kept to a minimum. There may only be one RBUF + * frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Rbuf extends Zend_Media_Id3_Frame +{ + /** + * A flag to denote that an ID3 tag with the maximum size described in + * buffer size may occur in the audio stream. + */ + const EMBEDDED = 0x1; + + /** @var integer */ + private $_bufferSize; + + /** @var integer */ + private $_infoFlags; + + /** @var integer */ + private $_offset = 0; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + // Who designs frames with 3 byte integers?? + $this->_reader = new Zend_Io_StringReader + ("\0" . $this->_reader->read($this->_reader->getSize())); + + $this->_bufferSize = $this->_reader->readUInt32BE(); + $this->_infoFlags = $this->_reader->readInt8(); + if ($this->_reader->available()) { + $this->_offset = $this->_reader->readInt32BE(); + } + } + + /** + * Returns the buffer size. + * + * @return integer + */ + public function getBufferSize() + { + return $this->_bufferSize; + } + + /** + * Sets the buffer size. + * + * @param integer $size The buffer size. + */ + public function setBufferSize($bufferSize) + { + $this->_bufferSize = $bufferSize; + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasInfoFlag($flag) + { + return ($this->_infoFlags & $flag) == $flag; + } + + /** + * Returns the flags byte. + * + * @return integer + */ + public function getInfoFlags() + { + return $this->_infoFlags; + } + + /** + * Sets the flags byte. + * + * @param string $flags The flags byte. + */ + public function setInfoFlags($infoFlags) + { + $this->_infoFlags = $infoFlags; + } + + /** + * Returns the offset to next tag. + * + * @return integer + */ + public function getOffset() + { + return $this->_offset; + } + + /** + * Sets the offset to next tag. + * + * @param integer $offset The offset. + */ + public function setOffset($offset) + { + $this->_offset = $offset; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $tmp = new Zend_Io_StringWriter(); + $tmp->writeUInt32BE($this->_bufferSize); + + $writer->write(substr($tmp->toString(), 1, 3)) + ->writeInt8($this->_infoFlags) + ->writeInt32BE($this->_offset); + } +} diff --git a/src/Zend/Media/Id3/Frame/Rva2.php b/src/Zend/Media/Id3/Frame/Rva2.php new file mode 100644 index 0000000..13f35df --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Rva2.php @@ -0,0 +1,213 @@ +Relative volume adjustment (2) frame is a more subjective frame + * than the previous ones. It allows the user to say how much he wants to + * increase/decrease the volume on each channel when the file is played. The + * purpose is to be able to align all files to a reference volume, so that you + * don't have to change the volume constantly. This frame may also be used to + * balance adjust the audio. + * + * The volume adjustment is encoded in a way giving the scale of +/- 64 dB with + * a precision of 0.001953125 dB. + * + * There may be more than one RVA2 frame in each tag, but only one with the same + * identification string. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Rva2 extends Zend_Media_Id3_Frame +{ + /** + * The channel type key. + * + * @see $types + * @var string + */ + const channelType = 'channelType'; + + /** + * The volume adjustment key. Adjustments are +/- 64 dB with a precision of + * 0.001953125 dB. + * + * @var string + */ + const volumeAdjustment = 'volumeAdjustment'; + + /** + * The peak volume key. + * + * @var string + */ + const peakVolume = 'peakVolume'; + + /** + * The list of channel types. + * + * @var Array + */ + public static $types = array + ('Other', 'Master volume', 'Front right', 'Front left', 'Back right', + 'Back left', 'Front centre', 'Back centre', 'Subwoofer'); + + /** @var string */ + private $_device; + + /** @var Array */ + private $_adjustments; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list ($this->_device) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset(strlen($this->_device) + 1); + + for ($i = $j = 0; $i < 9; $i++) { + $this->_adjustments[$i] = array + (self::channelType => $this->_reader->readInt8(), + self::volumeAdjustment => + $this->_reader->readInt16BE() / 512.0); + $bitsInPeak = $this->_reader->readInt8(); + $bytesInPeak = $bitsInPeak > 0 ? ceil($bitsInPeak / 8) : 0; + switch ($bytesInPeak) { + case 8: + $this->_adjustments[$i][self::peakVolume] = + $this->_reader->readInt64BE(); + break; + case 4: + $this->_adjustments[$i][self::peakVolume] = + $this->_reader->readUInt32BE(); + break; + case 2: + $this->_adjustments[$i][self::peakVolume] = + $this->_reader->readUInt16BE(); + break; + case 1: + $this->_adjustments[$i][self::peakVolume] = + $this->_reader->readUInt8(); + break; + default: + break; + } + } + } + + /** + * Returns the device where the adjustments should apply. + * + * @return string + */ + public function getDevice() + { + return $this->_device; + } + + /** + * Sets the device where the adjustments should apply. + * + * @param string $device The device. + */ + public function setDevice($device) + { + $this->_device = $device; + } + + /** + * Returns the array containing volume adjustments for each channel. Volume + * adjustments are arrays themselves containing the following keys: + * channelType, volumeAdjustment, peakVolume. + * + * @return Array + */ + public function getAdjustments() + { + return $this->_adjustments; + } + + /** + * Sets the array of volume adjustments for each channel. Each volume + * adjustment is an array too containing the following keys: channelType, + * volumeAdjustment, peakVolume. + * + * @param Array $adjustments The volume adjustments array. + */ + public function setAdjustments($adjustments) + { + $this->_adjustments = $adjustments; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_device, 1); + foreach ($this->_adjustments as $channel) { + $writer->writeInt8($channel[self::channelType]) + ->writeInt16BE($channel[self::volumeAdjustment] * 512); + if (abs($channel[self::peakVolume]) <= 0xff) { + $writer->writeInt8(8) + ->writeUInt8($channel[self::peakVolume]); + } else if (abs($channel[self::peakVolume]) <= 0xffff) { + $writer->writeInt8(16) + ->writeUInt16BE($channel[self::peakVolume]); + } else if (abs($channel[self::peakVolume]) <= 0xffffffff) { + $writer->writeInt8(32) + ->writeUInt32BE($channel[self::peakVolume]); + } else { + $writer->writeInt8(64) + ->writeInt64BE($channel[self::peakVolume]); // UInt64 + } + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Rvad.php b/src/Zend/Media/Id3/Frame/Rvad.php new file mode 100644 index 0000000..622770b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Rvad.php @@ -0,0 +1,238 @@ +Relative volume adjustment frame is a more subjective function + * than the previous ones. It allows the user to say how much he wants to + * increase/decrease the volume on each channel while the file is played. The + * purpose is to be able to align all files to a reference volume, so that you + * don't have to change the volume constantly. This frame may also be used to + * balance adjust the audio. + * + * There may only be one RVAD frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Rvad extends Zend_Media_Id3_Frame +{ + /* The required keys. */ + + /** @var string */ + const right = 'right'; + + /** @var string */ + const left = 'left'; + + /** @var string */ + const peakRight = 'peakRight'; + + /** @var string */ + const peakLeft = 'peakLeft'; + + /* The optional keys. */ + + /** @var string */ + const rightBack = 'rightBack'; + + /** @var string */ + const leftBack = 'leftBack'; + + /** @var string */ + const peakRightBack = 'peakRightBack'; + + /** @var string */ + const peakLeftBack = 'peakLeftBack'; + + /** @var string */ + const center = 'center'; + + /** @var string */ + const peakCenter = 'peakCenter'; + + /** @var string */ + const bass = 'bass'; + + /** @var string */ + const peakBass = 'peakBass'; + + /** @var Array */ + private $_adjustments; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $flags = $this->_reader->readInt8(); + $descriptionBits = $this->_reader->readInt8(); + if ($descriptionBits <= 8 || $descriptionBits > 16) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('Unsupported description bit size of: ' . $descriptionBits); + } + + $this->_adjustments[self::right] = + ($flags & 0x1) == 0x1 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::left] = + ($flags & 0x2) == 0x2 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::peakRight] = $this->_reader->readUInt16BE(); + $this->_adjustments[self::peakLeft] = $this->_reader->readUInt16BE(); + + if (!$this->_reader->available()) { + return; + } + + $this->_adjustments[self::rightBack] = + ($flags & 0x4) == 0x4 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::leftBack] = + ($flags & 0x8) == 0x8 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::peakRightBack] = + $this->_reader->readUInt16BE(); + $this->_adjustments[self::peakLeftBack] = + $this->_reader->readUInt16BE(); + + if (!$this->_reader->available()) { + return; + } + + $this->_adjustments[self::center] = + ($flags & 0x10) == 0x10 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::peakCenter] = $this->_reader->readUInt16BE(); + + if (!$this->_reader->available()) { + return; + } + + $this->_adjustments[self::bass] = + ($flags & 0x20) == 0x20 ? + $this->_reader->readUInt16BE() : -$this->_reader->readUInt16BE(); + $this->_adjustments[self::peakBass] = $this->_reader->readUInt16BE(); + } + + /** + * Returns the array containing the volume adjustments. The array must + * contain the following keys: right, left, peakRight, peakLeft. It may + * optionally contain the following keys: rightBack, leftBack, + * peakRightBack, peakLeftBack, center, peakCenter, bass, and peakBass. + * + * @return Array + */ + public function getAdjustments() + { + return $this->_adjustments; + } + + /** + * Sets the array of volume adjustments. The array must contain the + * following keys: right, left, peakRight, peakLeft. It may optionally + * contain the following keys: rightBack, leftBack, peakRightBack, + * peakLeftBack, center, peakCenter, bass, and peakBass. + * + * @param Array $adjustments The volume adjustments array. + */ + public function setAdjustments($adjustments) + { + $this->_adjustments = $adjustments; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeInt8($flags = 0); + if ($this->_adjustments[self::right] > 0) + $flags = $flags | 0x1; + if ($this->_adjustments[self::left] > 0) + $flags = $flags | 0x2; + $writer->writeInt8(16) + ->writeUInt16BE(abs($this->_adjustments[self::right])) + ->writeUInt16BE(abs($this->_adjustments[self::left])) + ->writeUInt16BE(abs($this->_adjustments[self::peakRight])) + ->writeUInt16BE(abs($this->_adjustments[self::peakLeft])); + + if (isset($this->_adjustments[self::rightBack]) && + isset($this->_adjustments[self::leftBack]) && + isset($this->_adjustments[self::peakRightBack]) && + isset($this->_adjustments[self::peakLeftBack])) { + if ($this->_adjustments[self::rightBack] > 0) + $flags = $flags | 0x4; + if ($this->_adjustments[self::leftBack] > 0) + $flags = $flags | 0x8; + $writer->writeUInt16BE(abs($this->_adjustments[self::rightBack])) + ->writeUInt16BE(abs($this->_adjustments[self::leftBack])) + ->writeUInt16BE + (abs($this->_adjustments[self::peakRightBack])) + ->writeUInt16BE + (abs($this->_adjustments[self::peakLeftBack])); + } + + if (isset($this->_adjustments[self::center]) && + isset($this->_adjustments[self::peakCenter])) { + if ($this->_adjustments[self::center] > 0) + $flags = $flags | 0x10; + $writer->writeUInt16BE(abs($this->_adjustments[self::center])) + ->writeUInt16BE(abs($this->_adjustments[self::peakCenter])); + } + + if (isset($this->_adjustments[self::bass]) && + isset($this->_adjustments[self::peakBass])) { + if ($this->_adjustments[self::bass] > 0) + $flags = $flags | 0x20; + $writer->writeUInt16BE(abs($this->_adjustments[self::bass])) + ->writeUInt16BE(abs($this->_adjustments[self::peakBass])); + } + $writer->setOffset(0); + $writer->writeInt8($flags); + } +} diff --git a/src/Zend/Media/Id3/Frame/Rvrb.php b/src/Zend/Media/Id3/Frame/Rvrb.php new file mode 100644 index 0000000..3edff59 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Rvrb.php @@ -0,0 +1,331 @@ +Reverb is yet another subjective frame, with which you can adjust + * echoes of different kinds. Reverb left/right is the delay between every + * bounce in milliseconds. Reverb bounces left/right is the number of bounces + * that should be made. $FF equals an infinite number of bounces. Feedback is + * the amount of volume that should be returned to the next echo bounce. $00 is + * 0%, $FF is 100%. If this value were $7F, there would be 50% volume reduction + * on the first bounce, 50% of that on the second and so on. Left to left means + * the sound from the left bounce to be played in the left speaker, while left + * to right means sound from the left bounce to be played in the right speaker. + * + * Premix left to right is the amount of left sound to be mixed in the right + * before any reverb is applied, where $00 id 0% and $FF is 100%. Premix right + * to left does the same thing, but right to left. Setting both premix to $FF + * would result in a mono output (if the reverb is applied symmetric). There + * may only be one RVRB frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Rvrb extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_reverbLeft; + + /** @var integer */ + private $_reverbRight; + + /** @var integer */ + private $_reverbBouncesLeft; + + /** @var integer */ + private $_reverbBouncesRight; + + /** @var integer */ + private $_reverbFeedbackLtoL; + + /** @var integer */ + private $_reverbFeedbackLtoR; + + /** @var integer */ + private $_reverbFeedbackRtoR; + + /** @var integer */ + private $_reverbFeedbackRtoL; + + /** @var integer */ + private $_premixLtoR; + + /** @var integer */ + private $_premixRtoL; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_reverbLeft = $this->_reader->readUInt16BE(); + $this->_reverbRight = $this->_reader->readUInt16BE(); + $this->_reverbBouncesLeft = $this->_reader->readUInt8(); + $this->_reverbBouncesRight = $this->_reader->readUInt8(); + $this->_reverbFeedbackLtoL = $this->_reader->readUInt8(); + $this->_reverbFeedbackLtoR = $this->_reader->readUInt8(); + $this->_reverbFeedbackRtoR = $this->_reader->readUInt8(); + $this->_reverbFeedbackRtoL = $this->_reader->readUInt8(); + $this->_premixLtoR = $this->_reader->readUInt8(); + $this->_premixRtoL = $this->_reader->readUInt8(); + } + + /** + * Returns the left reverb. + * + * @return integer + */ + public function getReverbLeft() + { + return $this->_reverbLeft; + } + + /** + * Sets the left reverb. + * + * @param integer $reverbLeft The left reverb. + */ + public function setReverbLeft($reverbLeft) + { + return $this->_reverbLeft = $reverbLeft; + } + + /** + * Returns the right reverb. + * + * @return integer + */ + public function getReverbRight() + { + return $this->_reverbRight; + } + + /** + * Sets the right reverb. + * + * @param integer $reverbRight The right reverb. + */ + public function setReverbRight($reverbRight) + { + return $this->_reverbRight = $reverbRight; + } + + /** + * Returns the left reverb bounces. + * + * @return integer + */ + public function getReverbBouncesLeft() + { + return $this->_reverbBouncesLeft; + } + + /** + * Sets the left reverb bounces. + * + * @param integer $reverbBouncesLeft The left reverb bounces. + */ + public function setReverbBouncesLeft($reverbBouncesLeft) + { + $this->_reverbBouncesLeft = $reverbBouncesLeft; + } + + /** + * Returns the right reverb bounces. + * + * @return integer + */ + public function getReverbBouncesRight() + { + return $this->_reverbBouncesRight; + } + + /** + * Sets the right reverb bounces. + * + * @param integer $reverbBouncesRight The right reverb bounces. + */ + public function setReverbBouncesRight($reverbBouncesRight) + { + $this->_reverbBouncesRight = $reverbBouncesRight; + } + + /** + * Returns the left-to-left reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackLtoL() + { + return $this->_reverbFeedbackLtoL; + } + + /** + * Sets the left-to-left reverb feedback. + * + * @param integer $reverbFeedbackLtoL The left-to-left reverb feedback. + */ + public function setReverbFeedbackLtoL($reverbFeedbackLtoL) + { + $this->_reverbFeedbackLtoL = $reverbFeedbackLtoL; + } + + /** + * Returns the left-to-right reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackLtoR() + { + return $this->_reverbFeedbackLtoR; + } + + /** + * Sets the left-to-right reverb feedback. + * + * @param integer $reverbFeedbackLtoR The left-to-right reverb feedback. + */ + public function setReverbFeedbackLtoR($reverbFeedbackLtoR) + { + $this->_reverbFeedbackLtoR = $reverbFeedbackLtoR; + } + + /** + * Returns the right-to-right reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackRtoR() + { + return $this->_reverbFeedbackRtoR; + } + + /** + * Sets the right-to-right reverb feedback. + * + * @param integer $reverbFeedbackRtoR The right-to-right reverb feedback. + */ + public function setReverbFeedbackRtoR($reverbFeedbackRtoR) + { + $this->_reverbFeedbackRtoR = $reverbFeedbackRtoR; + } + + /** + * Returns the right-to-left reverb feedback. + * + * @return integer + */ + public function getReverbFeedbackRtoL() + { + return $this->_reverbFeedbackRtoL; + } + + /** + * Sets the right-to-left reverb feedback. + * + * @param integer $reverbFeedbackRtoL The right-to-left reverb feedback. + */ + public function setReverbFeedbackRtoL($reverbFeedbackRtoL) + { + $this->_reverbFeedbackRtoL = $reverbFeedbackRtoL; + } + + /** + * Returns the left-to-right premix. + * + * @return integer + */ + public function getPremixLtoR() + { + return $this->_premixLtoR; + } + + /** + * Sets the left-to-right premix. + * + * @param integer $premixLtoR The left-to-right premix. + */ + public function setPremixLtoR($premixLtoR) + { + $this->_premixLtoR = $premixLtoR; + } + + /** + * Returns the right-to-left premix. + * + * @return integer + */ + public function getPremixRtoL() + { + return $this->_premixRtoL; + } + + /** + * Sets the right-to-left premix. + * + * @param integer $premixRtoL The right-to-left premix. + */ + public function setPremixRtoL($premixRtoL) + { + $this->_premixRtoL = $premixRtoL; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt16BE($this->_reverbLeft) + ->writeUInt16BE($this->_reverbRight) + ->writeUInt8($this->_reverbBouncesLeft) + ->writeUInt8($this->_reverbBouncesRight) + ->writeUInt8($this->_reverbFeedbackLtoL) + ->writeUInt8($this->_reverbFeedbackLtoR) + ->writeUInt8($this->_reverbFeedbackRtoR) + ->writeUInt8($this->_reverbFeedbackRtoL) + ->writeUInt8($this->_premixLtoR) + ->writeUInt8($this->_premixRtoL); + } +} diff --git a/src/Zend/Media/Id3/Frame/Seek.php b/src/Zend/Media/Id3/Frame/Seek.php new file mode 100644 index 0000000..102e121 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Seek.php @@ -0,0 +1,95 @@ +Seek frame indicates where other tags in a file/stream can be + * found. The minimum offset to next tag is calculated from the end of this tag + * to the beginning of the next. There may only be one seek frame in a tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Seek extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_minOffset; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_minOffset = $this->_reader->readInt32BE(); + } + + /** + * Returns the minimum offset to next tag in bytes. + * + * @return integer + */ + public function getMinimumOffset() + { + return $this->_minOffset; + } + + /** + * Sets the minimum offset to next tag in bytes. + * + * @param integer $minOffset The minimum offset. + */ + public function setMinimumOffset($minOffset) + { + $this->_minOffset = $minOffset; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeInt32BE($this->_minOffset); + } +} diff --git a/src/Zend/Media/Id3/Frame/Sign.php b/src/Zend/Media/Id3/Frame/Sign.php new file mode 100644 index 0000000..a3b4692 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Sign.php @@ -0,0 +1,123 @@ +Group identification registration, to be signed. Although signatures + * can reside inside the registration frame, it might be desired to store the + * signature elsewhere, e.g. in watermarks. There may be more than one signature + * frame in a tag, but no two may be identical. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Sign extends Zend_Media_Id3_Frame +{ + /** @var integer */ + private $_group; + + /** @var string */ + private $_signature; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $this->_group = $this->_reader->readUInt8(); + $this->_signature = $this->_reader->read($this->_reader->getSize()); + } + + /** + * Returns the group symbol byte. + * + * @return integer + */ + public function getGroup() + { + return $this->_group; + } + + /** + * Sets the group symbol byte. + * + * @param integer $group The group symbol byte. + */ + public function setGroup($group) + { + $this->_group = $group; + } + + /** + * Returns the signature binary data. + * + * @return string + */ + public function getSignature() + { + return $this->_signature; + } + + /** + * Sets the signature binary data. + * + * @param string $signature The signature binary data string. + */ + public function setSignature($signature) + { + $this->_signature = $signature; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_group) + ->write($this->_signature); + } +} diff --git a/src/Zend/Media/Id3/Frame/Sylt.php b/src/Zend/Media/Id3/Frame/Sylt.php new file mode 100644 index 0000000..74f6a11 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Sylt.php @@ -0,0 +1,371 @@ +Synchronised lyrics/text frame is another way of incorporating the + * words, said or sung lyrics, in the audio file as text, this time, however, + * in sync with the audio. It might also be used to describing events e.g. + * occurring on a stage or on the screen in sync with the audio. + * + * There may be more than one SYLT frame in each tag, but only one with the + * same language and content descriptor. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_SYLT extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding, Zend_Media_Id3_Language, + Zend_Media_Id3_Timing +{ + /** + * The list of content types. + * + * @var Array + */ + public static $types = array + ('Other', 'Lyrics', 'Text transcription', 'Movement/Part name', + 'Events', 'Chord', 'Trivia', 'URLs to webpages', 'URLs to images'); + + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_language = 'und'; + + /** @var integer */ + private $_format = Zend_Media_Id3_Timing::MPEG_FRAMES; + + /** @var integer */ + private $_type = 0; + + /** @var string */ + private $_description; + + /** @var Array */ + private $_events = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_language = strtolower($this->_reader->read(3)); + if ($this->_language == 'xxx') { + $this->_language = 'und'; + } + $this->_format = $this->_reader->readUInt8(); + $this->_type = $this->_reader->readUInt8(); + + $offset = $this->_reader->getOffset(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($this->_description) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset + ($offset + strlen($this->_description) + 2); + break; + case self::UTF8: + // break intentionally omitted + default: + list($this->_description) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_reader->setOffset + ($offset + strlen($this->_description) + 1); + break; + } + $this->_description = + $this->_convertString($this->_description, $encoding); + + while ($this->_reader->available()) { + $offset = $this->_reader->getOffset(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($syllable) = + $this->_explodeString16 + ($this->_reader->read + ($this->_reader->getSize()), 2); + $this->_reader->setOffset + ($offset + strlen($syllable) + 2); + break; + case self::UTF8: + // break intentionally omitted + default: + list($syllable) = + $this->_explodeString8 + ($this->_reader->read + ($this->_reader->getSize()), 2); + $this->_reader->setOffset + ($offset + strlen($syllable) + 1); + break; + } + $this->_events + [$this->_reader->readUInt32BE()] = + $this->_convertString($syllable, $encoding); + } + ksort($this->_events); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @return string + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see Zend_Media_Id3_Language + * @param string $language The language code. + */ + public function setLanguage($language) + { + $language = strtolower($language); + if ($language == 'xxx') { + $language = 'und'; + } + $this->_language = substr($language, 0, 3); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() + { + return $this->_format; + } + + /** + * Sets the timing format. + * + * @see Zend_Media_Id3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) + { + $this->_format = $format; + } + + /** + * Returns the content type code. + * + * @return integer + */ + public function getType() + { + return $this->_type; + } + + /** + * Sets the content type code. + * + * @param integer $type The content type code. + */ + public function setType($type) + { + $this->_type = $type; + } + + /** + * Returns the content description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription + ($description, $language = null, $encoding = null) + { + $this->_description = $description; + if ($language !== null) { + $this->setLanguage($language); + } + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Returns the syllable events with their timestamps. + * + * @return Array + */ + public function getEvents() + { + return $this->_events; + } + + /** + * Sets the syllable events with their timestamps using given encoding. + * + * The text language and encoding must be that of the description text. + * + * @param Array $text The test string. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setEvents($events, $language = null, $encoding = null) + { + $this->_events = $events; + if ($language !== null) { + $this->setLanguage($language); + } + if ($encoding !== null) { + $this->setEncoding($encoding); + } + ksort($this->_events); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_language) + ->writeUInt8($this->_format) + ->writeUInt8($this->_type); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1); + break; + default: + $writer->writeString8($this->_description, 1); + break; + } + foreach ($this->_events as $timestamp => $syllable) { + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($syllable, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($syllable, null, 1); + break; + default: + $writer->writeString8($syllable, 1); + break; + } + $writer->writeUInt32BE($timestamp); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Sytc.php b/src/Zend/Media/Id3/Frame/Sytc.php new file mode 100644 index 0000000..df2698a --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Sytc.php @@ -0,0 +1,157 @@ +Synchronised tempo codes frame might be used. + * + * The tempo data consists of one or more tempo codes. Each tempo code consists + * of one tempo part and one time part. The tempo is in BPM described with one + * or two bytes. If the first byte has the value $FF, one more byte follows, + * which is added to the first giving a range from 2 - 510 BPM, since $00 and + * $01 is reserved. $00 is used to describe a beat-free time period, which is + * not the same as a music-free time period. $01 is used to indicate one single + * beat-stroke followed by a beat-free period. + * + * The tempo descriptor is followed by a time stamp. Every time the tempo in the + * music changes, a tempo descriptor may indicate this for the player. All tempo + * descriptors must be sorted in chronological order. The first beat-stroke in + * a time-period is at the same time as the beat description occurs. There may + * only be one SYTC frame in each tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Sytc extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Timing +{ + /** Describes a beat-free time period. */ + const BEAT_FREE = 0x00; + + /** Indicate one single beat-stroke followed by a beat-free period. */ + const SINGLE_BEAT = 0x01; + + /** @var integer */ + private $_format = Zend_Media_Id3_Timing::MPEG_FRAMES; + + /** @var Array */ + private $_events = array(); + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + $offset = 0; + $this->_format = $this->_reader->readUInt8(); + while ($this->_reader->available()) { + $tempo = $this->_reader->readUInt8(); + if ($tempo == 0xff) + $tempo += $this->_reader->readUInt8(); + $this->_events[$this->_reader->readUInt32BE()] = $tempo; + } + ksort($this->_events); + } + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat() + { + return $this->_format; + } + + /** + * Sets the timing format. + * + * @see Zend_Media_Id3_Timing + * @param integer $format The timing format. + */ + public function setFormat($format) + { + $this->_format = $format; + } + + /** + * Returns the time-bpm tempo events. + * + * @return Array + */ + public function getEvents() + { + return $this->_events; + } + + /** + * Sets the time-bpm tempo events. + * + * @param Array $events The time-bpm tempo events. + */ + public function setEvents($events) + { + $this->_events = $events; + ksort($this->_events); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_format); + foreach ($this->_events as $timestamp => $tempo) { + if ($tempo >= 0xff) { + $writer->writeUInt8(0xff) + ->writeUInt8($tempo - 0xff); + } else { + $writer->writeUInt8($tempo); + } + $writer->writeUInt32BE($timestamp); + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Talb.php b/src/Zend/Media/Id3/Frame/Talb.php new file mode 100644 index 0000000..cd055e9 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Talb.php @@ -0,0 +1,40 @@ +Album/Movie/Show title frame is intended for the title of the + * recording (or source of sound) from which the audio in the file is taken. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Talb extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tbpm.php b/src/Zend/Media/Id3/Frame/Tbpm.php new file mode 100644 index 0000000..41f43a9 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tbpm.php @@ -0,0 +1,40 @@ +BPM frame contains the number of beats per minute in the main part + * of the audio. The BPM is an integer and represented as a numerical string. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tbpm extends Zend_Media_Id3_NumberFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tcom.php b/src/Zend/Media/Id3/Frame/Tcom.php new file mode 100644 index 0000000..75a45c5 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tcom.php @@ -0,0 +1,39 @@ +Composer frame is intended for the name of the composer. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tcom extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tcon.php b/src/Zend/Media/Id3/Frame/Tcon.php new file mode 100644 index 0000000..030dd61 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tcon.php @@ -0,0 +1,49 @@ +Content type, which ID3v1 was stored as a one byte numeric value + * only, is now a string. You may use one or several of the ID3v1 types as + * numerical strings, or, since the category list would be impossible to + * maintain with accurate and up to date categories, define your own. + * + * You may also use any of the following keywords: + * + *
    + *  RX  Remix
    + *  CR  Cover
    + * 
    + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tcon extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tcop.php b/src/Zend/Media/Id3/Frame/Tcop.php new file mode 100644 index 0000000..9678164 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tcop.php @@ -0,0 +1,46 @@ +Copyright message frame, in which the string must begin with a + * year and a space character (making five characters), is intended for the + * copyright holder of the original sound, not the audio file itself. The + * absence of this frame means only that the copyright information is + * unavailable or has been removed, and must not be interpreted to mean that the + * audio is public domain. Every time this field is displayed the field must be + * preceded with 'Copyright ' (C) ' ', where (C) is one character showing a C in + * a circle. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tcop extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tdat.php b/src/Zend/Media/Id3/Frame/Tdat.php new file mode 100644 index 0000000..9b5b571 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdat.php @@ -0,0 +1,42 @@ +Date frame is a numeric string in the DDMM format containing the + * date for the recording. This field is always four characters long. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Tdat extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tden.php b/src/Zend/Media/Id3/Frame/Tden.php new file mode 100644 index 0000000..d1cc911 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tden.php @@ -0,0 +1,42 @@ +Encoding time frame contains a timestamp describing when the audio + * was encoded. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tden extends Zend_Media_Id3_DateFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tdly.php b/src/Zend/Media/Id3/Frame/Tdly.php new file mode 100644 index 0000000..489afe4 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdly.php @@ -0,0 +1,41 @@ +Playlist delay defines the numbers of milliseconds of silence that + * should be inserted before this audio. The value zero indicates that this is a + * part of a multifile audio track that should be played continuously. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tdly extends Zend_Media_Id3_NumberFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tdor.php b/src/Zend/Media/Id3/Frame/Tdor.php new file mode 100644 index 0000000..22eac5f --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdor.php @@ -0,0 +1,42 @@ +Original release time frame contains a timestamp describing when + * the original recording of the audio was released. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tdor extends Zend_Media_Id3_DateFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tdrc.php b/src/Zend/Media/Id3/Frame/Tdrc.php new file mode 100644 index 0000000..d2d28b3 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdrc.php @@ -0,0 +1,43 @@ +Recording time frame contains a timestamp describing when the + * audio was recorded. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tdrc extends Zend_Media_Id3_DateFrame +{ +} diff --git a/src/Zend/Media/Id3/Frame/Tdrl.php b/src/Zend/Media/Id3/Frame/Tdrl.php new file mode 100644 index 0000000..3bfe57b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdrl.php @@ -0,0 +1,42 @@ +Release time frame contains a timestamp describing when the audio + * was first released. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tdrl extends Zend_Media_Id3_DateFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tdtg.php b/src/Zend/Media/Id3/Frame/Tdtg.php new file mode 100644 index 0000000..9b5dbe0 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tdtg.php @@ -0,0 +1,42 @@ +Tagging time frame contains a timestamp describing then the audio + * was tagged. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tdtg extends Zend_Media_Id3_DateFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tenc.php b/src/Zend/Media/Id3/Frame/Tenc.php new file mode 100644 index 0000000..c0c483b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tenc.php @@ -0,0 +1,41 @@ +Encoded by frame contains the name of the person or organisation + * that encoded the audio file. This field may contain a copyright message, if + * the audio file also is copyrighted by the encoder. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tenc extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Text.php b/src/Zend/Media/Id3/Frame/Text.php new file mode 100644 index 0000000..11c169e --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Text.php @@ -0,0 +1,40 @@ +Lyricist/Text writer frame is intended for the writer of the text + * or lyrics in the recording. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Text extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tflt.php b/src/Zend/Media/Id3/Frame/Tflt.php new file mode 100644 index 0000000..44b50eb --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tflt.php @@ -0,0 +1,57 @@ +File type frame indicates which type of audio this tag defines. + * The following types and refinements are defined: + * + *
    + * MIME   MIME type follows
    + *  MPG    MPEG Audio
    + *    /1     MPEG 1/2 layer I
    + *    /2     MPEG 1/2 layer II
    + *    /3     MPEG 1/2 layer III
    + *    /2.5   MPEG 2.5
    + *    /AAC   Advanced audio compression
    + *  VQF    Transform-domain Weighted Interleave Vector Quantisation
    + *  PCM    Pulse Code Modulated audio
    + * 
    + * + * but other types may be used, but not for these types though. This is used in + * a similar way to the predefined types in the + * {@link Zend_Media_Id3_Frame_Tmed TMED} frame. If this frame is not present + * audio type is assumed to be MPG. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tflt extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Time.php b/src/Zend/Media/Id3/Frame/Time.php new file mode 100644 index 0000000..5eba339 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Time.php @@ -0,0 +1,105 @@ +Time frame contains the time for the recording in the HHMM format. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Time extends Zend_Media_Id3_DateFrame +{ + private $_hours; + private $_minutes; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options, 'HHmm'); + $this->_hours = substr($this->getText(), 0, 2); + $this->_minutes = substr($this->getText(), 2, 2); + } + + /** + * Returns the hour. + * + * @return integer + */ + public function getHour() + { + return intval($this->_hours); + } + + /** + * Sets the hour. + * + * @param integer $hours The hours. + */ + public function setHour($hours) + { + $this->setText + (($this->_hours = str_pad(strval($hours), 2, "0", STR_PAD_LEFT)) . + ($this->_minutes ? $this->_minutes : '00'), + Zend_Media_Id3_Encoding::ISO88591); + } + + /** + * Returns the minutes. + * + * @return integer + */ + public function getMinute() + { + return intval($this->_minutes); + } + + /** + * Sets the minutes. + * + * @param integer $minutes The minutes. + */ + public function setMinute($minutes) + { + $this->setText + (($this->_hours ? $this->_hours : '00') . + ($this->_minutes = + str_pad(strval($minutes), 2, "0", STR_PAD_LEFT)), + Zend_Media_Id3_Encoding::ISO88591); + } +} diff --git a/src/Zend/Media/Id3/Frame/Tipl.php b/src/Zend/Media/Id3/Frame/Tipl.php new file mode 100644 index 0000000..f105700 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tipl.php @@ -0,0 +1,43 @@ +Involved people list is very similar to the musician credits list, + * but maps between functions, like producer, and names. + * + * @todo Implement better support + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tipl extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tit1.php b/src/Zend/Media/Id3/Frame/Tit1.php new file mode 100644 index 0000000..94b2618 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tit1.php @@ -0,0 +1,41 @@ +Content group description frame is used if the sound belongs to a + * larger category of sounds/music. For example, classical music is often sorted + * in different musical sections (e.g. 'Piano Concerto', 'Weather - Hurricane'). + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tit1 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tit2.php b/src/Zend/Media/Id3/Frame/Tit2.php new file mode 100644 index 0000000..37300aa --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tit2.php @@ -0,0 +1,40 @@ +Title/Songname/Content description frame is the actual name of the + * piece (e.g. 'Adagio', 'Hurricane Donna'). + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tit2 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tit3.php b/src/Zend/Media/Id3/Frame/Tit3.php new file mode 100644 index 0000000..cc780f4 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tit3.php @@ -0,0 +1,41 @@ +Subtitle/Description refinement frame is used for information + * directly related to the contents title (e.g. 'Op. 16' or 'Performed live at + * Wembley'). + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tit3 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tkey.php b/src/Zend/Media/Id3/Frame/Tkey.php new file mode 100644 index 0000000..a1e24a4 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tkey.php @@ -0,0 +1,43 @@ +Initial key frame contains the musical key in which the sound + * starts. It is represented as a string with a maximum length of three + * characters. The ground keys are represented with 'A', 'B', 'C', 'D', 'E', 'F' + * and 'G' and halfkeys represented with 'b' and '#'. Minor is represented as + * 'm', e.g. 'Dbm'. Off key is represented with an 'o' only. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tkey extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tlan.php b/src/Zend/Media/Id3/Frame/Tlan.php new file mode 100644 index 0000000..371b67c --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tlan.php @@ -0,0 +1,43 @@ +Language frame should contain the languages of the text or lyrics + * spoken or sung in the audio. The language is represented with three + * characters according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO-639-2}. If more than one language is used in the text their language + * codes should follow according to the amount of their usage. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tlan extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tlen.php b/src/Zend/Media/Id3/Frame/Tlen.php new file mode 100644 index 0000000..d165fd0 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tlen.php @@ -0,0 +1,40 @@ +Length frame contains the length of the audio file in + * milliseconds. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tlen extends Zend_Media_Id3_NumberFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tmcl.php b/src/Zend/Media/Id3/Frame/Tmcl.php new file mode 100644 index 0000000..d1e81ed --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tmcl.php @@ -0,0 +1,44 @@ +Musician credits list is intended as a mapping between instruments + * and the musician that played it. Every odd field is an instrument and every + * even is an artist or a comma delimited list of artists. + * + * @todo Implement better support + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tmcl extends Zend_Media_Id3_TextFrame +{} diff --git a/src/ID3/Frame/TMED.php b/src/Zend/Media/Id3/Frame/Tmed.php similarity index 50% rename from src/ID3/Frame/TMED.php rename to src/Zend/Media/Id3/Frame/Tmed.php index d4db37f..5cc4e68 100644 --- a/src/ID3/Frame/TMED.php +++ b/src/Zend/Media/Id3/Frame/Tmed.php @@ -1,48 +1,33 @@ Media type frame describes from which media the sound originated. * This may be a text string or a reference to the predefined media types found - * in the list below. Example: "VID/PAL/VHS" $00. + * in the list below. Example: 'VID/PAL/VHS'. * *
      *  DIG    Other digital media
    @@ -127,11 +112,13 @@ require_once("ID3/Frame/AbstractText.php");
      *    /IV   Type IV cassette (metal)
      * 
    * - * @package php-reader + * @category Zend + * @package Zend_Media * @subpackage ID3 - * @author Sven Vollbehr - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ */ -final class ID3_Frame_TMED extends ID3_Frame_AbstractText {} +final class Zend_Media_Id3_Frame_Tmed extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tmoo.php b/src/Zend/Media/Id3/Frame/Tmoo.php new file mode 100644 index 0000000..3ab4a5c --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tmoo.php @@ -0,0 +1,42 @@ +Mood frame is intended to reflect the mood of the audio with a few + * keywords, e.g. 'Romantic' or 'Sad'. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tmoo extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Toal.php b/src/Zend/Media/Id3/Frame/Toal.php new file mode 100644 index 0000000..f556895 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Toal.php @@ -0,0 +1,41 @@ +Original album/movie/show title frame is intended for the title of + * the original recording (or source of sound), if for example the music in the + * file should be a cover of a previously released song. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Toal extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tofn.php b/src/Zend/Media/Id3/Frame/Tofn.php new file mode 100644 index 0000000..5c3c86b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tofn.php @@ -0,0 +1,41 @@ +Original filename frame contains the preferred filename for the + * file, since some media doesn't allow the desired length of the filename. The + * filename is case sensitive and includes its suffix. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tofn extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Toly.php b/src/Zend/Media/Id3/Frame/Toly.php new file mode 100644 index 0000000..9be2636 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Toly.php @@ -0,0 +1,41 @@ +Original lyricist/text writer frame is intended for the text + * writer of the original recording, if for example the music in the file should + * be a cover of a previously released song. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Toly extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tope.php b/src/Zend/Media/Id3/Frame/Tope.php new file mode 100644 index 0000000..6ebef09 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tope.php @@ -0,0 +1,41 @@ +Original artist/performer frame is intended for the performer of + * the original recording, if for example the music in the file should be a + * cover of a previously released song. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tope extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tory.php b/src/Zend/Media/Id3/Frame/Tory.php new file mode 100644 index 0000000..cc553ca --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tory.php @@ -0,0 +1,76 @@ +Original release year frame is intended for the year when the + * original recording, if for example the music in the file should be a cover of + * a previously released song, was released. The field is formatted as in the + * {@link Zend_Media_Id3_Frame_Tyer TYER} frame. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Tory extends Zend_Media_Id3_DateFrame +{ + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options, 'Y'); + } + + /** + * Returns the year. + * + * @return integer + */ + public function getYear() + { + return intval($this->getText()); + } + + /** + * Sets the year. + * + * @param integer $year The year given in four digits. + */ + public function setYear($year) + { + $this->setText(strval($year)); + } +} diff --git a/src/Zend/Media/Id3/Frame/Town.php b/src/Zend/Media/Id3/Frame/Town.php new file mode 100644 index 0000000..4daa9e6 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Town.php @@ -0,0 +1,40 @@ +File owner/licensee frame contains the name of the owner or + * licensee of the file and it's contents. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Town extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpe1.php b/src/Zend/Media/Id3/Frame/Tpe1.php new file mode 100644 index 0000000..b284cb5 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpe1.php @@ -0,0 +1,40 @@ +Lead artist/Lead performer/Soloist/Performing group is used for + * the main artist. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpe1 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpe2.php b/src/Zend/Media/Id3/Frame/Tpe2.php new file mode 100644 index 0000000..f31fc7a --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpe2.php @@ -0,0 +1,40 @@ +Band/Orchestra/Accompaniment frame is used for additional + * information about the performers in the recording. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpe2 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpe3.php b/src/Zend/Media/Id3/Frame/Tpe3.php new file mode 100644 index 0000000..0e70445 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpe3.php @@ -0,0 +1,39 @@ +Conductor frame is used for the name of the conductor. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpe3 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpe4.php b/src/Zend/Media/Id3/Frame/Tpe4.php new file mode 100644 index 0000000..0f338b6 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpe4.php @@ -0,0 +1,41 @@ +Interpreted, remixed, or otherwise modified by frame contains more + * information about the people behind a remix and similar interpretations of + * another existing piece. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpe4 extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpos.php b/src/Zend/Media/Id3/Frame/Tpos.php new file mode 100644 index 0000000..50a9ebc --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpos.php @@ -0,0 +1,114 @@ +Number of a set frame is a numeric string that describes which part + * of a set the audio came from. This frame is used if the source described in + * the {@link Zend_Media_Id3_Frame_Talb TALB} frame is divided into several + * mediums, e.g. a double CD. The value may be extended with a '/' character and + * a numeric string containing the total number of parts in the set. E.g. '1/2'. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpos extends Zend_Media_Id3_TextFrame +{ + private $_number; + private $_total; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + + if ($this->_reader === null) { + return; + } + + $this->_reader->skip(1); + $this->setText($this->_reader->readString8($this->_reader->getSize())); + @list ($this->_number, $this->_total) = explode("/", $this->getText()); + } + + /** + * Returns the number. + * + * @return integer + */ + public function getNumber() + { + return intval($this->_number); + } + + /** + * Sets the number. + * + * @param integer $number The number. + */ + public function setNumber($part) + { + $this->setText + ($this->_number = strval($part) . + ($this->_total ? '/' . $this->_total : ''), + Zend_Media_Id3_Encoding::ISO88591); + } + + /** + * Returns the total number. + * + * @return integer + */ + public function getTotal() + { + return intval($this->_total); + } + + /** + * Sets the total number. + * + * @param integer $total The total number. + */ + public function setTotal($total) + { + $this->setText + (($this->_number ? $this->_number : '?') . "/" . + ($this->_total = strval($total)), + Zend_Media_Id3_Encoding::ISO88591); + } +} diff --git a/src/Zend/Media/Id3/Frame/Tpro.php b/src/Zend/Media/Id3/Frame/Tpro.php new file mode 100644 index 0000000..0b0d69f --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpro.php @@ -0,0 +1,48 @@ +Produced notice frame, in which the string must begin with a year + * and a space character (making five characters), is intended for the + * production copyright holder of the original sound, not the audio file itself. + * The absence of this frame means only that the production copyright + * information is unavailable or has been removed, and must not be interpreted + * to mean that the audio is public domain. Every time this field is displayed + * the field must be preceded with 'Produced ' (P) ' ', where (P) is one + * character showing a P in a circle. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tpro extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tpub.php b/src/Zend/Media/Id3/Frame/Tpub.php new file mode 100644 index 0000000..d826c1c --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tpub.php @@ -0,0 +1,40 @@ +Publisher frame simply contains the name of the label or + * publisher. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tpub extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Trck.php b/src/Zend/Media/Id3/Frame/Trck.php new file mode 100644 index 0000000..0d1ff8b --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Trck.php @@ -0,0 +1,113 @@ +Track number/Position in set frame is a numeric string containing + * the order number of the audio-file on its original recording. This may be + * extended with a '/' character and a numeric string containing the total + * number of tracks/elements on the original recording. E.g. '4/9'. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Trck extends Zend_Media_Id3_TextFrame +{ + private $_number; + private $_total; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + + if ($this->_reader === null) { + return; + } + + $this->_reader->skip(1); + $this->setText($this->_reader->readString8($this->_reader->getSize())); + @list ($this->_number, $this->_total) = explode("/", $this->getText()); + } + + /** + * Returns the number. + * + * @return integer + */ + public function getNumber() + { + return intval($this->_number); + } + + /** + * Sets the number. + * + * @param integer $number The number. + */ + public function setNumber($part) + { + $this->setText + ($this->_number = strval($part) . + ($this->_total ? '/' . $this->_total : ''), + Zend_Media_Id3_Encoding::ISO88591); + } + + /** + * Returns the total number. + * + * @return integer + */ + public function getTotal() + { + return intval($this->_total); + } + + /** + * Sets the total number. + * + * @param integer $total The total number. + */ + public function setTotal($total) + { + $this->setText + (($this->_number ? $this->_number : '?') . "/" . + ($this->_total = strval($total)), + Zend_Media_Id3_Encoding::ISO88591); + } +} diff --git a/src/Zend/Media/Id3/Frame/Trda.php b/src/Zend/Media/Id3/Frame/Trda.php new file mode 100644 index 0000000..12dd24d --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Trda.php @@ -0,0 +1,45 @@ +Recording dates frame is intended to be used as complement to + * the {@link Zend_Media_Id3_Frame_Tyer TYER}, + * {@link Zend_Media_Id3_Frame_Tdat TDAT} and + * {@link Zend_Media_Id3_Frame_Time TIME} frames. E.g. '4th-7th June, 12th June' + * in combination with the {@link Zend_Media_Id3_Frame_Tyer TYER} frame. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Trda extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Trsn.php b/src/Zend/Media/Id3/Frame/Trsn.php new file mode 100644 index 0000000..d757f95 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Trsn.php @@ -0,0 +1,40 @@ +Internet radio station name frame contains the name of the + * internet radio station from which the audio is streamed. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_TRSN extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Trso.php b/src/Zend/Media/Id3/Frame/Trso.php new file mode 100644 index 0000000..f627fb3 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Trso.php @@ -0,0 +1,40 @@ +Internet radio station owner frame contains the name of the owner + * of the internet radio station from which the audio is streamed. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_TRSO extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsiz.php b/src/Zend/Media/Id3/Frame/Tsiz.php new file mode 100644 index 0000000..097cccd --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsiz.php @@ -0,0 +1,42 @@ +Size frame contains the size of the audiofile in bytes, excluding + * the ID3v2 tag. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Tsiz extends Zend_Media_Id3_NumberFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsoa.php b/src/Zend/Media/Id3/Frame/Tsoa.php new file mode 100644 index 0000000..7b81bf0 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsoa.php @@ -0,0 +1,43 @@ +Album sort order frame defines a string which should be used + * instead of the {@link Zend_Media_Id3_Frame_Talb TALB} album name frame for + * sorting purposes. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tsoa extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsop.php b/src/Zend/Media/Id3/Frame/Tsop.php new file mode 100644 index 0000000..d0df497 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsop.php @@ -0,0 +1,43 @@ +Performer sort order frame defines a string which should be used + * instead of the {@link Zend_Media_Id3_Frame_Tpe2 TPE2} performer frame for + * sorting purposes. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tsop extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsot.php b/src/Zend/Media/Id3/Frame/Tsot.php new file mode 100644 index 0000000..c1ceb2e --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsot.php @@ -0,0 +1,43 @@ +Title sort order frame defines a string which should be used + * instead of the {@link Zend_Media_Id3_Frame_Tit2 TIT2} title frame for sorting + * purposes. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tsot extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsrc.php b/src/Zend/Media/Id3/Frame/Tsrc.php new file mode 100644 index 0000000..92fa926 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsrc.php @@ -0,0 +1,206 @@ +TSRC frame should contain the International Standard Recording + * Code or ISRC (12 characters). + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tsrc extends Zend_Media_Id3_TextFrame +{ + /** @var string */ + private $_country; + + /** @var string */ + private $_registrant; + + /** @var string */ + private $_year; + + /** @var string */ + private $_uniqueNumber; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + + if ($this->_reader === null) { + return; + } + + $this->_reader->skip(1); + $this->setText($this->_reader->readString8($this->_reader->getSize())); + $this->_country = substr($this->getText(), 0, 2); + $this->_registrant = substr($this->getText(), 2, 3); + $this->_year = substr($this->getText(), 5, 2); + $this->_uniqueNumber = substr($this->getText(), 7, 5); + } + + /** + * Returns the appropriate for the registrant the two-character ISO 3166-1 + * alpha-2 country code. + * + * @return string + */ + public function getCountry() + { + return $this->_country; + } + + /** + * Sets the country. + * + * @param string $country The two-character ISO 3166-1 alpha-2 country code. + */ + public function setCountry($country) + { + $this->_country = $country; + } + + /** + * Returns the three character alphanumeric registrant code, uniquely + * identifying the organisation which registered the ISRC code. + * + * @return string + */ + public function getRegistrant() + { + return $this->_registrant; + } + + /** + * Sets the registrant. + * + * @param string $registrant The three character alphanumeric registrant + * code. + */ + public function setRegistrant($registrant) + { + $this->_registrant = $registrant; + } + + /** + * Returns the year of registration. + * + * @return integer + */ + public function getYear() + { + $year = intval($this->_year); + if ($year > 50) { + return 1900 + $year; + } else { + return 2000 + $year; + } + } + + /** + * Sets the year. + * + * @param integer $year The year of registration. + */ + public function setYear($year) + { + $this->_year = substr(strval($year), 2, 2); + } + + /** + * Returns the unique number identifying the particular sound recording. + * + * @return integer + */ + public function getUniqueNumber() + { + return intval($this->_uniqueNumber); + } + + /** + * Sets the unique number. + * + * @param integer $uniqueNumber The unique number identifying the + * particular sound recording. + */ + public function setUniqueNumber($uniqueNumber) + { + $this->_uniqueNumber = + str_pad(strval($uniqueNumber), 5, "0", STR_PAD_LEFT); + } + + /** + * Returns the whole ISRC code in the form + * "country-registrant-year-unique number". + * + * @return string + */ + public function getIsrc() + { + return $this->_country . "-" . $this->_registrant . "-" . + $this->_year . "-" . $this->_uniqueNumber; + } + + /** + * Sets the ISRC code in the form "country-registrant-year-unique number". + * + * @param string $isrc The ISRC code. + */ + public function setIsrc($isrc) + { + list($this->_country, + $this->_registrant, + $this->_year, + $this->_uniqueNumber) = preg_split('/-/', $isrc); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $this->setText + ($this->_country . $this->_registrant . $this->_year . + $this->_uniqueNumber, Zend_Media_Id3_Encoding::ISO88591); + parent::_writeData($writer); + } +} diff --git a/src/Zend/Media/Id3/Frame/Tsse.php b/src/Zend/Media/Id3/Frame/Tsse.php new file mode 100644 index 0000000..736fa3e --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsse.php @@ -0,0 +1,41 @@ +Software/Hardware and settings used for encoding frame includes + * the used audio encoder and its settings when the file was encoded. Hardware + * refers to hardware encoders, not the computer on which a program was run. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Tsse extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Tsst.php b/src/Zend/Media/Id3/Frame/Tsst.php new file mode 100644 index 0000000..210dfc7 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tsst.php @@ -0,0 +1,42 @@ +Set subtitle frame is intended for the subtitle of the part of a + * set this track belongs to. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since ID3v2.4.0 + */ +final class Zend_Media_Id3_Frame_Tsst extends Zend_Media_Id3_TextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Txxx.php b/src/Zend/Media/Id3/Frame/Txxx.php new file mode 100644 index 0000000..d519943 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Txxx.php @@ -0,0 +1,144 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Txxx extends Zend_Media_Id3_TextFrame +{ + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($this->_description, $this->_text) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_description = + $this->_convertString($this->_description, $encoding); + $this->_text = + $this->_convertString(array($this->_text), $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + list($this->_description, $this->_text) = $this->_convertString + ($this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2), + $encoding); + $this->_text = array($this->_text); + break; + } + } + + /** + * Returns the description text. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the description text using given encoding. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = null) + { + $this->_description = $description; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, null, 1) + ->writeString16 + ($this->_text[0], + Zend_Io_Writer::LITTLE_ENDIAN_ORDER); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1) + ->writeString16($this->_text[0], null); + break; + default: + $writer->writeString8($this->_description, 1) + ->writeString8($this->_text[0]); + break; + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Tyer.php b/src/Zend/Media/Id3/Frame/Tyer.php new file mode 100644 index 0000000..d015430 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Tyer.php @@ -0,0 +1,73 @@ +Year frame is a numeric string with a year of the recording. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @deprecated ID3v2.3.0 + */ +final class Zend_Media_Id3_Frame_Tyer extends Zend_Media_Id3_DateFrame +{ + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options, 'Y'); + } + + /** + * Returns the year. + * + * @return integer + */ + public function getYear() + { + return intval($this->getText()); + } + + /** + * Sets the year. + * + * @param integer $year The year given in four digits. + */ + public function setYear($year) + { + $this->setText(strval($year)); + } +} diff --git a/src/Zend/Media/Id3/Frame/Ufid.php b/src/Zend/Media/Id3/Frame/Ufid.php new file mode 100644 index 0000000..90981e5 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Ufid.php @@ -0,0 +1,130 @@ +Unique File Identifier frame's purpose is to be able to identify + * the audio file in a database, that may provide more information relevant to + * the content. Since standardisation of such a database is beyond this document, + * all UFID frames begin with an 'owner identifier' field. It is a null- + * terminated string with a URL [URL] containing an email address, or a link to + * a location where an email address can be found, that belongs to the + * organisation responsible for this specific database implementation. + * Questions regarding the database should be sent to the indicated email + * address. The URL should not be used for the actual database queries. The + * string "http://www.id3.org/dummy/ufid.html" should be used for tests. The + * 'Owner identifier' must be non-empty (more than just a termination). The + * 'Owner identifier' is then followed by the actual identifier, which may be + * up to 64 bytes. There may be more than one "UFID" frame in a tag, but only + * one with the same 'Owner identifier'. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Arlo Kleijweg + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Ufid extends Zend_Media_Id3_Frame +{ + /** @var string */ + private $_owner; + + /** @var string */ + private $_fileIdentifier; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader === null) { + return; + } + + list($this->_owner, $this->_fileIdentifier) = + $this->_explodeString8($this->_data, 2); + } + + /** + * Returns the owner identifier string. + * + * @return string + */ + public function getOwner() + { + return $this->_owner; + } + + /** + * Sets the owner identifier string. + * + * @param string $owner The owner identifier string. + */ + public function setOwner($owner) + { + $this->_owner = $owner; + } + + /** + * Returns the identifier binary data associated with the frame. + * + * @return string + */ + public function getFileIdentifier() + { + return $this->_fileIdentifier; + } + + /** + * Sets the identifier binary data associated with the frame. + * + * @param string $fileIdentifier The file identifier binary data string. + */ + public function setFileIdentifier($fileIdentifier) + { + $this->_fileIdentifier = $fileIdentifier; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeString8($this->_owner, 1) + ->write($this->_fileIdentifier); + } +} diff --git a/src/Zend/Media/Id3/Frame/Unknown.php b/src/Zend/Media/Id3/Frame/Unknown.php new file mode 100644 index 0000000..ac43daf --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Unknown.php @@ -0,0 +1,48 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Unknown extends Zend_Media_Id3_Frame +{ + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + {} +} diff --git a/src/Zend/Media/Id3/Frame/User.php b/src/Zend/Media/Id3/Frame/User.php new file mode 100644 index 0000000..6d611db --- /dev/null +++ b/src/Zend/Media/Id3/Frame/User.php @@ -0,0 +1,43 @@ +Terms of use frame contains a brief description of the terms of + * use and ownership of the file. More detailed information concerning the legal + * terms might be available through the {@link Zend_Media_Id3_Frame_Wcop WCOP} + * frame. Newlines are allowed in the text. There may be more than one Terms of + * use frames in a tag, but only one with the same language. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_User extends Zend_Media_Id3_LanguageTextFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Uslt.php b/src/Zend/Media/Id3/Frame/Uslt.php new file mode 100644 index 0000000..8c866f2 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Uslt.php @@ -0,0 +1,154 @@ +Unsynchronised lyrics/text transcription frame contains the lyrics + * of the song or a text transcription of other vocal activities. There may be + * more than one unsynchronised lyrics/text transcription frame in each tag, but + * only one with the same language and content descriptor. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Uslt extends Zend_Media_Id3_LanguageTextFrame +{ + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_language = strtolower($this->_reader->read(3)); + if ($this->_language == 'xxx') { + $this->_language = 'und'; + } + + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($this->_description, $this->_text) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + $this->_description = + $this->_convertString($this->_description, $encoding); + $this->_text = + $this->_convertString($this->_text, $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + list($this->_description, $this->_text) = $this->_convertString + ($this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2), + $encoding); + break; + } + } + + /** + * Returns the short content description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. The description + * language and encoding must be that of the actual text. + * + * @param string $description The content description text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setDescription + ($description, $language = null, $encoding = null) + { + $this->_description = $description; + if ($language !== null) { + $this->setLanguage($language); + } + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_language); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1) + ->writeString16 + ($this->_text,Zend_Io_Writer::LITTLE_ENDIAN_ORDER); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1) + ->writeString16($this->_text); + break; + default: + $writer->writeString8($this->_description, 1) + ->writeString8($this->_text); + break; + } + } +} diff --git a/src/Zend/Media/Id3/Frame/Wcom.php b/src/Zend/Media/Id3/Frame/Wcom.php new file mode 100644 index 0000000..0474dcb --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wcom.php @@ -0,0 +1,41 @@ +Commercial information frame is a URL pointing at a webpage with + * information such as where the album can be bought. There may be more than one + * WCOM frame in a tag, but not with the same content. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wcom extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Wcop.php b/src/Zend/Media/Id3/Frame/Wcop.php new file mode 100644 index 0000000..1335a90 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wcop.php @@ -0,0 +1,40 @@ +Copyright/Legal information frame is a URL pointing at a webpage + * where the terms of use and ownership of the file is described. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wcop extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Woaf.php b/src/Zend/Media/Id3/Frame/Woaf.php new file mode 100644 index 0000000..68245b4 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Woaf.php @@ -0,0 +1,40 @@ +Official audio file webpage frame is a URL pointing at a file + * specific webpage. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Woaf extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Woar.php b/src/Zend/Media/Id3/Frame/Woar.php new file mode 100644 index 0000000..9e7cee0 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Woar.php @@ -0,0 +1,41 @@ +Official artist/performer webpage frame is a URL pointing at the + * artists official webpage. There may be more than one WOAR frame in a tag if + * the audio contains more than one performer, but not with the same content. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Woar extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Woas.php b/src/Zend/Media/Id3/Frame/Woas.php new file mode 100644 index 0000000..67043cb --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Woas.php @@ -0,0 +1,40 @@ +Official audio source webpage frame is a URL pointing at the + * official webpage for the source of the audio file, e.g. a movie. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Woas extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Wors.php b/src/Zend/Media/Id3/Frame/Wors.php new file mode 100644 index 0000000..6bb16da --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wors.php @@ -0,0 +1,40 @@ +Official Internet radio station homepage contains a URL pointing + * at the homepage of the internet radio station. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wors extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Wpay.php b/src/Zend/Media/Id3/Frame/Wpay.php new file mode 100644 index 0000000..38838fa --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wpay.php @@ -0,0 +1,40 @@ +Payment frame is a URL pointing at a webpage that will handle the + * process of paying for this file. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wpay extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Wpub.php b/src/Zend/Media/Id3/Frame/Wpub.php new file mode 100644 index 0000000..7b41a21 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wpub.php @@ -0,0 +1,40 @@ +Publishers official webpage frame is a URL pointing at the + * official webpage for the publisher. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wpub extends Zend_Media_Id3_LinkFrame +{} diff --git a/src/Zend/Media/Id3/Frame/Wxxx.php b/src/Zend/Media/Id3/Frame/Wxxx.php new file mode 100644 index 0000000..e1f0c92 --- /dev/null +++ b/src/Zend/Media/Id3/Frame/Wxxx.php @@ -0,0 +1,180 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Frame_Wxxx extends Zend_Media_Id3_LinkFrame + implements Zend_Media_Id3_Encoding +{ + /** @var integer */ + private $_encoding; + + /** @var string */ + private $_description; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + list($this->_description, $this->_link) = + $this->_explodeString16 + ($this->_reader->read($this->_reader->getSize()), 2); + break; + case self::UTF8: + // break intentionally omitted + default: + list($this->_description, $this->_link) = + $this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 2); + break; + } + $this->_description = + $this->_convertString($this->_description, $encoding); + $this->_link = implode($this->_explodeString8($this->_link, 1), ''); + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the link description. + * + * @return string + */ + public function getDescription() + { + return $this->_description; + } + + /** + * Sets the content description text using given encoding. + * + * @param string $description The content description text. + * @param integer $encoding The text encoding. + */ + public function setDescription($description, $encoding = null) + { + $this->_description = $description; + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_description, + Zend_Io_Writer::LITTLE_ENDIAN_ORDER, 1); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->writeString16($this->_description, null, 1); + break; + default: + $writer->writeString8($this->_description, 1); + break; + } + $writer->write($this->_link); + } +} diff --git a/src/Zend/Media/Id3/Header.php b/src/Zend/Media/Id3/Header.php new file mode 100644 index 0000000..804232d --- /dev/null +++ b/src/Zend/Media/Id3/Header.php @@ -0,0 +1,179 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3_Header extends Zend_Media_Id3_Object +{ + /** A flag to denote whether or not unsynchronisation is applied on all + frames */ + const UNSYNCHRONISATION = 128; + + /** A flag to denote whether or not the header is followed by an extended + header */ + const EXTENDED_HEADER = 64; + + /** A flag used as an experimental indicator. This flag shall always be set + when the tag is in an experimental stage. */ + const EXPERIMENTAL = 32; + + /** + * A flag to denote whether a footer is present at the very end of the tag. + * + * @since ID3v2.4.0 + */ + const FOOTER = 16; + + /** @var integer */ + private $_version = 4.0; + + /** @var integer */ + private $_flags = 0; + + /** @var integer */ + private $_size; + + /** + * Constructs the class with given parameters and reads object related data + * from the ID3v2 tag. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) + return; + + $this->_version = $options['version'] = + $this->_reader->readInt8() + $this->_reader->readInt8() / 10; + $this->_flags = $this->_reader->readInt8(); + $this->_size = + $this->_decodeSynchsafe32($this->_reader->readUInt32BE()); + } + + /** + * Returns the tag version number. The version number is in the form of + * major.revision. + * + * @return integer + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Sets the tag version number. Supported version numbers are 3.0 and 4.0 + * for ID3v2.3.0 and ID3v2.4.0 standards, respectively. + * + * @param integer $version The tag version number in the form of + * major.revision. + */ + public function setVersion($version) + { + $this->setOption('version', $this->_version = $version); + } + + /** + * Checks whether or not the flag is set. Returns true if the + * flag is set, false otherwise. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the flags byte. + * + * @return integer + */ + public function getFlags() + { + return $this->_flags; + } + + /** + * Sets the flags byte. + * + * @param string $flags The flags byte. + */ + public function setFlags($flags) + { + $this->_flags = $flags; + } + + /** + * Returns the tag size, excluding the header and the footer. + * + * @return integer + */ + public function getSize() + { + return $this->_size; + } + + /** + * Sets the tag size, excluding the header and the footer. Called + * automatically upon tag generation to adjust the tag size. + * + * @param integer $size The size of the tag, in bytes. + */ + public function setSize($size) + { + $this->_size = $size; + } + + /** + * Writes the header/footer data without the identifier. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + $writer->writeInt8(floor($this->_version)) + ->writeInt8(($this->_version - floor($this->_version)) * 10) + ->writeInt8($this->_flags) + ->writeUInt32BE($this->_encodeSynchsafe32($this->_size)); + } +} diff --git a/src/Zend/Media/Id3/Language.php b/src/Zend/Media/Id3/Language.php new file mode 100644 index 0000000..200a78f --- /dev/null +++ b/src/Zend/Media/Id3/Language.php @@ -0,0 +1,56 @@ +Zend_Media_Id3_Language interface implies that the + * implementing ID3v2 frame supports its content to be given in multiple + * languages. + * + * The three byte language code is used to describe the language of the frame's + * content, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO-639-2}. The language should be represented in lower case. If the language + * is not known the string 'und' should be used. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +interface Zend_Media_Id3_Language +{ + /** + * Returns the text language code. + * + * @return string + */ + public function getLanguage(); + + /** + * Sets the text language code. + * + * @param string $language The text language code. + */ + public function setLanguage($language); +} diff --git a/src/Zend/Media/Id3/LanguageTextFrame.php b/src/Zend/Media/Id3/LanguageTextFrame.php new file mode 100644 index 0000000..e55063f --- /dev/null +++ b/src/Zend/Media/Id3/LanguageTextFrame.php @@ -0,0 +1,222 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_LanguageTextFrame extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding, Zend_Media_Id3_Language +{ + /** + * The text encoding. + * + * @var integer + */ + protected $_encoding; + + /** + * The ISO-639-2 language code. + * + * @var string + */ + protected $_language = 'und'; + + /** + * The text. + * + * @var string + */ + protected $_text; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + $this->_language = strtolower($this->_reader->read(3)); + if ($this->_language == 'xxx') { + $this->_language = 'und'; + } + + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $this->_text = $this->_convertString + ($this->_reader->readString16($this->_reader->getSize()), + $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + $this->_text = $this->_convertString + ($this->_reader->readString8($this->_reader->getSize()), + $encoding); + break; + } + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @return string + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Sets the text language code as specified in the + * {@link http://www.loc.gov/standards/iso639-2/ ISO-639-2} standard. + * + * @see Zend_Media_Id3_Language + * @param string $language The language code. + */ + public function setLanguage($language) + { + $language = strtolower($language); + if ($language == 'xxx') { + $language = 'und'; + } + $this->_language = substr($language, 0, 3); + } + + /** + * Returns the text. + * + * @return string + */ + public function getText() + { + return $this->_text; + } + + /** + * Sets the text using given language and encoding. + * + * @param string $text The text. + * @param string $language The language code. + * @param integer $encoding The text encoding. + */ + public function setText($text, $language = null, $encoding = null) + { + $this->_text = $text; + if ($language !== null) { + $this->setLanguage($language); + } + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding) + ->write($this->_language); + switch ($this->_encoding) { + case self::UTF16LE: + $writer->writeString16 + ($this->_text, Zend_Io_Writer::LITTLE_ENDIAN_ORDER); + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + // break intentionally omitted + default: + $writer->write($this->_text); + break; + } + } +} diff --git a/src/Zend/Media/Id3/LinkFrame.php b/src/Zend/Media/Id3/LinkFrame.php new file mode 100644 index 0000000..6d3be2f --- /dev/null +++ b/src/Zend/Media/Id3/LinkFrame.php @@ -0,0 +1,92 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_LinkFrame extends Zend_Media_Id3_Frame +{ + /** @var string */ + protected $_link; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->_reader !== null) { + $this->_link = implode + ($this->_explodeString8 + ($this->_reader->read($this->_reader->getSize()), 1), ''); + } + } + + /** + * Returns the link associated with the frame. + * + * @return string + */ + public function getLink() + { + return $this->_link; + } + + /** + * Sets the link. The link encoding is always ISO-8859-1. + * + * @param string $link The link. + */ + public function setLink($link) + { + $this->_link = $link; + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->write($this->_link); + } +} diff --git a/src/Zend/Media/Id3/NumberFrame.php b/src/Zend/Media/Id3/NumberFrame.php new file mode 100644 index 0000000..c00779f --- /dev/null +++ b/src/Zend/Media/Id3/NumberFrame.php @@ -0,0 +1,93 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_NumberFrame + extends Zend_Media_Id3_TextFrame +{ + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + Zend_Media_Id3_Frame::__construct($reader, $options); + + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + + if ($this->_reader === null) { + return; + } + + $this->_reader->skip(1); + $this->setText($this->_reader->readString8($this->_reader->getSize())); + } + + /** + * Returns the integer value of the text. + * + * @return integer + */ + public function getValue() + { + return doubleval($this->getText()); + } + + /** + * Sets the integer value of the text. + * + * @param integer $value The integer value of the text. + */ + public function setValue($value) + { + $this->setText(strval($value), Zend_Media_Id3_Encoding::ISO88591); + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $this->setEncoding(Zend_Media_Id3_Encoding::ISO88591); + parent::_writeData($writer); + } +} diff --git a/src/Zend/Media/Id3/Object.php b/src/Zend/Media/Id3/Object.php new file mode 100644 index 0000000..1cacca2 --- /dev/null +++ b/src/Zend/Media/Id3/Object.php @@ -0,0 +1,376 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_Object +{ + /** + * The reader object. + * + * @var Zend_Io_Reader + */ + protected $_reader; + + /** + * The options array. + * + * @var Array + */ + private $_options; + + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + $this->_reader = $reader; + $this->_options = &$options; + } + + /** + * Returns the options array. + * + * @return Array + */ + public final 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 final function getOption($option, $defaultValue = null) + { + if (isset($this->_options[$option])) { + return $this->_options[$option]; + } + return $defaultValue; + } + + /** + * Sets the options array. See {@link Zend_Media_Id3v2} class for available + * options. + * + * @param Array $options The options array. + */ + public final 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 final function setOption($option, $value) + { + $this->_options[$option] = $value; + } + + /** + * Clears the given option value. + * + * @param string $option The name of the option. + */ + public final function clearOption($option) + { + unset($this->_options[$option]); + } + + /** + * Magic function so that $obj->value will work. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func(array($this, 'get' . ucfirst($name))); + } else { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Unknown 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 { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Unknown field: ' . $name); + } + } + + /** + * Encodes the given 32-bit integer to 28-bit synchsafe integer, where the + * most significant bit of each byte is zero, making seven bits out of eight + * available. + * + * @param integer $val The integer to encode. + * @return integer + */ + protected final function _encodeSynchsafe32($val) + { + return ($val & 0x7f) | ($val & 0x3f80) << 1 | + ($val & 0x1fc000) << 2 | ($val & 0xfe00000) << 3; + } + + /** + * Decodes the given 28-bit synchsafe integer to regular 32-bit integer. + * + + * @param integer $val The integer to decode + * @return integer + */ + protected final function _decodeSynchsafe32($val) + { + return ($val & 0x7f) | ($val & 0x7f00) >> 1 | + ($val & 0x7f0000) >> 2 | ($val & 0x7f000000) >> 3; + } + + /** + * Applies the unsynchronisation scheme to the given data string. + * + * Whenever a false synchronisation is found within the data, one zeroed + * byte is inserted after the first false synchronisation byte. This has the + * side effect that all 0xff00 combinations have to be altered, so they will + * not be affected by the decoding process. Therefore all the 0xff00 + * combinations have to be replaced with the 0xff0000 combination during the + * unsynchronisation. + * + * @param string $data The input data. + * @return string + */ + protected final function _encodeUnsynchronisation(&$data) + { + $result = ''; + for ($i = 0, $j = 0; $i < strlen($data) - 1; $i++) { + if (ord($data[$i]) == 0xff && + ((($tmp = ord($data[$i + 1])) & 0xe0) == 0xe0 || $tmp == 0x0)) { + $result .= substr($data, $j, $i + 1 - $j) . "\0"; + $j = $i + 1; + } + } + return $result . substr($data, $j); + } + + /** + * Reverses the unsynchronisation scheme from the given data string. + * + * @see _encodeUnsynchronisation + * @param string $data The input data. + * @return string + */ + protected final function _decodeUnsynchronisation(&$data) + { + $result = ''; + for ($i = 0, $j = 0; $i < strlen($data) - 1; $i++) { + if (ord($data[$i]) == 0xff && ord($data[$i + 1]) == 0x0) { + $result .= substr($data, $j, $i + 1 - $j); + $j = $i + 2; + } + } + return $result . substr($data, $j); + } + + /** + * Splits UTF-16 formatted binary data up according to null terminators + * residing in the string, up to a given limit. + * + * @param string $value The input string. + * @return Array + */ + protected final function _explodeString16($value, $limit = null) + { + $i = 0; + $array = array(); + while (count($array) < $limit - 1 || $limit === null) { + $start = $i; + do { + $i = strpos($value, "\x00\x00", $i); + if ($i === false) { + $array[] = substr($value, $start); + return $array; + } + } while ($i & 0x1 != 0 && $i++); // make sure its aligned + $array[] = substr($value, $start, $i - $start); + $i += 2; + } + $array[] = substr($value, $i); + return $array; + } + + /** + * Splits UTF-8 or ISO-8859-1 formatted binary data according to null + * terminators residing in the string, up to a given limit. + * + * @param string $value The input string. + * @return Array + */ + protected final function _explodeString8($value, $limit = null) + { + return preg_split("/\\x00/", $value, $limit); + } + + /** + * Converts string from the given character encoding to the target encoding + * specified by the options as the encoding to display all the texts with, + * and returns the converted string. + * + * Character encoding sets can be {@link Zend_Media_Id3_Encoding} + * constants or already in the string form accepted by iconv. + * + * @param string|Array $string + * @param string|integer $source The source encoding. + * @param string|integer $target The target encoding. Defaults to the + * encoding value set in options. + */ + protected final function _convertString($string, $source, $target = null) + { + if ($target === null) { + $target = $this->getOption('encoding', 'utf-8'); + } + + $source = $this->_translateIntToEncoding($source); + $target = $this->_translateIntToEncoding($target); + + if ($source == $target) { + return $string; + } + + if (is_array($string)) { + foreach ($string as $key => $value) { + $string[$key] = iconv($source, $target, $value); + } + } else { + $string = iconv($source, $target, $string); + } + return $string; + } + + /** + * Returns given encoding in the form accepted by iconv. + * + * Character encoding set can be a {@link Zend_Media_Id3_Encoding} + * constant or already in the string form accepted by iconv. + * + * @param string|integer $encoding The encoding. + * @return string + */ + protected final function _translateIntToEncoding($encoding) + { + if (is_string($encoding)) { + return strtolower($encoding); + } + if (is_integer($encoding)) { + switch ($encoding) { + case Zend_Media_Id3_Encoding::UTF16: + return 'utf-16'; + case Zend_Media_Id3_Encoding::UTF16LE: + return 'utf-16le'; + case Zend_Media_Id3_Encoding::UTF16BE: + return 'utf-16be'; + case Zend_Media_Id3_Encoding::ISO88591: + return 'iso-8859-1'; + default: + return 'utf-8'; + } + } + return 'utf-8'; + } + + /** + * Returns given encoding in the form possible to write to the tag frame. + * + * Character encoding set can be in the string form accepted by iconv or + * already a {@link Zend_Media_Id3_Encoding} constant. + * + * @param string|integer $encoding The encoding. + * @return integer + */ + protected final function _translateEncodingToInt($encoding) + { + if (is_integer($encoding)) { + if ($encoding >= 0 && $encoding <= 4) { + return $encoding; + } + } + if (is_string($encoding)) { + switch ($encoding) { + case 'utf-16': + return Zend_Media_Id3_Encoding::UTF16; + case 'utf-16le': + return Zend_Media_Id3_Encoding::UTF16; + case 'utf-16be': + return Zend_Media_Id3_Encoding::UTF16BE; + case 'iso-8859-1': + return Zend_Media_Id3_Encoding::ISO88591; + default: + return Zend_Media_Id3_Encoding::UTF8; + } + } + return Zend_Media_Id3_Encoding::UTF8; + } + + /** + * Writes the object data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + abstract public function write($writer); +} diff --git a/src/Zend/Media/Id3/TextFrame.php b/src/Zend/Media/Id3/TextFrame.php new file mode 100644 index 0000000..e189f13 --- /dev/null +++ b/src/Zend/Media/Id3/TextFrame.php @@ -0,0 +1,195 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Id3_TextFrame extends Zend_Media_Id3_Frame + implements Zend_Media_Id3_Encoding +{ + /** + * The text encoding. + * + * @var integer + */ + protected $_encoding; + + /** + * The text array. + * + * @var string + */ + protected $_text; + + /** + * Constructs the class with given parameters and parses object related + * data. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + $this->setEncoding + ($this->getOption('encoding', Zend_Media_Id3_Encoding::UTF8)); + + if ($this->_reader === null) { + return; + } + + $encoding = $this->_reader->readUInt8(); + switch ($encoding) { + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $this->_text = $this->_convertString + ($this->_explodeString16 + ($this->_reader->readString16($this->_reader->getSize())), + $encoding); + break; + case self::UTF8: + // break intentionally omitted + default: + $this->_text = $this->_convertString + ($this->_explodeString8 + ($this->_reader->readString8($this->_reader->getSize())), + $encoding); + break; + } + } + + /** + * Returns the text encoding. + * + * All the strings read from a file are automatically converted to the + * character encoding specified with the encoding option. See + * {@link Zend_Media_Id3v2} for details. This method returns that character + * encoding, or any value set after read, translated into a string form + * regarless if it was set using a {@link Zend_Media_Id3_Encoding} constant + * or a string. + * + * @return integer + */ + public function getEncoding() + { + return $this->_translateIntToEncoding($this->_encoding); + } + + /** + * Sets the text encoding. + * + * All the string written to the frame are done so using given character + * encoding. No conversions of existing data take place upon the call to + * this method thus all texts must be given in given character encoding. + * + * The character encoding parameter takes either a + * {@link Zend_Media_Id3_Encoding} constant or a character set name string + * in the form accepted by iconv. The default character encoding used to + * write the frame is 'utf-8'. + * + * @see Zend_Media_Id3_Encoding + * @param integer $encoding The text encoding. + */ + public function setEncoding($encoding) + { + $this->_encoding = $this->_translateEncodingToInt($encoding); + } + + /** + * Returns the first text chunk the frame contains. + * + * @return string + */ + public function getText() + { + return $this->_text[0]; + } + + /** + * Returns an array of texts the frame contains. + * + * @return Array + */ + public function getTexts() + { + return $this->_text; + } + + /** + * Sets the text using given encoding. + * + * @param mixed $text The text string or an array of strings. + * @param integer $encoding The text encoding. + */ + public function setText($text, $encoding = null) + { + $this->_text = is_array($text) ? $text : array($text); + if ($encoding !== null) { + $this->setEncoding($encoding); + } + } + + /** + * Writes the frame raw data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt8($this->_encoding); + switch ($this->_encoding) { + case self::UTF16LE: + $count = count($this->_text); + for ($i = 0; $i < $count; $i++) { + $writer->writeString16 + ($text, Zend_Io_Writer::LITTLE_ENDIAN_ORDER, + $i == $count ? null : 1); + } + break; + case self::UTF16: + // break intentionally omitted + case self::UTF16BE: + $writer->write(implode("\0\0", $this->_text)); + break; + default: + $writer->write(implode("\0", $this->_text)); + break; + } + } +} diff --git a/src/Zend/Media/Id3/Timing.php b/src/Zend/Media/Id3/Timing.php new file mode 100644 index 0000000..a1a7f09 --- /dev/null +++ b/src/Zend/Media/Id3/Timing.php @@ -0,0 +1,60 @@ +Zend_Media_Id3_Timing interface implies that the implementing + * ID3v2 frame contains one or more 32-bit timestamps. + * + * The timestamps are absolute times, meaning that every stamp contains the time + * from the beginning of the file. + * + * @category Zend + * @package Zend_Media + * @subpackage ID3 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +interface Zend_Media_Id3_Timing +{ + /** The timestamp is an absolute time, using MPEG frames as unit. */ + const MPEG_FRAMES = 1; + + /** The timestamp is an absolute time, using milliseconds as unit. */ + const MILLISECONDS = 2; + + /** + * Returns the timing format. + * + * @return integer + */ + public function getFormat(); + + /** + * Sets the timing format. + * + + * @param integer $format The timing format. + */ + public function setFormat($format); +} diff --git a/src/Zend/Media/Id3v1.php b/src/Zend/Media/Id3v1.php new file mode 100644 index 0000000..977218c --- /dev/null +++ b/src/Zend/Media/Id3v1.php @@ -0,0 +1,405 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3v1 +{ + /** @var string */ + private $_title; + + /** @var string */ + private $_artist; + + /** @var string */ + private $_album; + + /** @var string */ + private $_year; + + /** @var string */ + private $_comment; + + /** @var integer */ + private $_track; + + /** @var integer */ + private $_genre = 255; + + /** + * The genre list. + * + * @var Array + */ + public static $genres = array + ('Blues', 'Classic Rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', + 'Hip-Hop', 'Jazz', 'Metal', 'New Age', 'Oldies', 'Other', 'Pop', 'R&B', + 'Rap', 'Reggae', 'Rock', 'Techno', 'Industrial', 'Alternative', 'Ska', + 'Death Metal', 'Pranks', 'Soundtrack', 'Euro-Techno', 'Ambient', + 'Trip-Hop', 'Vocal', 'Jazz+Funk', 'Fusion', 'Trance', 'Classical', + 'Instrumental', 'Acid', 'House', 'Game', 'Sound Clip', 'Gospel', + 'Noise', 'AlternRock', 'Bass', 'Soul', 'Punk', 'Space', 'Meditative', + 'Instrumental Pop', 'Instrumental Rock', 'Ethnic', 'Gothic', + 'Darkwave', 'Techno-Industrial', 'Electronic', 'Pop-Folk', 'Eurodance', + 'Dream', 'Southern Rock', 'Comedy', 'Cult', 'Gangsta', 'Top 40', + 'Christian Rap', 'Pop/Funk', 'Jungle', 'Native American', 'Cabaret', + 'New Wave', 'Psychadelic', 'Rave', 'Showtunes', 'Trailer', 'Lo-Fi', + 'Tribal', 'Acid Punk', 'Acid Jazz', 'Polka', 'Retro', 'Musical', + 'Rock & Roll', 'Hard Rock', 'Folk', 'Folk-Rock', 'National Folk', + 'Swing', 'Fast Fusion', 'Bebob', 'Latin', 'Revival', 'Celtic', + 'Bluegrass', 'Avantgarde', 'Gothic Rock', 'Progressive Rock', + 'Psychedelic Rock', 'Symphonic Rock', 'Slow Rock', 'Big Band', + 'Chorus', 'Easy Listening', 'Acoustic', 'Humour', 'Speech', 'Chanson', + 'Opera', 'Chamber Music', 'Sonata', 'Symphony', 'Booty Bass', 'Primus', + 'Porn Groove', 'Satire', 'Slow Jam', 'Club', 'Tango', 'Samba', + 'Folklore', 'Ballad', 'Power Ballad', 'Rhythmic Soul', 'Freestyle', + 'Duet', 'Punk Rock', 'Drum Solo', 'A capella', 'Euro-House', + 'Dance Hall', 255 => 'Unknown'); + + /** @var Zend_Io_Reader */ + private $_reader; + + /** @var string */ + private $_filename = null; + + /** + * Constructs the Id3v1 class with given file. The file is not mandatory + * argument and may be omitted as a new tag can be written to a file also by + * giving the filename to the {@link #write} method of this class. + * + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @throws Zend_Media_Id3_Exception if given file descriptor is not valid + */ + public function __construct($filename = null) + { + if ($filename === null) { + return; + } + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + $this->_filename = $filename; + require_once('Zend/Io/FileReader.php'); + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception($e->getMessage()); + } + } + + if ($this->_reader->getSize() < 128) { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('File does not contain ID3v1 tag'); + } + $this->_reader->setOffset(-128); + if ($this->_reader->read(3) != 'TAG') { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('File does not contain ID3v1 tag'); + } + + $this->_title = $this->_reader->readString8(30, " \0"); + $this->_artist = $this->_reader->readString8(30, " \0"); + $this->_album = $this->_reader->readString8(30, " \0"); + $this->_year = $this->_reader->readString8(4); + $this->_comment = $this->_reader->readString8(28); + + /* ID3v1.1 support for tracks */ + $v11_null = $this->_reader->read(1); + $v11_track = $this->_reader->read(1); + if (ord($v11_null) == 0 && ord($v11_track) != 0) { + $this->_track = ord($v11_track); + } else { + $this->_comment = rtrim + ($this->_comment . $v11_null . $v11_track, " \0"); + } + + $this->_genre = $this->_reader->readInt8(); + } + + /** + * Returns the title field. + * + * @return string + */ + public function getTitle() + { + return $this->_title; + } + + /** + * Sets a new value for the title field. The field cannot exceed 30 + * characters in length. + * + * @param string $title The title. + */ + public function setTitle($title) + { + $this->_title = $title; + } + + /** + * Returns the artist field. + * + * @return string + */ + public function getArtist() + { + return $this->_artist; + } + + /** + * Sets a new value for the artist field. The field cannot exceed 30 + * characters in length. + * + * @param string $artist The artist. + */ + public function setArtist($artist) + { + $this->_artist = $artist; + } + + /** + * Returns the album field. + * + * @return string + */ + public function getAlbum() + { + return $this->_album; + } + + /** + * Sets a new value for the album field. The field cannot exceed 30 + * characters in length. + * + * @param string $album The album. + */ + public function setAlbum($album) + { + $this->_album = $album; + } + + /** + * Returns the year field. + * + * @return string + */ + public function getYear() + { + return $this->_year; + } + + /** + * Sets a new value for the year field. The field cannot exceed 4 + * characters in length. + * + * @param string $year The year. + */ + public function setYear($year) + { + $this->_year = $year; + } + + /** + * Returns the comment field. + * + * @return string + */ + public function getComment() + { + return $this->_comment; + } + + /** + * Sets a new value for the comment field. The field cannot exceed 30 + * characters in length. + * + * @param string $comment The comment. + */ + public function setComment($comment) + { + $this->_comment = $comment; + } + + /** + * Returns the track field. + * + * @since ID3v1.1 + * @return integer + */ + public function getTrack() + { + return $this->_track; + } + + /** + * Sets a new value for the track field. By setting this field you enforce + * the 1.1 version to be used. + * + * @since ID3v1.1 + * @param integer $track The track number. + */ + public function setTrack($track) + { + $this->_track = $track; + } + + /** + * Returns the genre. + * + * @return string + */ + public function getGenre() + { + if (isset(self::$genres[$this->_genre])) + return self::$genres[$this->_genre]; + else + return self::$genres[255]; // unknown + } + + /** + * Sets a new value for the genre field. The value may either be a numerical + * code representing one of the genres, or its string variant. + * + * The genre is set to unknown (code 255) in case the string is not found + * from the static {@link $genres} array of this class. + * + * @param integer $genre The genre. + */ + public function setGenre($genre) + { + if ((is_numeric($genre) && $genre >= 0 && $genre <= 255) || + ($genre = array_search($genre, self::$genres)) !== false) + $this->_genre = $genre; + else + $this->_genre = 255; // unknown + } + + /** + * Writes the possibly altered ID3v1 tag back to the file where it was read. + * If the class was constructed without a file name, one can be provided + * here as an argument. Regardless, the write operation will override + * previous tag information, if found. + * + * @param string $filename The optional path to the file. + * @throws Zend_Media_Id3_Exception if there is no file to write the tag to + */ + public function write($filename = null) + { + if ($filename === null && ($filename = $this->_filename) === null) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('No file given to write the tag to'); + } + + require_once('Zend/Io/FileWriter.php'); + try { + $writer = new Zend_Io_FileWriter($filename); + $offset = $writer->getSize(); + if ($this->_reader !== null) { + $offset = -128; + } else { + $reader = new Zend_Io_Reader($writer->getFileDescriptor()); + $reader->setOffset(-128); + if ($reader->read(3) == 'TAG') + $offset = -128; + } + $writer->setOffset($offset); + $writer->writeString8('TAG') + ->writeString8(substr($this->_title, 0, 30), 30) + ->writeString8(substr($this->_artist, 0, 30), 30) + ->writeString8(substr($this->_album, 0, 30), 30) + ->writeString8(substr($this->_year, 0, 4), 4); + if ($this->_track) { + $writer->writeString8(substr($this->_comment, 0, 28), 28) + ->writeInt8(0) + ->writeInt8($this->_track); + } else { + $writer->writeString8(substr($this->_comment, 0, 30), 30); + } + $writer->writeInt8($this->_genre); + $writer->flush(); + } catch (Zend_Io_Exception $e) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception($e->getMessage()); + } + + $this->_filename = $filename; + } + + /** + * Magic function so that $obj->value will work. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst(strtolower($name)))) { + return call_user_func + (array($this, 'get' . ucfirst(strtolower($name)))); + } else { + require_once('Zend/Media/Id3/Exception.php'); + throw new Zend_Media_Id3_Exception('Unknown 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(strtolower($name)))) { + call_user_func + (array($this, 'set' . ucfirst(strtolower($name))), $value); + } else { + require_once('Zend/Media/Id3/Exception.php'); + throw new Zend_Media_Id3_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Media/Id3v2.php b/src/Zend/Media/Id3v2.php new file mode 100644 index 0000000..5cfa5a1 --- /dev/null +++ b/src/Zend/Media/Id3v2.php @@ -0,0 +1,671 @@ + + * @author Ryan Butterfield + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Id3v2 extends Zend_Media_Id3_Object +{ + /** @var Zend_Media_Id3_Header */ + private $_header; + + /** @var Zend_Media_Id3_ExtendedHeader */ + private $_extendedHeader; + + /** @var Zend_Media_Id3_Header */ + private $_footer; + + /** @var Array */ + private $_frames = array(); + + /** @var string */ + private $_filename = null; + + /** + * Constructs the Zend_Media_Id3v2 class with given file and options. The + * options array may also be given as the only parameter. + * + * The following options are currently recognized: + * o encoding -- Indicates the encoding that all the texts are presented + * with. See the documentation of iconv for supported values. Please + * note that write operations do not convert string and thus encodings + * are limited to those supported by the {@link Zend_Media_Id3_Encoding} + * interface. + * o version -- The ID3v2 tag version to use in write operation. This + * option is automatically set when a tag is read from a file and + * defaults to version 4.0 for tag write. + * o readonly -- Indicates that the tag is read from a temporary file or + * another source it cannot be written back to. The tag can, however, + * still be written to another file. + * + * @todo Only limited subset of flags are processed. + * @todo Utilize the SEEK frame and search for a footer to find the tag + * @todo Utilize the LINK frame to fetch frames from other sources + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @param Array $options The options array. + * @throws Zend_Media_Id3_Exception if given file descriptor is not valid + */ + public function __construct($filename = null, $options = array()) + { + parent::__construct(null, $options); + + if (is_array($filename)) { + $options = $filename; + $filename = null; + } + + if ($filename === null) { + $this->_header = new Zend_Media_Id3_Header(null, $options); + return; + } + + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + require_once 'Zend/Io/FileReader.php'; + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception($e->getMessage()); + } + if (is_string($filename) && !isset($options['readonly'])) { + $this->_filename = $filename; + } + } + + $startOffset = $this->_reader->getOffset(); + + if ($this->_reader->read(3) != 'ID3') { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('File does not contain ID3v2 tag'); + } + + $this->_header = new Zend_Media_Id3_Header($this->_reader, $options); + + $tagSize = $this->_header->getSize(); + + if ($this->_header->getVersion() < 3 || + $this->_header->getVersion() > 4) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('File does not contain ID3v2 tag of supported version: v2.' . + $this->_header->getVersion()); + } + if ($this->_header->getVersion() < 4 && + $this->_header->hasFlag(Zend_Media_Id3_Header::UNSYNCHRONISATION)) { + $data = $this->_reader->read($this->_header->getSize()); + require_once 'Zend/Io/StringReader.php'; + $this->_reader = new Zend_Io_StringReader + ($this->_decodeUnsynchronisation($data)); + $tagSize = $this->_reader->getSize(); + } + $this->clearOption('unsyncronisation'); + if ($this->_header->hasFlag(Zend_Media_Id3_Header::UNSYNCHRONISATION)) { + $this->setOption('unsyncronisation', true); + } + if ($this->_header->hasFlag(Zend_Media_Id3_Header::EXTENDED_HEADER)) { + require_once 'Zend/Media/Id3/ExtendedHeader.php'; + $this->_extendedHeader = + new Zend_Media_Id3_ExtendedHeader($this->_reader, $options); + } + if ($this->_header->hasFlag(Zend_Media_Id3_Header::FOOTER)) { + // skip footer, and rather copy header + $this->_footer = &$this->_header; + } + + while (true) { + $offset = $this->_reader->getOffset(); + + // Jump off the loop if we reached the end of the tag + if ($offset - $startOffset - 10 >= $tagSize - + ($this->hasFooter() ? 10 : 0) - 10 /* header */) { + break; + } + + // Jump off the loop if we reached padding + if (ord($identifier = $this->_reader->read(1)) === 0) { + break; + } + + $identifier .= $this->_reader->read(3); + + // Jump off the loop if we reached invalid entities. This fix is + // just to make things work. Utility called MP3ext does not seem + // to know what it is doing as it uses padding to write its + // version information there. + if ($identifier == 'MP3e') { + break; + } + + $this->_reader->setOffset($offset); + if (@fopen($file = 'Zend/Media/Id3/Frame/' . + ucfirst(strtolower($identifier)) . '.php', 'r', + true) !== false) { + require_once($file); + } + if (class_exists + ($classname = 'Zend_Media_Id3_Frame_' . + ucfirst(strtolower($identifier)))) { + $frame = new $classname($this->_reader, $options); + } else { + require_once 'Zend/Media/Id3/Frame/Unknown.php'; + $frame = + new Zend_Media_Id3_Frame_Unknown($this->_reader, $options); + } + + if (!isset($this->_frames[$frame->getIdentifier()])) { + $this->_frames[$frame->getIdentifier()] = array(); + } + $this->_frames[$frame->getIdentifier()][] = $frame; + } + } + + /** + * Returns the header object. + * + * @return Zend_Media_Id3_Header + */ + public function getHeader() + { + return $this->_header; + } + + /** + * Checks whether there is an extended header present in the tag. Returns + * true if the header is present, false otherwise. + * + * @return boolean + */ + public function hasExtendedHeader() + { + if ($this->_header) { + return $this->_header->hasFlag + (Zend_Media_Id3_Header::EXTENDED_HEADER); + } + return false; + } + + /** + * Returns the extended header object if present, or false + * otherwise. + * + * @return Zend_Media_Id3_ExtendedHeader|false + */ + public function getExtendedHeader() + { + if ($this->hasExtendedHeader()) { + return $this->_extendedHeader; + } + return false; + } + + /** + * Sets the extended header object. + * + * @param Zend_Media_Id3_ExtendedHeader $extendedHeader The header object + */ + public function setExtendedHeader($extendedHeader) + { + if (is_subclass_of($extendedHeader, 'Zend_Media_Id3_ExtendedHeader')) { + $this->_header->flags = + $this->_header->flags | Zend_Media_Id3_Header::EXTENDED_HEADER; + $this->_extendedHeader->setOptions($this->getOptions()); + $this->_extendedHeader = $extendedHeader; + } else { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Invalid argument'); + } + } + + /** + * Checks whether there is a frame given as an argument defined in the tag. + * Returns true if one ore more frames are present, + * false otherwise. + * + * @param string $identifier The frame name. + * @return boolean + */ + public function hasFrame($identifier) + { + return isset($this->_frames[$identifier]); + } + + /** + * Returns all the frames the tag contains as an associate array. The frame + * identifiers work as keys having an array of frames as associated value. + * + * @return Array + */ + public function getFrames() + { + return $this->_frames; + } + + /** + * Returns an array of frames matching the given identifier or an empty + * array if no frames matched the identifier. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches + * any single character. + * + * Please note that one may also use the shorthand $obj->identifier to + * access the first frame with the identifier given. Wildcards cannot be + * used with the shorthand method. + * + * @param string $identifier The frame name. + * @return Array + */ + public function getFramesByIdentifier($identifier) + { + $matches = array(); + $searchPattern = '/^' . + str_replace(array('*', '?'), array('.*', '.'), $identifier) . '$/i'; + foreach ($this->_frames as $identifier => $frames) { + if (preg_match($searchPattern, $identifier)) { + foreach ($frames as $frame) { + $matches[] = $frame; + } + } + } + return $matches; + } + + /** + * Removes any frames matching the given object identifier. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches + * any single character. + * + * One may also use the shorthand unset($obj->identifier) to achieve the + * same result. Wildcards cannot be used with the shorthand method. + * + * @param string $identifier The frame name. + */ + public final function removeFramesByIdentifier($identifier) + { + $searchPattern = '/^' . + str_replace(array('*', '?'), array('.*', '.'), $identifier) . '$/i'; + foreach ($this->_frames as $identifier => $frames) { + if (preg_match($searchPattern, $identifier)) { + unset($this->_frames[$identifier]); + } + } + } + + /** + * Adds a new frame to the tag and returns it. + * + * @param Zend_Media_Id3_Frame $frame The frame to add. + * @return Zend_Media_Id3_Frame + */ + public function addFrame($frame) + { + $frame->setOptions($this->getOptions()); + if (!$this->hasFrame($frame->getIdentifier())) { + $this->_frames[$frame->getIdentifier()] = array(); + } + return $this->_frames[$frame->getIdentifier()][] = $frame; + } + + /** + * Remove the given frame from the tag. + * + * @param Zend_Media_Id3_Frame $frame The frame to remove. + */ + public function removeFrame($frame) + { + if (!$this->hasFrame($frame->getIdentifier())) { + return; + } + foreach ($this->_frames[$frame->getIdentifier()] as $key => $value) { + if ($frame === $value) { + unset($this->_frames[$frame->getIdentifier()][$key]); + } + } + } + + /** + * Checks whether there is a footer present in the tag. Returns + * true if the footer is present, false otherwise. + * + * @return boolean + */ + public function hasFooter() + { + return $this->_header->hasFlag(Zend_Media_Id3_Header::FOOTER); + } + + /** + * Returns the footer object if present, or false otherwise. + * + * @return Zend_Media_Id3_Header|false + */ + public function getFooter() + { + if ($this->hasFooter()) { + return $this->_footer; + } + return false; + } + + /** + * Sets whether the tag should have a footer defined. + * + * @param boolean $useFooter Whether the tag should have a footer + */ + public function setFooter($useFooter) + { + if ($useFooter) { + $this->_header->setFlags + ($this->_header->getFlags() | Zend_Media_Id3_Header::FOOTER); + $this->_footer = &$this->_header; + } else { + /* Count footer bytes towards the tag size, so it gets removed or + overridden upon re-write */ + if ($this->hasFooter()) { + $this->_header->setSize($this->_header->getSize() + 10); + } + + $this->_header->setFlags + ($this->_header->getFlags() & ~Zend_Media_Id3_Header::FOOTER); + $this->_footer = null; + } + } + + /** + * Writes the possibly altered ID3v2 tag back to the file where it was read. + * If the class was constructed without a file name, one can be provided + * here as an argument. Regardless, the write operation will override + * previous tag information, if found. + * + * If write is called without setting any frames to the tag, the tag is + * removed from the file. + * + * @param string|Zend_Io_Writer $filename The optional path to the file, use + * null to save to the same file. + */ + public function write($filename) + { + if ($filename === null && ($filename = $this->_filename) === null) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('No file given to write to'); + } else if ($filename !== null && $filename instanceof Zend_Io_Writer) { + require_once 'Zend/Io/Writer.php'; + $this->_writeData($filename); + return; + } else if ($filename !== null && $this->_filename !== null && + realpath($filename) != realpath($this->_filename) && + !copy($this->_filename, $filename)) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('Unable to copy source to destination: ' . + realpath($this->_filename) . '->' . realpath($filename)); + } + + if (($fd = fopen + ($filename, file_exists($filename) ? 'r+b' : 'wb')) === false) { + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception + ('Unable to open file for writing: ' . $filename); + } + + if ($this->_reader !== null) { + $oldTagSize = 10 /* header */ + $this->_header->getSize(); + } else { + $reader = new Zend_Io_Reader($fd); + if ($reader->read(3) == 'ID3') { + $header = new Zend_Media_Id3_Header($reader); + $oldTagSize = 10 /* header */ + $header->getSize(); + } else { + $oldTagSize = 0; + } + } + require_once 'Zend/Io/StringWriter.php'; + $tag = new Zend_Io_StringWriter(); + $this->_writeData($tag); + $tagSize = empty($this->_frames) ? 0 : $tag->getSize(); + + if ($tagSize > $oldTagSize || $tagSize == 0) { + fseek($fd, 0, SEEK_END); + $oldFileSize = ftell($fd); + ftruncate + ($fd, $newFileSize = $tagSize - $oldTagSize + $oldFileSize); + for ($i = 1, $cur = $oldFileSize; $cur > 0; $cur -= 1024, $i++) { + if ($cur >= 1024) { + fseek($fd, $off=-(($i * 1024) + + ($newFileSize - $oldFileSize)), SEEK_END); + $buffer = fread($fd, 1024); + fseek($fd, $off=-($i * 1024), SEEK_END); + $bytes = fwrite($fd, $buffer, 1024); + } else { + fseek($fd, 0); + $buffer = fread($fd, $cur); + fseek($fd, $off=$newFileSize % 1024 - $cur); + $bytes = fwrite($fd, $buffer, $cur); + } + } + if (($remaining = $oldFileSize % 1024) != 0) { + + } + fseek($fd, 0, SEEK_END); + } + fseek($fd, 0); + for ($i = 0; $i < $tagSize; $i += 1024) { + fseek($tag->getFileDescriptor(), $i); + $bytes = fwrite($fd, fread($tag->getFileDescriptor(), 1024)); + } + fclose($fd); + + $this->_filename = $filename; + } + + /** + * Writes the tag data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + private function _writeData($writer) + { + $this->clearOption('unsyncronisation'); + + $buffer = new Zend_Io_StringWriter(); + foreach ($this->_frames as $frames) { + foreach ($frames as $frame) { + $frame->write($buffer); + } + } + $frameData = $buffer->toString(); + $frameDataLength = strlen($frameData); + $paddingLength = 0; + + // ID3v2.4.0 supports frame level unsynchronisation. The corresponding + // option is set to true when any of the frames use the + // unsynchronisation scheme. + if ($this->getOption('unsyncronisation', false) === true) { + $this->_header->setFlags + ($this->_header->getFlags() | + Zend_Media_Id3_Header::UNSYNCHRONISATION); + } + + // ID3v2.3.0 supports only tag level unsynchronisation + if ($this->getOption('version', 4) < 4) { + $frameData = $this->_encodeUnsynchronisation($frameData); + if (($len = strlen($frameData)) != $frameDataLength) { + $frameDataLength = $len; + $this->_header->setFlags + ($this->_header->getFlags() | + Zend_Media_Id3_Header::UNSYNCHRONISATION); + } else { + $this->_header->setFlags + ($this->_header->getFlags() & + ~Zend_Media_Id3_Header::UNSYNCHRONISATION); + } + } + + // The tag padding is calculated as follows. If the tag can be written + // in the space of the previous tag, the remaining space is used for + // padding. If there is no previous tag or the new tag is bigger than + // the space taken by the previous tag, the padding is a constant + // 4096 bytes. + if ($this->hasFooter() === false) { + if ($this->_reader !== null && + $frameDataLength < $this->_header->getSize()) { + $paddingLength = $this->_header->getSize() - $frameDataLength; + } else { + $paddingLength = 4096; + } + } + + /* ID3v2.4.0 CRC calculated w/ padding */ + if ($this->getOption('version', 4) >= 4) { + $frameData = + str_pad($frameData, $frameDataLength += $paddingLength, "\0"); + } + + $extendedHeaderData = ''; + $extendedHeaderDataLength = 0; + if ($this->hasExtendedHeader()) { + $this->_extendedHeader->setPadding($paddingLength); + if ($this->_extendedHeader->hasFlag + (Zend_Media_Id3_ExtendedHeader::CRC32)) { + $crc = crc32($frameData); + if ($crc & 0x80000000) { + $crc = -(($crc ^ 0xffffffff) + 1); + } + $this->_extendedHeader->setCrc($crc); + } + $buffer = new Zend_Io_StringWriter(); + $this->_extendedHeader->write($buffer); + $extendedHeaderData = $buffer->toString(); + $extendedHeaderDataLength = strlen($extendedHeaderData); + } + + /* ID3v2.3.0 CRC calculated w/o padding */ + if ($this->getOption('version', 4) < 4) { + $frameData = + str_pad($frameData, $frameDataLength += $paddingLength, "\0"); + } + + $this->_header->setSize($extendedHeaderDataLength + $frameDataLength); + + $writer->write('ID3'); + $this->_header->write($writer); + $writer->write($extendedHeaderData); + $writer->write($frameData); + if ($this->hasFooter()) { + $writer->write('3DI'); + $this->_footer->write($writer); + } + } + + /** + * Magic function so that $obj->value will work. The method will attempt to + * return the first frame that matches the identifier. + * + * If there is no frame or field with given name, the method will attempt to + * create a frame with given identifier. + * + * If none of these work, an exception is thrown. + * + * @param string $name The frame or field name. + * @return mixed + */ + public function __get($name) + { + if (isset($this->_frames[strtoupper($name)])) { + return $this->_frames[strtoupper($name)][0]; + } + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func + (array($this, 'get' . ucfirst($name))); + } + if (@fopen($filename = 'Zend/Media/Id3/Frame/' . ucfirst($name) . + '.php', 'r', true) !== false) { + require_once $filename; + } + if (class_exists + ($classname = 'Zend_Media_Id3_Frame_' . ucfirst($name))) { + return $this->addFrame(new $classname()); + } + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Id3_Exception('Unknown frame/field: ' . $name); + } + + /** + * Magic function so that isset($obj->value) will work. This method checks + * whether the frame matching the identifier exists. + * + * @param string $name The frame identifier. + * @return boolean + */ + public function __isset($name) + { + return isset($this->_frames[strtoupper($name)]); + } + + /** + * Magic function so that unset($obj->value) will work. This method removes + * all the frames matching the identifier. + * + * @param string $name The frame identifier. + */ + public function __unset($name) + { + unset($this->_frames[strtoupper($name)]); + } +} diff --git a/src/Zend/Media/Iso14496.php b/src/Zend/Media/Iso14496.php new file mode 100644 index 0000000..69d424a --- /dev/null +++ b/src/Zend/Media/Iso14496.php @@ -0,0 +1,404 @@ + + *
  • ftyp -- {@link Zend_Media_Iso14496_Box_Ftyp File Type Box}; + * file type and compatibility + *
  • pdin -- {@link Zend_Media_Iso14496_Box_Pdin Progressive Download + * Information Box} + *
  • moov -- {@link Zend_Media_Iso14496_Box_Moov Movie Box}; + * container for all the metadata + *
      + *
    • mvhd -- {@link Zend_Media_Iso14496_Box_Mvhd Movie Header + * Box}; overall declarations + *
    • trak -- {@link Zend_Media_Iso14496_Box_Trak Track Box}; + * container for an individual track or stream + *
        + *
      • tkhd -- {@link Zend_Media_Iso14496_Box_Tkhd Track Header + * Box}; overall information about the track + *
      • tref -- {@link Zend_Media_Iso14496_Box_Tref Track Reference + * Box} + *
      • edts -- {@link Zend_Media_Iso14496_Box_Edts Edit Box} + *
          + *
        • elst -- {@link Zend_Media_Iso14496_Box_Elst Edit List Box} + *
        + *
      • mdia -- {@link Zend_Media_Iso14496_Box_Mdia Media Box} + *
          + *
        • mdhd -- {@link Zend_Media_Iso14496_Box_Mdhd Media Header + * Box}; overall information about the media + *
        • hdlr -- {@link Zend_Media_Iso14496_Box_Hdlr Handler + * Reference Box}; declares the media type + *
        • minf -- {@link Zend_Media_Iso14496_Box_Minf Media + * Information Box} + *
            + *
          • vmhd -- {@link Zend_Media_Iso14496_Box_Vmhd Video Media Header + * Box}; overall information (video track only) + *
          • smhd -- {@link Zend_Media_Iso14496_Box_Smhd Sound Media Header + * Box}; overall information (sound track only) + *
          • hmhd -- {@link Zend_Media_Iso14496_Box_Hmhd Hint Media Header + * Box}; overall information (hint track only) + *
          • nmhd -- {@link Zend_Media_Iso14496_Box_Nmhd Null Media Header + * Box}; overall information (some tracks only) + *
          • dinf -- {@link Zend_Media_Iso14496_Box_Dinf Data + * Information Box} + *
              + *
            • dref -- {@link Zend_Media_Iso14496_Box_Dref Data + * Reference Box} + *
            + *
          • stbl -- {@link Zend_Media_Iso14496_Box_Stbl Sample + * Table Box} + *
              + *
            • stsd -- {@link Zend_Media_Iso14496_Box_Stsd Sample + * Descriptions Box} + *
            • stts -- {@link Zend_Media_Iso14496_Box_Stts Decoding + * Time To Sample Box} + *
            • ctts -- {@link Zend_Media_Iso14496_Box_Ctts Composition Time + * To Sample Box} + *
            • stsc -- {@link Zend_Media_Iso14496_Box_Stsc Sample To + * Chunk Box} + *
            • stsz -- {@link Zend_Media_Iso14496_Box_Stsz Sample Size + * Box} + *
            • stz2 -- {@link Zend_Media_Iso14496_Box_Stz2 Compact Sample + * Size Box} + *
            • stco -- {@link Zend_Media_Iso14496_Box_Stco Chunk + * Offset Box}; 32-bit + *
            • co64 -- {@link Zend_Media_Iso14496_Box_Co64 Chunk Ooffset + * Box}; 64-bit + *
            • stss -- {@link Zend_Media_Iso14496_Box_Stss Sync Sample + * Table Box} + *
            • stsh -- {@link Zend_Media_Iso14496_Box_Stsh Shadow Sync + * Sample Table Box} + *
            • padb -- {@link Zend_Media_Iso14496_Box_Padb Padding Bits + * Box} + *
            • stdp -- {@link Zend_Media_Iso14496_Box_Stdp Sample + * Degradation Priority Box} + *
            • sdtp -- {@link Zend_Media_Iso14496_Box_Sdtp Independent and + * Disposable Samples Box} + *
            • sbgp -- {@link Zend_Media_Iso14496_Box_Sbgp Sample To Group + * Box} + *
            • sgpd -- {@link Zend_Media_Iso14496_Box_Sgpd Sample Group + * Description} + *
            • subs -- {@link Zend_Media_Iso14496_Box_Subs Sub-Sample + * Information Box} + *
            + *
          + *
        + *
      + *
    • mvex -- {@link Zend_Media_Iso14496_Box_Mvex Movie Extends Box} + *
        + *
      • mehd -- {@link Zend_Media_Iso14496_Box_Mehd Movie Extends Header + * Box} + *
      • trex -- {@link Zend_Media_Iso14496_Box_Trex Track Extends + * Box} + *
      + *
    • ipmc -- {@link Zend_Media_Iso14496_Box_Ipmc IPMP Control Box} + *
    + *
  • moof -- {@link Zend_Media_Iso14496_Box_Moof Movie Fragment Box} + *
      + *
    • mfhd -- {@link Zend_Media_Iso14496_Box_Mfhd Movie Fragment + * Header Box} + *
    • traf -- {@link Zend_Media_Iso14496_Box_Traf Track Fragment Box} + *
        + *
      • tfhd -- {@link Zend_Media_Iso14496_Box_Tfhd Track Fragment + * Header Box} + *
      • trun -- {@link Zend_Media_Iso14496_Box_Trun Track Fragment + * Run} + *
      • sdtp -- {@link Zend_Media_Iso14496_Box_Sdtp Independent and + * Disposable Samples} + *
      • sbgp -- {@link Zend_Media_Iso14496_Box_Sbgp !SampleToGroup + * Box} + *
      • subs -- {@link Zend_Media_Iso14496_Box_Subs Sub-Sample Information + * Box} + *
      + *
    + *
  • mfra -- {@link Zend_Media_Iso14496_Box_Mfra Movie Fragment Random + * Access Box} + *
      + *
    • tfra -- {@link Zend_Media_Iso14496_Box_Tfra Track Fragment Random + * Access Box} + *
    • mfro -- {@link Zend_Media_Iso14496_Box_Mfro Movie Fragment + * Random Access Offset Box} + *
    + *
  • mdat -- {@link Zend_Media_Iso14496_Box_Mdat Media Data Box} + *
  • free -- {@link Zend_Media_Iso14496_Box_Free Free Space Box} + *
  • skip -- {@link Zend_Media_Iso14496_Box_Skip Free Space Box} + *
      + *
    • udta -- {@link Zend_Media_Iso14496_Box_Udta User Data Box} + *
        + *
      • cprt -- {@link Zend_Media_Iso14496_Box_Cprt Copyright Box} + *
      + *
    + *
  • meta -- {@link Zend_Media_Iso14496_Box_Meta The Meta Box} + *
      + *
    • hdlr -- {@link Zend_Media_Iso14496_Box_Hdlr Handler Reference + * Box}; declares the metadata type + *
    • dinf -- {@link Zend_Media_Iso14496_Box_Dinf Data Information + * Box} + *
        + *
      • dref -- {@link Zend_Media_Iso14496_Box_Dref Data Reference + * Box}; declares source(s) of metadata items + *
      + *
    • ipmc -- {@link Zend_Media_Iso14496_Box_Ipmc IPMP Control Box} + *
    • iloc -- {@link Zend_Media_Iso14496_Box_Iloc Item Location Box} + *
    • ipro -- {@link Zend_Media_Iso14496_Box_Ipro Item Protection Box} + *
        + *
      • sinf -- {@link Zend_Media_Iso14496_Box_Sinf Protection Scheme + * Information Box} + *
          + *
        • frma -- {@link Zend_Media_Iso14496_Box_Frma Original Format + * Box} + *
        • imif -- {@link Zend_Media_Iso14496_Box_Imif IPMP Information + * Box} + *
        • schm -- {@link Zend_Media_Iso14496_Box_Schm Scheme Type Box} + *
        • schi -- {@link Zend_Media_Iso14496_Box_Schi Scheme Information + * Box} + *
        + *
      + *
    • iinf -- {@link Zend_Media_Iso14496_Box_Iinf Item Information + * Box} + *
        + *
      • infe -- {@link Zend_Media_Iso14496_Box_Infe Item Information Entry + * Box} + *
      + *
    • xml -- {@link Zend_Media_Iso14496_Box_Xml XML Box} + *
    • bxml -- {@link Zend_Media_Iso14496_Box_Bxml Binary XML Box} + *
    • pitm -- {@link Zend_Media_Iso14496_Box_Pitm Primary Item Reference + * Box} + *
    + * + * + * 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 -- {@link Zend_Media_Iso14496_Box_Moov Movie Box}; + * container for all the metadata + *
    • udta -- {@link Zend_Media_Iso14496_Box_Udta User Data Box} + *
    • meta -- {@link Zend_Media_Iso14496_Box_Meta The Meta Box} + *
        + *
      • ilst -- {@link Zend_Media_Iso14496_Box_Ilst The iTunes/iPod Tag + * Container Box} + *
      • id32 -- {@link Zend_Media_Iso14496_Box_Id32 The ID3v2 Box} + *
      + *
    + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496 extends Zend_Media_Iso14496_Box +{ + /** @var string */ + private $_filename; + + /** + * Constructs the Zend_Media_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. The use of base option implies readonly + * option. + * o readonly -- Indicates that the file is read from a temporary location + * or another source it cannot be written back to. + * + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @param Array $options The options array. + */ + public function __construct($filename, $options = array()) + { + if (isset($options['base'])) { + $options['readonly'] = true; + } + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + require_once 'Zend/Io/FileReader.php'; + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Id3/Exception.php'; + throw new Zend_Media_Iso14496_Exception($e->getMessage()); + } + if (is_string($filename) && !isset($options['readonly'])) { + $this->_filename = $filename; + } + } + $this->setOptions($options); + $this->setOffset(0); + $this->setSize($this->_reader->getSize()); + $this->setType('file'); + $this->setContainer(true); + $this->constructBoxes(); + } + + /** + * Writes the changes back to given media file. + * + * The write operation commits only changes made to the Movie Box. It + * further changes the order of the Movie Box and Media Data Box in a way + * compatible for progressive download from a web page. + * + * All box offsets must be assumed to be invalid after the write operation. + * + * @param string $filename The optional path to the file, use null to save + * to the same file. + */ + public function write($filename) + { + if ($filename === null && ($filename = $this->_filename) === null) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception + ('No file given to write to'); + } else if ($filename !== null && $this->_filename !== null && + realpath($filename) != realpath($this->_filename) && + !copy($this->_filename, $filename)) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception + ('Unable to copy source to destination: ' . + realpath($this->_filename) . '->' . realpath($filename)); + } + + if (($fd = fopen + ($filename, file_exists($filename) ? 'r+b' : 'wb')) === false) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception + ('Unable to open file for writing: ' . $filename); + } + + /* Calculate file size */ + fseek($fd, 0, SEEK_END); + $oldFileSize = ftell($fd); + $oldMoovSize = $this->moov->getSize(); + $this->moov->udta->meta->free->setSize(8); + $this->moov->udta->meta->hdlr->setHandlerType('mdir'); + $newFileSize = $oldFileSize - $oldMoovSize + $this->moov->getHeapSize(); + + /* Calculate free space size */ + if ($oldFileSize < $newFileSize || + $this->mdat->getOffset() < $this->moov->getOffset()) { + // Add constant 4096 bytes for free space to be used later + $this->moov->udta->meta->free->setSize(8 /* header */ + 4096); + ftruncate($fd, $newFileSize += 4096); + } else { + // Adjust free space to fill up the rest of the space + $this->moov->udta->meta->free->setSize + (8 + $oldFileSize - $newFileSize); + $newFileSize = $oldFileSize; + } + + /* Calculate positions */ + if ($this->mdat->getOffset() < $this->moov->getOffset()) { + $start = $this->mdat->getOffset(); + $until = $this->moov->getOffset(); + $where = $newFileSize; + $delta = $this->moov->getHeapSize(); + } else { + $start = $this->moov->getOffset(); + $until = $oldFileSize; + $where = $newFileSize; + $delta = $newFileSize - $oldFileSize; + } + + /* Move data to the end of the file */ + if ($newFileSize != $oldFileSize) { + for ($i = 1, $cur = $until; $cur > $start; $cur -= 1024, $i++) { + fseek + ($fd, $until - (($i * 1024) + + ($excess = $cur - 1024 > $start ? + 0 : $cur - $start - 1024))); + $buffer = fread($fd, 1024); + fseek($fd, $where - (($i * 1024) + $excess)); + 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); + for ($i = 1; $i <= $chunkOffsetTableCount; $i++) { + $chunkOffsetTable[$i] += $delta; + } + $chunkOffsetBox->setChunkOffsetTable($chunkOffsetTable); + } + + /* Write moov box */ + fseek($fd, $start); + $this->moov->write(new Zend_Io_Writer($fd)); + fclose($fd); + } +} diff --git a/src/Zend/Media/Iso14496/Box.php b/src/Zend/Media/Iso14496/Box.php new file mode 100644 index 0000000..e39df0d --- /dev/null +++ b/src/Zend/Media/Iso14496/Box.php @@ -0,0 +1,667 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Iso14496_Box +{ + /** + * The reader object. + * + * @var Reader + */ + protected $_reader; + + /** @var Array */ + private $_options; + + /** @var integer */ + private $_offset = false; + + /** @var integer */ + private $_size = false; + + /** @var string */ + private $_type; + + /** @var Zend_Media_Iso14496_Box */ + private $_parent = null; + + /** @var boolean */ + private $_container = false; + + /** @var Array */ + private $_boxes = array(); + + /** @var Array */ + private static $_path = array(); + + /** + * Constructs the class with given parameters and options. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + 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() - $this->_offset; + } + if ($this->_type == 'uuid') { + $this->_type = $this->_reader->readGUID(); + } + } + $this->_options = &$options; + } + + /** + * Releases any references to contained boxes and the parent. + */ + public function __destruct() + { + unset($this->_boxes); + unset($this->_parent); + } + + /** + * Returns the options array. + * + * @return Array + */ + public final 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 final function getOption($option, $defaultValue = null) + { + if (isset($this->_options[$option])) { + return $this->_options[$option]; + } + return $defaultValue; + } + + /** + * Sets the options array. See {@link Zend_Media_Id3v2} class for available + * options. + * + * @param Array $options The options array. + */ + public final 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 final function setOption($option, $value) + { + $this->_options[$option] = $value; + } + + /** + * Clears the given option value. + * + * @param string $option The name of the option. + */ + public final function clearOption($option) + { + unset($this->_options[$option]); + } + + /** + * Returns the file offset to box start, or false if the box was + * created on heap. + * + * @return integer + */ + public final function getOffset() + { + return $this->_offset; + } + + /** + * Sets the file offset where the box starts. + * + * @param integer $offset The file offset to box start. + */ + public final function setOffset($offset) + { + $this->_offset = $offset; + } + + /** + * Returns the box size in bytes read from the file, including the size and + * type header, fields, and all contained boxes, or false if the + * box was created on heap. + * + * @return integer + */ + public final 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. + * + * @param integer $size The box size. + */ + protected final 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 final function getType() + { + return $this->_type; + } + + /** + * Sets the box type. + * + * @param string $type The box type. + */ + public final function setType($type) + { + $this->_type = $type; + } + + /** + * Returns the parent box containing this box. + * + * @return Zend_Media_Iso14496_Box + */ + public final function getParent() + { + return $this->_parent; + } + + /** + * Sets the parent containing box. + * + * @param Zend_Media_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. + * + * @return boolean + */ + public final function isContainer() + { + return $this->_container; + } + + /** + * Returns a boolean value corresponding to whether the box is a container. + * + * @return boolean + */ + public final function getContainer() + { + return $this->_container; + } + + /** + * Sets whether the box is a container. + * + * @param boolean $container Whether the box is a container. + */ + protected final function setContainer($container) + { + $this->_container = $container; + } + + /** + * Reads and constructs the boxes found within this box. + * + * @todo Does not parse iTunes internal ---- boxes. + */ + protected final function constructBoxes + ($defaultclassname = 'Zend_Media_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 = rtrim($this->_reader->read(4), ' '); + if ($size == 1) { + $size = $this->_reader->readInt64BE(); + } + if ($size == 0) { + $size = $this->_reader->getSize() - $offset; + } + + if (preg_match("/^\xa9?[a-z0-9]{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 = 'Zend/Media/Iso14496/Box/' . + ucfirst($type) . '.php', 'r', true) !== false) { + require_once($filename); + } + if (class_exists + ($classname = 'Zend_Media_Iso14496_Box_' . + ucfirst($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); + } + + /** + * Checks whether the box given as an argument is present in the file. Returns + * true if one or more boxes are present, false + * otherwise. + * + * @param string $identifier The box identifier. + * @return boolean + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function hasBox($identifier) + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Box not a container'); + } + return isset($this->_boxes[$identifier]); + } + + /** + * Returns all the boxes the file contains as an associate array. The box + * identifiers work as keys having an array of boxes as associated value. + * + * @return Array + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function getBoxes() + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Box not a container'); + } + return $this->_boxes; + } + + /** + * Returns an array of boxes matching the given identifier or an empty array + * if no boxes matched the identifier. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches + * any single character. + * + * Please note that one may also use the shorthand $obj->identifier to + * access the first box with the identifier given. Wildcards cannot be used + * with the shorthand and they will not work with user defined uuid types. + * + * @param string $identifier The box identifier. + * @return Array + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function getBoxesByIdentifier($identifier) + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Box not a container'); + } + $matches = array(); + $searchPattern = "/^" . + str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; + foreach ($this->_boxes as $identifier => $boxes) { + if (preg_match($searchPattern, $identifier)) { + foreach ($boxes as $box) { + $matches[] = $box; + } + } + } + return $matches; + } + + /** + * Removes any boxes matching the given box identifier. + * + * The identifier may contain wildcard characters '*' and '?'. The asterisk + * matches against zero or more characters, and the question mark matches any + * single character. + * + * One may also use the shorthand unset($obj->identifier) to achieve the same + * result. Wildcards cannot be used with the shorthand method. + * + * @param string $identifier The box identifier. + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function removeBoxesByIdentifier($identifier) + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception("Box not a container"); + } + $searchPattern = "/^" . + str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i"; + foreach ($this->_objects as $identifier => $objects) { + if (preg_match($searchPattern, $identifier)) { + unset($this->_objects[$identifier]); + } + } + } + + /** + * Adds a new box into the current box and returns it. + * + * @param Zend_Media_Iso14496_Box $box The box to add + * @return Zend_Media_Iso14496_Box + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function addBox(&$box) + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Box not a container'); + } + $box->setParent($this); + $box->setOptions($this->_options); + if (!$this->hasBox($box->getType())) { + $this->_boxes[$box->getType()] = array(); + } + return $this->_boxes[$box->getType()][] = $box; + } + + /** + * Removes the given box. + * + * @param Zend_Media_Iso14496_Box $box The box to remove + * @throws Zend_Media_Iso14496_Exception if called on a non-container box + */ + public final function removeBox($box) + { + if (!$this->isContainer()) { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Box not a container'); + } + if ($this->hasBox($box->getType())) { + foreach ($this->_boxes[$box->getType()] as $key => $value) { + if ($box === $value) { + unset($this->_boxes[$box->getType()][$key]); + } + } + } + } + + /** + * Returns the number of boxes this box contains. + * + * @return integer + */ + public final function getBoxCount() + { + if (!$this->isContainer()) { + return 0; + } + return count($this->_boxes); + } + + /** + * Magic function so that $obj->value will work. If called on a container box, + * the method will first attempt to return the first contained box that + * matches the identifier, and if not found, invoke a getter method. + * + * If there are no boxes or getter methods with given name, the method + * 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 + */ + public function __get($name) + { + if ($this->isContainer() && + isset($this->_boxes[str_pad($name, 4, ' ')])) { + return $this->_boxes[str_pad($name, 4, ' ')][0]; + } + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func(array($this, 'get' . ucfirst($name))); + } + if (@fopen($filename = 'Zend/Media/Iso14496/Box/' . + ucfirst($name) . '.php', 'r', true) !== false) { + require_once($filename); + } + if (class_exists + ($classname = 'Zend_Media_Iso14496_Box_' . ucfirst($name))) { + return $this->addBox(new $classname()); + } + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_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 { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_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 + * identifier. + * + * @param string $name The box name. + * @return boolean + */ + public function __isset($name) + { + 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 heap size in bytes, including the size and + * type header, fields, and all contained boxes. The box size is updated to + * reflect that of the heap size upon write. Subclasses should overwrite + * this method and call the parent method to get the calculated header and + * subbox sizes and then add their own bytes to that. + * + * @return integer + */ + public function getHeapSize() + { + $size = 8; + if ($this->isContainer()) { + foreach ($this->getBoxes() as $name => $boxes) { + foreach ($boxes as $box) { + $size += $box->getHeapSize(); + } + } + } + if ($size > 0xffffffff) { + $size += 8; + } + if (strlen($this->_type) > 4) { + $size += 16; + } + return $size; + } + + /** + * Writes the box header. Subclasses should overwrite this method and call + * the parent method first and then write the box related data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + if (get_class($this) == "Zend_Media_Iso14496_Box") { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception + ('Unknown box \'' . $this->getType() . '\' cannot be written.'); + } + + $this->_size = $this->getHeapSize(); + if ($this->_size > 0xffffffff) { + $writer->writeUInt32BE(1); + } else { + $writer->writeUInt32BE($this->_size); + } + if (strlen($this->_type) > 4) { + $writer->write('uuid'); + } else { + $writer->write($this->_type); + } + if ($this->_size > 0xffffffff) { + $writer->writeInt64BE($this->_size); + } + if (strlen($this->_type) > 4) { + $writer->writeGuid($this->_type); + } + } + + /** + * Writes the frame data with the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + public function write($writer) + { + if (get_class($this) == "Zend_Media_Iso14496_Box") { + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception + ('Unknown box \'' . $this->getType() . '\' cannot be written.'); + } + + $this->_writeData($writer); + if ($this->isContainer()) { + foreach ($this->getBoxes() as $name => $boxes) { + foreach ($boxes as $box) { + $box->write($writer); + } + } + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Bxml.php b/src/Zend/Media/Iso14496/Box/Bxml.php new file mode 100644 index 0000000..6690e25 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Bxml.php @@ -0,0 +1,118 @@ +XML Box forms may be used. + * The Binary XML Box may only be used when there is a single well-defined + * binarization of the XML for that defined format as identified by the handler. + * + * Within an XML box the data is in UTF-8 format unless the data starts with a + * byte-order-mark (BOM), which indicates that the data is in UTF-16 format. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Bxml extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_xml; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_xml = $this->_reader->read + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the XML data. + * + * @return string + */ + public function getXml() + { + return $this->_xml; + } + + /** + * Sets the binary data. + * + * @param string $xml The XML data. + */ + public function setXml($xml) + { + $this->_xml = $xml; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + strlen($this->_xml); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write($this->_xml); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Cdsc.php b/src/Zend/Media/Iso14496/Box/Cdsc.php new file mode 100644 index 0000000..8687442 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Cdsc.php @@ -0,0 +1,119 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Cdsc extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_trackId = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset <= $this->getSize()) { + $this->_trackId[] = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @return integer + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Sets an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @param Array $trackId The array of values. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_trackId) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_trackId); $i++) { + $writer->writeUInt32BE($this->_trackId[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Co64.php b/src/Zend/Media/Iso14496/Box/Co64.php new file mode 100644 index 0000000..6b45d57 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Co64.php @@ -0,0 +1,133 @@ +Chunk Offset Box table gives the index of each chunk into the + * containing file. There are two variants, permitting the use of 32-bit or + * 64-bit offsets. The latter is useful when managing very large presentations. + * At most one of these variants will occur in any single instance of a sample + * table. + * + * Offsets are file offsets, not the offset into any box within the file (e.g. + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Box}). This permits referring + * to media data in files without any box structure. It does also mean that care + * must be taken when constructing a self-contained ISO file with its metadata + * ({@link Zend_Media_Iso14496_Box_Moov Movie Box}) at the front, as the size of + * the {@link Zend_Media_Iso14496_Box_Moov Movie Box} will affect the chunk + * offsets to the media data. + * + * This box variant contains 64-bit offsets. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Co64 extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_chunkOffsetTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_chunkOffsetTable[$i] = $this->_reader->readInt64BE(); + } + } + + /** + * Returns an array of values. Each entry has 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. + * + * @return Array + */ + 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) + { + $this->_chunkOffsetTable = $chunkOffsetTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_chunkOffsetTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt32BE($entryCount = count($this->_chunkOffsetTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeInt64BE($this->_chunkOffsetTable[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Cprt.php b/src/Zend/Media/Iso14496/Box/Cprt.php new file mode 100644 index 0000000..7c61282 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Cprt.php @@ -0,0 +1,150 @@ +Copyright Box contains a copyright declaration which applies to + * the entire presentation, when contained within the + * {@link Zend_Media_Iso14496_Box_Moov Movie Box}, or, when contained in a + * track, to that entire track. There may be multiple copyright boxes using + * different language codes. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Cprt extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_language; + + /** @var string */ + private $_notice; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + * @todo Distinguish UTF-16? + */ + public function __construct($reader, &$options = array()) + { + 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->readString8 + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the three byte language code to describe the language of the + * notice, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @return string + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Sets the three byte language code to describe the language of this + * media, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @param string $language The language code. + */ + public function setLanguage($language) + { + $this->_language = $language; + } + + /** + * Returns the copyright notice. + * + * @return string + */ + public function getNotice() + { + return $this->_notice; + } + + /** + * Returns the copyright notice. + * + * @param string $notice The copyright notice. + */ + public function setNotice($notice) + { + $this->_notice = $notice; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 3 + strlen($this->_notice); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE((ord($this->_language[0]) - 0x60) << 10 | + (ord($this->_language[1])- 0x60) << 5 | + (ord($this->_language[2])- 0x60)) + ->writeString8($this->_notice, 1); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ctts.php b/src/Zend/Media/Iso14496/Box/Ctts.php new file mode 100644 index 0000000..694c6d0 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ctts.php @@ -0,0 +1,139 @@ +Composition Time to Sample Box provides the offset between + * decoding time and composition time. Since decoding time must be less than the + * composition time, the offsets are expressed as unsigned numbers such that + * CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for + * sample n. + * + * The composition time to sample table is optional and must only be present if + * DT and CT differ for any samples. Hint tracks do not use this box. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Ctts extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_compositionOffsetTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_compositionOffsetTable[$i] = array + ('sampleCount' => $this->_reader->readUInt32BE(), + 'sampleOffset' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given offset. + * o sampleOffset -- a non-negative integer that gives the offset between + * CT and DT, such that CT(n) = DT(n) + CTTS(n). + * + * @return Array + */ + public function getCompositionOffsetTable() + { + return $this->_compositionOffsetTable; + } + + /** + * Sets an array of values. Each entry must have an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given offset. + * o sampleOffset -- a non-negative integer that gives the offset between + * CT and DT, such that CT(n) = DT(n) + CTTS(n). + * + * @param Array $compositionOffsetTable The array of values. + */ + public function setCompositionOffsetTable($compositionOffsetTable) + { + $this->_compositionOffsetTable = $compositionOffsetTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + + count($this->_compositionOffsetTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_compositionOffsetTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE + ($this->_compositionOffsetTable[$i]['sampleCount']) + ->writeUInt32BE + ($this->_compositionOffsetTable[$i]['sampleOffset']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Dinf.php b/src/Zend/Media/Iso14496/Box/Dinf.php new file mode 100644 index 0000000..c69604f --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Dinf.php @@ -0,0 +1,72 @@ +Data Information Box contains objects that declare the location + * of the media information in a track. + * + + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Dinf extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Dref.php b/src/Zend/Media/Iso14496/Box/Dref.php new file mode 100644 index 0000000..40f629d --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Dref.php @@ -0,0 +1,100 @@ +Data Reference Box contains a table of data references (normally + * URLs) that declare the location(s) of the media data used within the + * presentation. The data reference index in the sample description ties entries + * in this table to the samples in the track. A track may be split over several + * sources in this way. + * + * This box may either contain {@link Zend_Media_Iso14496_Box_Urn urn} or + * {@link Zend_Media_Iso14496_Box_Url url} boxes. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Dref extends Zend_Media_Iso14496_FullBox +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->_reader->skip(4); + $this->constructBoxes(); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->getBoxCount()); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Edts.php b/src/Zend/Media/Iso14496/Box/Edts.php new file mode 100644 index 0000000..3f9ebe4 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Edts.php @@ -0,0 +1,76 @@ +Edit Box maps the presentation time-line to the media time-line as + * it is stored in the file. The Edit Box is a container for the edit lists. + * + * The Edit Box is optional. In the absence of this box, there is an implicit + * one-to-one mapping of these time-lines, and the presentation of a track + * starts at the beginning of the presentation. An empty edit is used to offset + * the start time of a track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Edts extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Elst.php b/src/Zend/Media/Iso14496/Box/Elst.php new file mode 100644 index 0000000..771185f --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Elst.php @@ -0,0 +1,169 @@ +Edit List Box contains an explicit timeline map. Each entry + * defines part of the track time-line: by mapping part of the media time-line, + * or by indicating empty time, or by defining a dwell, where a single + * time-point in the media is held for a period. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Elst extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_entries = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 0; $i < $entryCount; $i++) { + $entry = array(); + if ($this->getVersion() == 1) { + $entry['segmentDuration'] = $this->_reader->readInt64BE(); + $entry['mediaTime'] = $this->_reader->readInt64BE(); + } else { + $entry['segmentDuration'] = $this->_reader->readUInt32BE(); + $entry['mediaTime'] = $this->_reader->readInt32BE(); + } + $entry['mediaRate'] = + (float)($this->_reader->readInt16BE() . "." . + $this->_reader->readInt16BE()); + $this->_entries[] = $entry; + } + } + + /** + * Returns an array of entries. Each entry is an array containing the + * following keys. + * o segmentDuration: specifies the duration of this edit segment in units + * of the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. + * o mediaTime: the starting time within the media of this edit segment + * (in media time scale units, in composition time). If this field is + * set to –1, it is an empty edit. The last edit in a track shall never + * be an empty edit. Any difference between the duration in the + * {@link Zend_Media_Iso14496_Box_MVHD Movie Header Box}, and the + * track's duration is expressed as an implicit empty edit at the end. + * o mediaRate: the relative rate at which to play the media corresponding + * to this edit segment. If this value is 0, then the edit is specifying + * a dwell: the media at media-time is presented for the + * segment-duration. Otherwise this field shall contain the value 1. + * + * @return Array + */ + public function getEntries() + { + return $this->_entries; + } + + /** + * Sets the array of entries. Each entry must be an array containing the + * following keys. + * o segmentDuration: specifies the duration of this edit segment in units + * of the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. + * o mediaTime: the starting time within the media of this edit segment + * (in media time scale units, in composition time). If this field is + * set to –1, it is an empty edit. The last edit in a track shall never + * be an empty edit. Any difference between the duration in the + * {@link Zend_Media_Iso14496_Box_MVHD Movie Header Box}, and the + * track's duration is expressed as an implicit empty edit at the end. + * o mediaRate: the relative rate at which to play the media corresponding + * to this edit segment. If this value is 0, then the edit is specifying + * a dwell: the media at media-time is presented for the + * segment-duration. Otherwise this field shall contain the value 1. + * + * @param Array $entries The array of entries; + */ + public function setEntries($entries) + { + $this->_entries = $entries; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_entries) * + ($this->getVersion() == 1 ? 20 : 12); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_entries)); + for ($i = 0; $i < $entryCount; $i++) { + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_entries[$i]['segmentDuration']) + ->writeInt64BE($this->_entries[$i]['mediaTime']); + } else { + $writer->writeUInt32BE($this->_entries[$i]['segmentDuration']) + ->writeInt32BE($this->_entries[$i]['mediaTime']); + } + @list($mediaRateInteger, $mediaRateFraction) = explode + ('.', (float)$this->_entries[$i]['mediaRate']); + $writer->writeInt16BE($mediaRateInteger) + ->writeInt16BE($mediaRateFraction); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Free.php b/src/Zend/Media/Iso14496/Box/Free.php new file mode 100644 index 0000000..2f8b997 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Free.php @@ -0,0 +1,89 @@ +Free Space Box are irrelevant and may be ignored, or + * the object deleted, without affecting the presentation. (Care should be + * exercised when deleting the object, as this may invalidate the offsets used + * in the sample table, unless this object is after all the media data). + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Free extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return ($this->getSize() >= 8 ? $this->getSize() : 0); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + if ($this->getSize() >= 8) { + parent::_writeData($writer); + $writer->write(str_repeat("\0", $this->getSize() - 8)); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Frma.php b/src/Zend/Media/Iso14496/Box/Frma.php new file mode 100644 index 0000000..210c575 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Frma.php @@ -0,0 +1,116 @@ +Original Format Box contains the four-character-code of the + * original un-transformed sample description. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Frma extends Zend_Media_Iso14496_Box +{ + /** @var string */ + private $_dataFormat; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_dataFormat = $this->_reader->read(4); + } + + /** + * Returns the four-character-code of the original un-transformed sample + * entry (e.g. mp4v if the stream contains protected MPEG-4 visual + * material). + * + * @return string + */ + public function getDataFormat() + { + return $this->_dataFormat; + } + + /** + * Sets the four-character-code of the original un-transformed sample + * entry (e.g. mp4v if the stream contains protected MPEG-4 visual + * material). + * + * @param string $dataFormat The data format. + */ + public function setDataFormat($dataFormat) + { + $this->_dataFormat = $dataFormat; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->write(substr($this->_dataFormat, 0, 4)); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ftyp.php b/src/Zend/Media/Iso14496/Box/Ftyp.php new file mode 100644 index 0000000..d70c239 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ftyp.php @@ -0,0 +1,210 @@ +File Type Box is placed as early as possible in the file (e.g. + * after any obligatory signature, but before any significant variable-size + * boxes such as a {@link Zend_Media_Iso14496_Box_Moov Movie Box}, + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Box}, or + * {@link Zend_Media_Iso14496_Box_Free Free Space}). It identifies which + * specification is the best use of the file, and a minor version of + * that specification; and also a set of others specifications to which the + * file complies. + * + * The minor version is informative only. It does not appear for + * compatible-brands, and must not be used to determine the conformance of a + * file to a standard. It may allow more precise identification of the major + * specification, for inspection, debugging, or improved decoding. + * + * The type isom (ISO Base Media file) is defined as identifying files + * that conform to the first version of the ISO Base Media File Format. More + * specific identifiers can be used to identify precise versions of + * specifications providing more detail. This brand is not be used as the major + * brand; this base file format should be derived into another specification to + * be used. There is therefore no defined normal file extension, or mime type + * assigned to this brand, nor definition of the minor version when isom + * is the major brand. + * + * Files would normally be externally identified (e.g. with a file extension or + * mime type) that identifies the best use (major brand), or the brand + * that the author believes will provide the greatest compatibility. + * + * The brand iso2 shall be used to indicate compatibility with the + * amended version of the ISO Base Media File Format; it may be used in addition + * to or instead of the isom brand and the same usage rules apply. If + * used without the brand isom identifying the first version of the + * specification, it indicates that support for some or all of the technology + * introduced by the amended version of the ISO Base Media File Format is + * required. + * + * The brand avc1 shall be used to indicate that the file is conformant + * with the AVC Extensions. If used without other brands, this implies + * that support for those extensions is required. The use of avc1 as a + * major-brand may be permitted by specifications; in that case, that + * specification defines the file extension and required behavior. + * + * If a Meta-box with an MPEG-7 handler type is used at the file level, then the + * brand mp71 is a member of the compatible-brands list in the file-type + * box. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Ftyp extends Zend_Media_Iso14496_Box +{ + /** @var integer */ + private $_majorBrand; + + /** @var integer */ + private $_minorVersion; + + /** @var integer */ + private $_compatibleBrands = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_majorBrand = $this->_reader->readString8(4); + $this->_minorVersion = $this->_reader->readUInt32BE(); + while ($this->_reader->getOffset() < $this->getSize()) { + if (($brand = $this->_reader->readString8(4)) != '') { + $this->_compatibleBrands[] = $brand; + } + } + } + + /** + * Returns the major version brand. + * + * @return string + */ + public function getMajorBrand() + { + return $this->_majorBrand; + } + + /** + * Sets the major version brand. + * + * @param string $majorBrand The major version brand. + */ + public function setMajorBrand($majorBrand) + { + $this->_majorBrand = $majorBrand; + } + + /** + * Returns the minor version number. + * + * @return integer + */ + public function getMinorVersion() + { + return $this->_minorVersion; + } + + /** + * Sets the minor version number. + * + * @param integer $minorVersion The minor version number. + */ + public function setMinorVersion($minorVersion) + { + $this->_minorVersion = $minorVersion; + } + + /** + * Returns the array of compatible version brands. + * + * @return Array + */ + public function getCompatibleBrands() + { + return $this->_compatibleBrands; + } + + /** + * Sets the array of compatible version brands. + * + * @param Array $compatibleBrands The array of compatible version brands. + */ + public function setCompatibleBrands($compatibleBrands) + { + $this->_compatibleBrands = $compatibleBrands; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8 + 4 * count($this->_compatibleBrands); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->writeString8(substr($this->_majorBrand, 0, 4)) + ->writeUInt32BE($this->_minorVersion); + for ($i = 0; $i < count($this->_compatibleBrands); $i++) { + $writer->writeString8(substr($this->_compatibleBrands[$i], 0, 4)); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Hdlr.php b/src/Zend/Media/Iso14496/Box/Hdlr.php new file mode 100644 index 0000000..b3a5996 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Hdlr.php @@ -0,0 +1,174 @@ +Handler Reference Box is within a + * {@link Zend_Media_Iso14496_Box_Mdia Media Box} declares the process by which + * the media-data in the track is presented, and thus, the nature of the media + * in a track. For example, a video track would be handled by a video handler. + * + * This box when present within a {@link Zend_Media_Iso14496_Box_Meta Meta Box}, + * declares the structure or format of the meta box contents. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Hdlr extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_handlerType; + + /** @var string */ + private $_name; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + 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->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the handler type. + * + * When present in a media box, the returned value contains 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 returned value contains an appropriate + * value to indicate the format of the meta box contents. + * + * @return integer + */ + 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 + * purposes). + * + * @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 heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 21 + strlen($this->_name); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write(str_pad('', 4, "\0")) + ->write($this->_handlerType) + ->writeUInt32BE(0) + ->writeUInt32BE(0) + ->writeUInt32BE(0) + ->writeString8($this->_name, 1); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Hint.php b/src/Zend/Media/Iso14496/Box/Hint.php new file mode 100644 index 0000000..f638b25 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Hint.php @@ -0,0 +1,120 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Hint extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_trackId = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset <= $this->getSize()) { + $this->_trackId[] = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @return Array + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Sets an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @param Array $trackId The array of values. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_trackId) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_trackId); $i++) { + $writer->writeUInt32BE($this->_trackId[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Hmhd.php b/src/Zend/Media/Iso14496/Box/Hmhd.php new file mode 100644 index 0000000..ddfeed6 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Hmhd.php @@ -0,0 +1,187 @@ +Hint Media Header Box header contains general information, + * independent of the protocol, for hint tracks. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Hmhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_maxPDUSize; + + /** @var integer */ + private $_avgPDUSize; + + /** @var integer */ + private $_maxBitrate; + + /** @var integer */ + private $_avgBitrate; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_maxPDUSize = $this->_reader->readUInt16BE(); + $this->_avgPDUSize = $this->_reader->readUInt16BE(); + $this->_maxBitrate = $this->_reader->readUInt32BE(); + $this->_avgBitrate = $this->_reader->readUInt32BE(); + } + + /** + * Returns the size in bytes of the largest PDU in this (hint) stream. + * + * @return integer + */ + public function getMaxPDUSize() + { + return $this->_maxPDUSize; + } + + /** + * Returns the size in bytes of the largest PDU in this (hint) stream. + * + * @param integer $maxPDUSize The maximum size. + */ + public function setMaxPDUSize($maxPDUSize) + { + $this->_maxPDUSize = $maxPDUSize; + } + + /** + * Returns the average size of a PDU over the entire presentation. + * + * @return integer + */ + public function getAvgPDUSize() + { + return $this->_avgPDUSize; + } + + /** + * Sets the average size of a PDU over the entire presentation. + * + * @param integer $avgPDUSize The average size. + */ + public function setAvgPDUSize() + { + $this->_avgPDUSize = $avgPDUSize; + } + + /** + * Returns the maximum rate in bits/second over any window of one second. + * + * @return integer + */ + public function getMaxBitrate() + { + return $this->_maxBitrate; + } + + /** + * Sets the maximum rate in bits/second over any window of one second. + * + * @param integer $maxBitrate The maximum bitrate. + */ + public function setMaxBitrate($maxBitrate) + { + $this->_maxBitrate = $maxBitrate; + } + + /** + * Returns the average rate in bits/second over the entire presentation. + * + * @return integer + */ + public function getAvgBitrate() + { + return $this->_avgBitrate; + } + + /** + * Sets the average rate in bits/second over the entire presentation. + * + * @param integer $maxbitrate The agerage bitrate. + */ + public function setAvgBitrate($avgBitrate) + { + $this->_avgBitrate = $avgBitrate; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->writeUInt16BE($this->_maxPDUSize) + ->writeUInt16BE($this->_avgPDUSize) + ->writeUInt16BE($this->_maxBitrate) + ->writeUInt16BE($this->_avgBitrate); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Id32.php b/src/Zend/Media/Iso14496/Box/Id32.php new file mode 100644 index 0000000..3645bae --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Id32.php @@ -0,0 +1,160 @@ +ID3v2 Box resides under the + * {@link Zend_Media_Iso14496_Box_Meta Meta Box} and stores ID3 version 2 + * meta-data. There may be more than one Id3v2 Box present each with a different + * language code. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Id32 extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_language = 'und'; + + /** @var Zend_Media_Id3v2 */ + private $_tag; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_language = + chr(((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + + 0x60) . + chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60); + $this->_tag = new Zend_Media_Id3v2 + ($this->_reader, array('readonly' => true)); + } + + /** + * Returns the three byte language code to describe the language of this + * media, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @return string + */ + 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 Zend_Media_Id3v2 Id3v2} tag class instance. + * + * @return string + */ + public function getTag() + { + return $this->_tag; + } + + /** + * Sets the {@link Zend_Media_Id3v2 Id3v2} tag class instance using given + * language. + * + * @param Zend_Media_Id3v2 $tag The tag instance. + * @param string $language The language code. + */ + public function setTag($tag, $language = null) + { + $this->_tag = $tag; + if ($language !== null) { + $this->_language = $language; + } + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + * @todo There has got to be a better way to do this + */ + public function getHeapSize() + { + $writer = new Zend_Io_StringWriter(); + $this->_tag->write($writer); + return parent::getHeapSize() + 2 + $writer->getSize(); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE + (((ord($this->_language[0]) - 0x60) << 10) | + ((ord($this->_language[1]) - 0x60) << 5) | + ord($this->_language[2]) - 0x60); + $this->_tag->write($writer); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Iinf.php b/src/Zend/Media/Iso14496/Box/Iinf.php new file mode 100644 index 0000000..dbf61e1 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Iinf.php @@ -0,0 +1,100 @@ +Item Information Box provides extra information about selected + * items, including symbolic (file) names. It may optionally occur, but + * if it does, it must be interpreted, as item protection or content encoding + * may have changed the format of the data in the item. If both content encoding + * and protection are indicated for an item, a reader should first un-protect + * the item, and then decode the item's content encoding. If more control is + * needed, an IPMP sequence code may be used. + * + + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Iinf extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->_reader->skip(2); + $this->constructBoxes(); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE($this->getBoxCount()); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Iloc.php b/src/Zend/Media/Iso14496/Box/Iloc.php new file mode 100644 index 0000000..4be38d5 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Iloc.php @@ -0,0 +1,245 @@ +The Item Location Box provides a directory of resources in this or + * other files, by locating their containing file, their offset within that + * file, and their length. Placing this in binary format enables common handling + * of this data, even by systems which do not understand the particular metadata + * system (handler) used. For example, a system might integrate all the + * externally referenced metadata resources into one file, re-adjusting file + * offsets and file references accordingly. + * + * Items may be stored fragmented into extents, e.g. to enable interleaving. An + * extent is a contiguous subset of the bytes of the resource; the resource is + * formed by concatenating the extents. If only one extent is used then either + * or both of the offset and length may be implied: + * + * o If the offset is not identified (the field has a length of zero), then + * the beginning of the file (offset 0) is implied. + * o If the length is not specified, or specified as zero, then the entire + * file length is implied. References into the same file as this metadata, + * or items divided into more than one extent, should have an explicit + * offset and length, or use a MIME type requiring a different + * interpretation of the file, to avoid infinite recursion. + * + * The size of the item is the sum of the extentLengths. Note: extents may be + * interleaved with the chunks defined by the sample tables of tracks. + * + * The dataReferenceIndex may take the value 0, indicating a reference into the + * same file as this metadata, or an index into the dataReference table. + * + * Some referenced data may itself use offset/length techniques to address + * resources within it (e.g. an MP4 file might be included in this way). + * Normally such offsets are relative to the beginning of the containing file. + * The field base offset provides an additional offset for offset calculations + * within that contained data. For example, if an MP4 file is included within a + * file formatted to this specification, then normally data-offsets within that + * MP4 section are relative to the beginning of file; baseOffset adds to those + * offsets. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Iloc extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_items = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $offsetSize = (($tmp = $this->_reader->readUInt16BE()) >> 12) & 0xf; + $lengthSize = ($tmp >> 8) & 0xf; + $baseOffsetSize = ($tmp >> 4) & 0xf; + $itemCount = $this->_reader->readUInt16BE(); + for ($i = 0; $i < $itemCount; $i++) { + $item = array(); + $item['itemId'] = $this->_reader->readUInt16BE(); + $item['dataReferenceIndex'] = $this->_reader->readUInt16BE(); + $item['baseOffset'] = + ($baseOffsetSize == 4 ? $this->_reader->readUInt32BE() : + ($baseOffsetSize == 8 ? $this->_reader->readInt64BE() : 0)); + $extentCount = $this->_reader->readUInt16BE(); + $item['extents'] = array(); + for ($j = 0; $j < $extentCount; $j++) { + $extent = array(); + $extent['offset'] = + ($offsetSize == 4 ? $this->_reader->readUInt32BE() : + ($offsetSize == 8 ? $this->_reader->readInt64BE() : 0)); + $extent['length'] = + ($lengthSize == 4 ? $this->_reader->readUInt32BE() : + ($lengthSize == 8 ? $this->_reader->readInt64BE() : 0)); + $item['extents'][] = $extent; + } + $this->_items[] = $item; + } + } + + /** + * Returns the array of items. Each entry has the following keys set: + * itemId, dataReferenceIndex, baseOffset, and extents. + * + * @return Array + */ + public function getItems() + { + return $this->_items; + } + + /** + * Sets the array of items. Each entry must have the following keys set: + * itemId, dataReferenceIndex, baseOffset, and extents. + * + * @return Array + */ + public function setItems($items) + { + $this->_items = $items; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + $totalSize = 4; + for ($i = 0; $i < count($this->_itemId); $i++) { + $totalSize += 6; + if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) { + $totalSize += 8; + } else { + $totalSize += 4; + } + $extentCount = count($this->_itemId[$i]['extents']); + for ($j = 0; $j < $extentCount; $j++) { + if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) { + $totalSize += 8 * $extentCount; + } else { + $totalSize += 4 * $extentCount; + } + if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) { + $totalSize += 8 * $extentCount; + } else { + $totalSize += 4 * $extentCount; + } + } + } + return parent::getHeapSize() + $totalSize; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $offsetSize = 4; + $lengthSize = 4; + $baseOffsetSize = 4; + + $itemCount = count($this->_itemId); + for ($i = 0; $i < $itemCount; $i++) { + if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) { + $baseOffsetSize = 8; + } + for ($j = 0; $j < count($this->_itemId[$i]['extents']); $j++) { + if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) { + $offsetSize = 8; + } + if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) { + $lengthSize = 8; + } + } + } + + $writer->writeUInt16BE + ((($offsetSize & 0xf) << 12) | (($lengthSize & 0xf) << 8) | + (($baseOffsetSize & 0xf) << 4)) + ->writeUInt16BE($itemCount); + for ($i = 0; $i < $itemCount; $i++) { + $writer->writeUInt16BE($this->_itemId[$i]['itemId']) + ->writeUInt16BE($this->_itemId[$i]['dataReferenceIndex']); + if ($baseOffsetSize == 4) { + $writer->writeUInt32BE($this->_itemId[$i]['baseOffset']); + } + if ($baseOffsetSize == 8) { + $writer->writeInt64BE($this->_itemId[$i]['baseOffset']); + } + $writer->writeUInt16BE + ($extentCount = count($this->_itemId[$i]['extents'])); + for ($j = 0; $j < $extentCount; $j++) { + if ($offsetSize == 4) { + $writer->writeUInt32BE + ($this->_itemId[$i]['extents'][$j]['offset']); + } + if ($offsetSize == 8) { + $writer->writeInt64BE + ($this->_itemId[$i]['extents'][$j]['offset']); + } + if ($offsetSize == 4) { + $writer->writeUInt32BE + ($this->_itemId[$i]['extents'][$j]['length']); + } + if ($offsetSize == 8) { + $writer->writeInt64BE + ($this->_itemId[$i]['extents'][$j]['length']); + } + } + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ilst.php b/src/Zend/Media/Iso14496/Box/Ilst.php new file mode 100644 index 0000000..065e736 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ilst.php @@ -0,0 +1,326 @@ + + *
  • _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
  • + * + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since iTunes/iPod specific + */ +final class Zend_Media_Iso14496_Box_Ilst extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes('Zend_Media_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 Zend_Media_Iso14496_Box_Ilst_Container($name))->data; + } +} + +/** + * Generic iTunes/iPod DATA Box container. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since iTunes/iPod specific + * @ignore + */ +final class Zend_Media_Iso14496_Box_Ilst_Container + extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct(is_string($reader) ? null : $reader, $options); + $this->setContainer(true); + + if (is_string($reader)) { + $this->setType($reader); + $this->addBox(new Zend_Media_Iso14496_Box_Data()); + } else { + $this->constructBoxes(); + } + } +} + +/**#@+ @ignore */ +require_once 'Zend/Media/Iso14496/FullBox.php'; +/**#@-*/ + +/** + * A box that contains data for iTunes/iPod specific boxes. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @since iTunes/iPod specific + */ +final class Zend_Media_Iso14496_Box_Data extends Zend_Media_Iso14496_FullBox +{ + /** @var mixed */ + private $_value; + + /** A flag to indicate that the data is an unsigned 8-bit integer. */ + const INTEGER = 0x0; + + /** + * A flag to indicate that the data is an unsigned 8-bit integer. Different + * value used in old versions of iTunes. + */ + const INTEGER_OLD_STYLE = 0x15; + + /** A flag to indicate that the data is a string. */ + const STRING = 0x1; + + /** A flag to indicate that the data is the contents of an JPEG image. */ + const JPEG = 0xd; + + /** A flag to indicate that the data is the contents of a PNG image. */ + const PNG = 0xe; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_reader->skip(4); + $data = $this->_reader->read + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + switch ($this->getFlags()) { + case self::INTEGER: + // break intentionally omitted + case self::INTEGER_OLD_STYLE: + for ($i = 0; $i < strlen($data); $i++) { + $this->_value .= ord($data[$i]); + } + break; + case self::STRING: + // break intentionally omitted + default: + $this->_value = $data; + break; + } + } + + /** + * Returns the value this box contains. + * + * @return mixed + */ + public function getValue() + { + return $this->_value; + } + + /** + * Sets the value this box contains. + * + * @return mixed + */ + public function setValue($value, $type = null) + { + $this->_value = (string)$value; + if ($type === null && is_string($value)) { + $this->_flags = self::STRING; + } + if ($type === null && is_int($value)) { + $this->_flags = self::INTEGER; + } + if ($type !== null) { + $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))); + } + require_once 'Zend/Media/Iso14496/Exception.php'; + throw new Zend_Media_Iso14496_Exception('Unknown box/field: ' . $name); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + strlen($this->_value); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write("\0\0\0\0"); + switch ($this->getFlags()) { + case self::INTEGER: + // break intentionally omitted + case self::INTEGER_OLD_STYLE: + for ($i = 0; $i < strlen($this->_value); $i++) { + $writer->writeInt8($this->_value[$i]); + } + break; + case self::STRING: + // break intentionally omitted + default: + $writer->write($this->_value); + break; + } + } +} diff --git a/src/ISO14496/Box/IMIF.php b/src/Zend/Media/Iso14496/Box/Imif.php similarity index 52% rename from src/ISO14496/Box/IMIF.php rename to src/Zend/Media/Iso14496/Box/Imif.php index a8fcf8f..8b68193 100644 --- a/src/ISO14496/Box/IMIF.php +++ b/src/Zend/Media/Iso14496/Box/Imif.php @@ -1,22 +1,18 @@ - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ */ -final class ISO14496_Box_IMIF extends ISO14496_Box +final class Zend_Media_Iso14496_Box_Imif extends Zend_Media_Iso14496_Box { - /** - * 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 = null, &$options = array()) - { - parent::__construct($reader, $options); - $this->setContainer(true); - - if ($reader === null) - return; - - $this->constructBoxes(); - } + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } } diff --git a/src/Zend/Media/Iso14496/Box/Infe.php b/src/Zend/Media/Iso14496/Box/Infe.php new file mode 100644 index 0000000..6ad30f3 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Infe.php @@ -0,0 +1,233 @@ +Item Information Entry Box contains the entry information. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Infe extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_itemId; + + /** @var integer */ + private $_itemProtectionIndex; + + /** @var string */ + private $_itemName; + + /** @var string */ + private $_contentType; + + /** @var string */ + private $_contentEncoding; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + 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->getOffset() + $this->getSize() - + $this->_reader->getOffset())); + } + + /** + * Returns the item identifier. The value is either 0 for the primary + * resource (e.g. the XML contained in an + * {@link Zend_Media_Iso14496_Box_Xml XML Box}) or the ID of the item for + * which the following information is defined. + * + * @return integer + */ + public function getItemId() + { + return $this->_itemId; + } + + /** + * Sets the item identifier. The value must be either 0 for the primary + * resource (e.g. the XML contained in an + * {@link Zend_Media_Iso14496_Box_Xml XML Box}) or the ID of the item for + * which the following information is defined. + * + * @param integer $itemId The item identifier. + */ + public function setItemId($itemId) + { + $this->_itemId = $itemId; + } + + /** + * Returns the item protection index. The value is either 0 for an + * unprotected item, or the one-based index into the + * {@link Zend_Media_Iso14496_Box_Ipro Item Protection Box} defining the + * protection applied to this item (the first box in the item protection box + * has the index 1). + * + * @return integer + */ + public function getItemProtectionIndex() + { + return $this->_itemProtectionIndex; + } + + /** + * Sets the item protection index. The value must be either 0 for an + * unprotected item, or the one-based index into the + * {@link Zend_Media_Iso14496_Box_Ipro Item Protection Box} defining the + * protection applied to this item (the first box in the item protection box + * has the index 1). + * + * @param integer $itemProtectionIndex The index. + */ + public function setItemProtectionIndex($itemProtectionIndex) + { + $this->_itemProtectionIndex = $itemProtectionIndex; + } + + /** + * Returns the symbolic name of the item. + * + * @return string + */ + public function getItemName() + { + return $this->_itemName; + } + + /** + * Sets the symbolic name of the item. + * + * @param string $itemName The item name. + */ + public function setItemName($itemName) + { + $this->_itemName = $itemName; + } + + /** + * Returns the MIME type for the item. + * + * @return string + */ + public function getContentType() + { + return $this->_contentType; + } + + /** + * Sets the MIME type for the item. + * + * @param string $contentType The content type. + */ + public function setContentType($contentType) + { + $this->_contentType = $contentType; + } + + /** + * Returns the optional content encoding type as defined for + * Content-Encoding for HTTP /1.1. Some possible values are gzip, + * compress and deflate. An empty string indicates no content + * encoding. + * + * @return string + */ + public function getContentEncoding() + { + return $this->_contentEncoding; + } + + /** + * Sets the optional content encoding type as defined for + * Content-Encoding for HTTP /1.1. Some possible values are gzip, + * compress and deflate. An empty string indicates no content + * encoding. + * + * @param string $contentEncoding The content encoding. + */ + public function setContentEncoding($contentEncoding) + { + $this->_contentEncoding = $contentEncoding; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 7 + strlen($this->_itemName) + + strlen($this->_contentType) + strlen($this->_contentEncoding); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE($this->_itemId) + ->writeUInt16BE($this->_itemProtectionIndex) + ->writeString8($this->_itemName, 1) + ->writeString8($this->_contentType, 1) + ->writeString8($this->_contentEncoding, 1); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ipro.php b/src/Zend/Media/Iso14496/Box/Ipro.php new file mode 100644 index 0000000..8e30cb5 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ipro.php @@ -0,0 +1,95 @@ +Item Protection Box provides an array of item protection + * information, for use by the + * {@link Zend_Media_Iso14496_Box_Iinf Item Information Box}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Ipro extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->_reader->skip(2); + $this->constructBoxes(); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE($this->getBoxCount()); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mdhd.php b/src/Zend/Media/Iso14496/Box/Mdhd.php new file mode 100644 index 0000000..b2bb219 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mdhd.php @@ -0,0 +1,243 @@ +Media Header Box declares overall information that is + * media-independent, and relevant to characteristics of the media in a track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mdhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_creationTime; + + /** @var integer */ + private $_modificationTime; + + /** @var integer */ + private $_timescale; + + /** @var integer */ + private $_duration; + + /** @var string */ + private $_language = 'und'; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->getVersion() == 1) { + $this->_creationTime = $this->_reader->readInt64BE(); + $this->_modificationTime = $this->_reader->readInt64BE(); + $this->_timescale = $this->_reader->readUInt32BE(); + $this->_duration = $this->_reader->readInt64BE(); + } else { + $this->_creationTime = $this->_reader->readUInt32BE(); + $this->_modificationTime = $this->_reader->readUInt32BE(); + $this->_timescale = $this->_reader->readUInt32BE(); + $this->_duration = $this->_reader->readUInt32BE(); + } + $this->_language = chr + (((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) . + chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60); + } + + /** + * Returns the creation time of the media in this track, in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getCreationTime() + { + return $this->_creationTime; + } + + /** + * Sets the creation time of the media in this track, in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @param integer $creationTime The creation time. + */ + public function setCreationTime($creationTime) + { + $this->_creationTime = $creationTime; + } + + /** + * Returns the most recent time the media in this track was modified in + * seconds since midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getModificationTime() + { + return $this->_modificationTime; + } + + /** + * Sets the most recent time the media in this track was modified in + * seconds since midnight, Jan. 1, 1904, in UTC time. + * + * @param integer $modificationTime The modification time. + */ + public function setModificationTime($modificationTime) + { + $this->_modificationTime = $modificationTime; + } + + /** + * Returns the time-scale for this media. This is the number of time units + * that pass in one second. For example, a time coordinate system that + * measures time in sixtieths of a second has a time scale of 60. + * + * @return integer + */ + public function getTimescale() + { + return $this->_timescale; + } + + /** + * Sets the time-scale for this media. This is the number of time units + * that pass in one second. For example, a time coordinate system that + * measures time in sixtieths of a second has a time scale of 60. + * + * @param integer $timescale The time-scale. + */ + public function setTimescale($timescale) + { + $this->_timescale = $timescale; + } + + /** + * Returns the duration of this media (in the scale of the timescale). + * + * @return integer + */ + public function getDuration() + { + return $this->_duration; + } + + /** + * Sets the duration of this media (in the scale of the timescale). + * + * @param integer $duration The duration. + */ + public function setDuration($duration) + { + $this->_duration = $duration; + } + + /** + * Returns the three byte language code to describe the language of this + * media, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @return string + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Sets the three byte language code to describe the language of this + * media, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @param string $language The language code. + */ + public function setLanguage($language) + { + $this->_language = $language; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + ($this->getVersion() == 1 ? 28 : 16) + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_creationTime) + ->writeInt64BE($this->_modificationTime) + ->writeUInt32BE($this->_timescale) + ->writeInt64BE($this->_duration); + } else { + $writer->writeUInt32BE($this->_creationTime) + ->writeUInt32BE($this->_modificationTime) + ->writeUInt32BE($this->_timescale) + ->writeUInt32BE($this->_duration); + } + $writer->writeUInt16BE((ord($this->_language[0]) - 0x60) << 10 | + (ord($this->_language[1])- 0x60) << 5 | + (ord($this->_language[2])- 0x60)) + ->write(str_pad('', 2, "\0")); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mdia.php b/src/Zend/Media/Iso14496/Box/Mdia.php new file mode 100644 index 0000000..d5320ab --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mdia.php @@ -0,0 +1,71 @@ +Media Box contains all the objects that declare information about + * the media data within a track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mdia extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mehd.php b/src/Zend/Media/Iso14496/Box/Mehd.php new file mode 100644 index 0000000..21f6409 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mehd.php @@ -0,0 +1,128 @@ +Movie Extends Header Box is optional, and provides the overall + * duration, including fragments, of a fragmented movie. If this box is not + * present, the overall duration must be computed by examining each fragment. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mehd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_fragmentDuration; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->getVersion() == 1) { + $this->_fragmentDuration = $this->_reader->readInt64BE(); + } else { + $this->_fragmentDuration = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns the length of the presentation of the whole movie including + * fragments (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of + * this field corresponds to the duration of the longest track, including + * movie fragments. + * + * @return integer + */ + public function getFragmentDuration() + { + return $this->_fragmentDuration; + } + + /** + * Sets the length of the presentation of the whole movie including + * fragments (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of + * this field must correspond to the duration of the longest track, + * including movie fragments. + * + * @param integer $fragmentDuration The fragment duration. + */ + public function setFragmentDuration($fragmentDuration) + { + $this->_fragmentDuration = $fragmentDuration; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + ($this->getVersion() == 1 ? 8 : 4); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_fragmentDuration); + } else { + $writer->writeUInt32BE($this->_fragmentDuration); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Meta.php b/src/Zend/Media/Iso14496/Box/Meta.php new file mode 100644 index 0000000..ba91025 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Meta.php @@ -0,0 +1,91 @@ +Meta Box contains descriptive or annotative metadata. The + * meta box is required to contain a + * {@link Zend_Media_Iso14496_Box_Hdlr hdlr} box indicating the structure or + * format of the meta box contents. That metadata is located either + * within a box within this box (e.g. an XML box), or is located by the item + * identified by a primary item box. + * + * All other contained boxes are specific to the format specified by the handler + * box. + * + * The other boxes defined here may be defined as optional or mandatory for a + * given format. If they are used, then they must take the form specified here. + * These optional boxes include a data-information box, which documents other + * files in which metadata values (e.g. pictures) are placed, and a item + * location box, which documents where in those files each item is located (e.g. + * in the common case of multiple pictures stored in the same file). At most one + * meta box may occur at each of the file level, movie level, or track level. + * + * If an {@link Zend_Media_Iso14496_Box_Ipro Item Protection Box} occurs, then + * some or all of the meta-data, including possibly the primary resource, may + * have been protected and be un-readable unless the protection system is taken + * into account. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Meta extends Zend_Media_Iso14496_FullBox +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mfhd.php b/src/Zend/Media/Iso14496/Box/Mfhd.php new file mode 100644 index 0000000..1ece273 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mfhd.php @@ -0,0 +1,114 @@ +Movie Fragment Header Box contains a sequence number, as a safety + * check. The sequence number usually starts at 1 and must increase for each + * movie fragment in the file, in the order in which they occur. This allows + * readers to verify integrity of the sequence; it is an error to construct a + * file where the fragments are out of sequence. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mfhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_sequenceNumber; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_sequenceNumber = $this->_reader->readUInt32BE(); + } + + /** + * Returns the ordinal number of this fragment, in increasing order. + * + * @return integer + */ + public function getSequenceNumber() + { + return $this->_sequenceNumber; + } + + /** + * Sets the ordinal number of this fragment, in increasing order. + * + * @param integer $sequenceNumber The sequence number. + */ + public function setSequenceNumber($sequenceNumber) + { + $this->_sequenceNumber = $sequenceNumber; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_sequenceNumber); + } +} diff --git a/src/ISO14496/Box/MFRA.php b/src/Zend/Media/Iso14496/Box/Mfra.php similarity index 52% rename from src/ISO14496/Box/MFRA.php rename to src/Zend/Media/Iso14496/Box/Mfra.php index 54eb649..518753a 100644 --- a/src/ISO14496/Box/MFRA.php +++ b/src/Zend/Media/Iso14496/Box/Mfra.php @@ -1,22 +1,18 @@ - * @copyright Copyright (c) 2008 The PHP Reader Project Workgroup - * @license http://code.google.com/p/php-reader/wiki/License New BSD License - * @version $Rev$ + * + + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ */ -final class ISO14496_Box_MFRA extends ISO14496_Box +final class Zend_Media_Iso14496_Box_Mfra extends Zend_Media_Iso14496_Box { - /** - * 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 = null, &$options = array()) - { - parent::__construct($reader, $options); - $this->setContainer(true); - - if ($reader === null) - return; - - $this->constructBoxes(); - } + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } } diff --git a/src/Zend/Media/Iso14496/Box/Mfro.php b/src/Zend/Media/Iso14496/Box/Mfro.php new file mode 100644 index 0000000..f736c90 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mfro.php @@ -0,0 +1,123 @@ +Movie Fragment Random Access Offset Box provides a copy of the + * length field from the enclosing {@link Zend_Media_Iso14496_Box_MFRA Movie Fragment + * Random Access Box}. It is placed last within that box, so that the size field + * is also last in the enclosing Movie Fragment Random Access Box. When the + * Movie Fragment Random Access Box is also last in the file this permits its + * easy location. The size field here must be correct. However, neither the + * presence of the Movie Fragment Random Access Box, nor its placement last in + * the file, are assured. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mfro extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_parentSize; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_parentSize = $this->_reader->readUInt32BE(); + } + + /** + * Returns the number of bytes of the enclosing + * {@link Zend_Media_Iso14496_Box_Mfra} box. This field is placed at the + * last of the enclosing box to assist readers scanning from the end of the + * file in finding the mfra box. + * + * @return integer + */ + public function getParentSize() + { + return $this->_parentSize; + } + + /** + * Sets the number of bytes of the enclosing + * {@link Zend_Media_Iso14496_Box_Mfra} box. This field is placed at the + * last of the enclosing box to assist readers scanning from the end of the + * file in finding the mfra box. + * + * @param integer $parentSize The number of bytes. + */ + public function setParentSize($parentSize) + { + $this->_parentSize = $parentSize; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_parentSize); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Minf.php b/src/Zend/Media/Iso14496/Box/Minf.php new file mode 100644 index 0000000..d8a36e9 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Minf.php @@ -0,0 +1,71 @@ +Media Information Box contains all the objects that declare + * characteristic information of the media in the track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Minf extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Moof.php b/src/Zend/Media/Iso14496/Box/Moof.php new file mode 100644 index 0000000..0417e6b --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Moof.php @@ -0,0 +1,81 @@ +Movie Fragment Box extend the presentation in time. They provide + * the information that would previously have been in the + * {@link Zend_Media_Iso14496_Box_Moov Movie Box}. The actual samples are in + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Boxes}, as usual, if they are + * in the same file. The data reference index is in the sample description, so + * it is possible to build incremental presentations where the media data is in + * files other than the file containing the Movie Box. + * + * The Movie Fragment Box is a top-level box, (i.e. a peer to the Movie Box and + * Media Data boxes). It contains a + * {@link Zend_Media_Iso14496_Box_Mfhd Movie Fragment Header Box}, and then one + * or more {@link Zend_Media_Iso14496_Box_Traf Track Fragment Boxes}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Moof extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Moov.php b/src/Zend/Media/Iso14496/Box/Moov.php new file mode 100644 index 0000000..21e9bcc --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Moov.php @@ -0,0 +1,72 @@ +Movie Box + * which occurs at the top-level of a file. Normally this box is close to the + * beginning or end of the file, though this is not required. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Moov extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mvex.php b/src/Zend/Media/Iso14496/Box/Mvex.php new file mode 100644 index 0000000..47bdd36 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mvex.php @@ -0,0 +1,74 @@ +Movie Extends Box warns readers that there might be + * {@link Zend_Media_Iso14496_Box_Mfra Movie Fragment Boxes} in this file. To + * know of all samples in the tracks, these Movie Fragment Boxes must be found + * and scanned in order, and their information logically added to that found in + * the {@link Zend_Media_Iso14496_Box_Moov Movie Box}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mvex extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Mvhd.php b/src/Zend/Media/Iso14496/Box/Mvhd.php new file mode 100644 index 0000000..e197692 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Mvhd.php @@ -0,0 +1,343 @@ +Movie Header Box defines overall information which is + * media-independent, and relevant to the entire presentation considered as a + * whole. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Mvhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_creationTime; + + /** @var integer */ + private $_modificationTime; + + /** @var integer */ + private $_timescale; + + /** @var integer */ + private $_duration; + + /** @var integer */ + private $_rate = 1.0; + + /** @var integer */ + private $_volume = 1.0; + + /** @var Array */ + private $_matrix = array + (0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000); + + /** @var integer */ + private $_nextTrackId; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->getVersion() == 1) { + $this->_creationTime = $this->_reader->readInt64BE(); + $this->_modificationTime = $this->_reader->readInt64BE(); + $this->_timescale = $this->_reader->readUInt32BE(); + $this->_duration = $this->_reader->readInt64BE(); + } else { + $this->_creationTime = $this->_reader->readUInt32BE(); + $this->_modificationTime = $this->_reader->readUInt32BE(); + $this->_timescale = $this->_reader->readUInt32BE(); + $this->_duration = $this->_reader->readUInt32BE(); + } + $this->_rate = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + $this->_volume = + ((($tmp = $this->_reader->readUInt16BE()) >> 8) & 0xff) + + (float)("0." . ((string)($tmp & 0xff))); + $this->_reader->skip(10); + for ($i = 0; $i < 9; $i++) { + $this->_matrix[$i] = $this->_reader->readUInt32BE(); + } + $this->_reader->skip(24); + $this->_nextTrackId = $this->_reader->readUInt32BE(); + } + + /** + * Returns the creation time of the presentation. The value is in seconds + * since midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getCreationTime() + { + return $this->_creationTime; + } + + /** + * Sets the creation time of the presentation in seconds since midnight, + * Jan. 1, 1904, in UTC time. + * + * @param integer $creationTime The creation time. + */ + public function setCreationTime($creationTime) + { + $this->_creationTime = $creationTime; + } + + /** + * Returns the most recent time the presentation was modified. The value is + * in seconds since midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getModificationTime() + { + return $this->_modificationTime; + } + + /** + * Sets the most recent time the presentation was modified in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @param integer $modificationTime The most recent time the presentation + * was modified. + */ + public function setModificationTime($modificationTime) + { + $this->_modificationTime = $modificationTime; + } + + /** + * Returns the time-scale for the entire presentation. This is the number of + * time units that pass in one second. For example, a time coordinate system + * that measures time in sixtieths of a second has a time scale of 60. + * + * @return integer + */ + public function getTimescale() + { + return $this->_timescale; + } + + /** + * Sets the time-scale for the entire presentation. This is the number of + * time units that pass in one second. For example, a time coordinate system + * that measures time in sixtieths of a second has a time scale of 60. + * + * @param integer $timescale The time-scale for the entire presentation. + */ + public function setTimescale($timescale) + { + $this->_timescale = $timescale; + } + + /** + * Returns the length of the presentation in the indicated timescale. This + * property is derived from the presentation's tracks: the value of this + * field corresponds to the duration of the longest track in the + * presentation. + * + * @return integer + */ + public function getDuration() + { + return $this->_duration; + } + + /** + * Sets the length of the presentation in the indicated timescale. This + * property must be derived from the presentation's tracks: the value of + * this field must correspond to the duration of the longest track in the + * presentation. + * + * @param integer $duration The length of the presentation. + */ + public function setDuration($duration) + { + $this->_duration = $duration; + } + + /** + * Returns the preferred rate to play the presentation. 1.0 is normal + * forward playback. + * + * @return integer + */ + public function getRate() + { + return $this->_rate; + } + + /** + * Sets the preferred rate to play the presentation. 1.0 is normal + * forward playback. + * + * @param integer $rate The preferred play rate. + */ + public function setRate($rate) + { + $this->_rate = $rate; + } + + /** + * Returns the preferred playback volume. 1.0 is full volume. + * + * @return integer + */ + public function getVolume() + { + return $this->_volume; + } + + /** + * Sets the preferred playback volume. 1.0 is full volume. + * + * @param integer $volume The playback volume. + */ + public function setVolume($volume) + { + $this->_volume = $volume; + } + + /** + * Returns the transformation matrix for the video; (u,v,w) are restricted + * here to (0,0,1), hex values (0,0,0x40000000). + * + * @return Array + */ + public function getMatrix() + { + return $this->_matrix; + } + + /** + * Sets the transformation matrix for the video; (u,v,w) are restricted + * here to (0,0,1), hex values (0,0,0x40000000). + * + * @param Array $matrix The transformation matrix array of 9 values + */ + public function setMatrix($matrix) + { + $this->_matrix = $matrix; + } + + /** + * Returns a value to use for the track ID of the next track to be added to + * this presentation. Zero is not a valid track ID value. The value is + * larger than the largest track-ID in use. If this value is equal to or + * larger than 32-bit maxint, and a new media track is to be added, then a + * search must be made in the file for a unused track identifier. + * + * @return integer + */ + public function getNextTrackId() + { + return $this->_nextTrackId; + } + + /** + * Sets a value to use for the track ID of the next track to be added to + * this presentation. Zero is not a valid track ID value. The value must be + * larger than the largest track-ID in use. + * + * @param integer $nextTrackId The next track ID. + */ + public function setNextTrackId($nextTrackId) + { + $this->_nextTrackId = $nextTrackId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + ($this->getVersion() == 1 ? 28 : 16) + 80; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_creationTime) + ->writeInt64BE($this->_modificationTime) + ->writeUInt32BE($this->_timescale) + ->writeInt64BE($this->_duration); + } else { + $writer->writeUInt32BE($this->_creationTime) + ->writeUInt32BE($this->_modificationTime) + ->writeUInt32BE($this->_timescale) + ->writeUInt32BE($this->_duration); + } + + @list(, $rateDecimals) = explode('.', (float)$this->_rate); + @list(, $volumeDecimals) = explode('.', (float)$this->_volume); + $writer->writeUInt32BE(floor($this->_rate) << 16 | $rateDecimals) + ->writeUInt16BE(floor($this->_volume) << 8 | $volumeDecimals) + ->write(str_pad('', 10, "\0")); + for ($i = 0; $i < 9; $i++) { + $writer->writeUInt32BE($this->_matrix[$i]); + } + $writer->write(str_pad('', 24, "\0")) + ->writeUInt32BE($this->_nextTrackId); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Pdin.php b/src/Zend/Media/Iso14496/Box/Pdin.php new file mode 100644 index 0000000..ea1c9f7 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Pdin.php @@ -0,0 +1,143 @@ +Progressive Download Information Box aids the progressive download + * of an ISO file. The box contains pairs of numbers (to the end of the box) + * specifying combinations of effective file download bitrate in units of + * bytes/sec and a suggested initial playback delay in units of milliseconds. + * + * A receiving party can estimate the download rate it is experiencing, and from + * that obtain an upper estimate for a suitable initial delay by linear + * interpolation between pairs, or by extrapolation from the first or last + * entry. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Pdin extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_progressiveDownloadInfo = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset() < + $this->getOffset() + $this->getSize()) { + $this->_progressiveDownloadInfo[] = array + ('rate' => $this->_reader->readUInt32BE(), + 'initialDelay' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns the progressive download information array. The array consists of + * items having two keys. + * + * o rate -- the download rate expressed in bytes/second + * o initialDelay -- the suggested delay to use when playing the file, + * such that if download continues at the given rate, all data within + * the file will arrive in time for its use and playback should not need + * to stall. + * + * @return Array + */ + public function getProgressiveDownloadInfo() + { + return $this->_progressiveDownloadInfo; + } + + /** + * Sets the progressive download information array. The array must consist + * of items having two keys. + * + * o rate -- the download rate expressed in bytes/second + * o initialDelay -- the suggested delay to use when playing the file, + * such that if download continues at the given rate, all data within + * the file will arrive in time for its use and playback should not need + * to stall. + * + * @param Array $progressiveDownloadInfo The array of values. + */ + public function setProgressiveDownloadInfo($progressiveDownloadInfo) + { + $this->_progressiveDownloadInfo = $progressiveDownloadInfo; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + count($this->_progressiveDownloadInfo) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_timeToSampleTable); $i++) { + $writer->writeUInt32BE + ($this->_progressiveDownloadInfo[$i]['rate']) + ->writeUInt32BE + ($this->_progressiveDownloadInfo[$i]['initialDelay']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Pitm.php b/src/Zend/Media/Iso14496/Box/Pitm.php new file mode 100644 index 0000000..9f8e51c --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Pitm.php @@ -0,0 +1,116 @@ +Primary Item + * Box must occur, or there must be a box within the meta-box (e.g. an + * {@link Zend_Media_Iso14496_Box_Xml XML Box}) containing the primary + * information in the format required by the identified handler. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Pitm extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_itemId; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_itemId = $this->_reader->readUInt16BE(); + } + + /** + * Returns the identifier of the primary item. + * + * @return integer + */ + public function getItemId() + { + return $this->_itemId; + } + + /** + * Sets the identifier of the primary item. + * + * @param integer $itemId The item identification. + */ + public function setItemId($itemId) + { + $this->_itemId = $itemId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE($this->_itemId); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Sbgp.php b/src/Zend/Media/Iso14496/Box/Sbgp.php new file mode 100644 index 0000000..3ca1f82 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Sbgp.php @@ -0,0 +1,197 @@ +Sample To Group Box table can be used to find the group that a + * sample belongs to and the associated description of that sample group. The + * table is compactly coded with each entry giving the index of the first sample + * of a run of samples with the same sample group descriptor. The sample group + * description ID is an index that refers to a + * {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box}, which + * contains entries describing the characteristics of each sample group. + * + * There may be multiple instances of this box if there is more than one sample + * grouping for the samples in a track. Each instance of the Sample To Group Box + * has a type code that distinguishes different sample groupings. Within a + * track, there shall be at most one instance of this box with a particular + * grouping type. The associated Sample Group Description shall indicate the + * same value for the grouping type. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Sbgp extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_groupingType; + + /** @var Array */ + private $_sampleToGroupTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $groupingType = $this->_reader->readUInt32BE(); + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_sampleToGroupTable[$i] = array + ('sampleCount' => $this->_reader->readUInt32BE(), + 'groupDescriptionIndex' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns the grouping type that identifies the type (i.e. criterion used + * to form the sample groups) of the sample grouping and links it to its + * sample group description table with the same value for grouping type. At + * most one occurrence of this box with the same value for groupingType + * shall exist for a track. + * + * @return integer + */ + public function getGroupingType() + { + return $this->_groupingType; + } + + /** + * Sets the grouping type that identifies the type (i.e. criterion used + * to form the sample groups) of the sample grouping and links it to its + * sample group description table with the same value for grouping type. At + * most one occurrence of this box with the same value for groupingType + * shall exist for a track. + * + * @param integer $groupingType The grouping type. + */ + public function setGroupingType($groupingType) + { + $this->_groupingType = $groupingType; + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o sampleCount -- an integer that gives the number of consecutive + * samples with the same sample group descriptor. If the sum of the + * sample count in this box is less than the total sample count, then + * the reader should effectively extend it with an entry that associates + * the remaining samples with no group. It is an error for the total in + * this box to be greater than the sample_count documented elsewhere, + * and the reader behavior would then be undefined. + * o groupDescriptionIndex -- an integer that gives the index of the + * sample group entry which describes the samples in this group. The + * index ranges from 1 to the number of sample group entries in the + * {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box}, + * or takes the value 0 to indicate that this sample is a member of no + * group of this type. + * + * @return Array + */ + public function getSampleToGroupTable() + { + return $this->_sampleToGroupTable; + } + + /** + * Sets the array of values. Each entry must be an array containing the + * following keys. + * o sampleCount -- an integer that gives the number of consecutive + * samples with the same sample group descriptor. If the sum of the + * sample count in this box is less than the total sample count, then + * the reader should effectively extend it with an entry that associates + * the remaining samples with no group. It is an error for the total in + * this box to be greater than the sample_count documented elsewhere, + * and the reader behavior would then be undefined. + * o groupDescriptionIndex -- an integer that gives the index of the + * sample group entry which describes the samples in this group. The + * index ranges from 1 to the number of sample group entries in the + * {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box}, + * or takes the value 0 to indicate that this sample is a member of no + * group of this type. + * + * @param Array $sampleToGroupTable The array of entries + */ + public function setSampleToGroupTable($sampleToGroupTable) + { + $this->_sampleToGroupTable = $sampleToGroupTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8 + + count($this->_sampleToGroupTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_groupingType); + $writer->writeUInt32BE($entryCount = count($this->_sampleToGroupTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE + ($this->_sampleToGroupTable[$i]['sampleCount']) + ->writeUInt32BE + ($this->_sampleToGroupTable[$i] + ['groupDescriptionIndex']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Schi.php b/src/Zend/Media/Iso14496/Box/Schi.php new file mode 100644 index 0000000..434aeb6 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Schi.php @@ -0,0 +1,74 @@ +Scheme Information Box is a container Box that is only interpreted + * by the scheme being used. Any information the encryption system needs is + * stored here. The content of this box is a series of boxes whose type and + * format are defined by the scheme declared in the + * {@link Zend_Media_Iso14496_Box_Schm Scheme Type Box}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Schi extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Schm.php b/src/Zend/Media/Iso14496/Box/Schm.php new file mode 100644 index 0000000..9dad95d --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Schm.php @@ -0,0 +1,177 @@ +Scheme Type Box identifies the protection scheme. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Schm extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_schemeType; + + /** @var integer */ + private $_schemeVersion; + + /** @var string */ + private $_schemeUri; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + 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->getOffset() + $this->getSize() - + $this->_reader->getOffset())); + } + } + + /** + * Returns the code defining the protection scheme. + * + * @return string + */ + public function getSchemeType() + { + return $this->_schemeType; + } + + /** + * Sets the code defining the protection scheme. + * + * @param string $schemeType The scheme type. + */ + public function setSchemeType($schemeType) + { + $this->_schemeType = $schemeType; + } + + /** + * Returns the version of the scheme used to create the content. + * + * @return integer + */ + public function getSchemeVersion() + { + return $this->_schemeVersion; + } + + /** + * Sets the version of the scheme used to create the content. + * + * @param integer $schemeVersion The scheme version. + */ + public function setSchemeVersion($schemeVersion) + { + $this->_schemeVersion = $schemeVersion; + } + + /** + * Returns the optional scheme address to allow for the option of directing + * the user to a web-page if they do not have the scheme installed on their + * system. It is an absolute URI. + * + * @return string + */ + public function getSchemeUri() + { + return $this->_schemeUri; + } + + /** + * Sets the optional scheme address to allow for the option of directing + * the user to a web-page if they do not have the scheme installed on their + * system. It is an absolute URI. + * + * @param string $schemeUri The scheme URI. + */ + public function setSchemeUri($schemeUri) + { + $this->_schemeUri = $schemeUri; + if ($schemeUri === null) { + $this->setFlags(0); + } else { + $this->setFlags(1); + } + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8 + + ($this->hasFlag(1) ? strlen($this->_schemeUri) + 1 : 0); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write($this->_schemeType); + $writer->writeUInt32BE($this->_schemeVersion); + if ($this->hasFlag(1)) { + $writer->writeString8($this->_schemeUri, 1); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Sdtp.php b/src/Zend/Media/Iso14496/Box/Sdtp.php new file mode 100644 index 0000000..45979f8 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Sdtp.php @@ -0,0 +1,187 @@ +Independent and Disposable Samples Box optional table answers + * three questions about sample dependency: + * 1) does this sample depend on others (is it an I-picture)? + * 2) do no other samples depend on this one? + * 3) does this sample contain multiple (redundant) encodings of the data at + * this time-instant (possibly with different dependencies)? + * + * In the absence of this table: + * 1) the sync sample table answers the first question; in most video codecs, + * I-pictures are also sync points, + * 2) the dependency of other samples on this one is unknown. + * 3) the existence of redundant coding is unknown. + * + * When performing trick modes, such as fast-forward, it is possible to use the + * first piece of information to locate independently decodable samples. + * Similarly, when performing random access, it may be necessary to locate the + * previous sync point or random access recovery point, and roll-forward from + * the sync point or the pre-roll starting point of the random access recovery + * point to the desired point. While rolling forward, samples on which no others + * depend need not be retrieved or decoded. + * + + * The value of sampleIsDependedOn is independent of the existence of redundant + * codings. However, a redundant coding may have different dependencies from the + * primary coding; if redundant codings are available, the value of + * sampleDependsOn documents only the primary coding. + * + * A sample dependency Box may also occur in the + * {@link Zend_Media_Iso14496_Box_Traf Track Fragment Box}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Sdtp extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_sampleDependencyTypeTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $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 = ord($data[$i - 1])) >> 4) & 0x3, + 'sampleIsDependedOn' => ($tmp >> 2) & 0x3, + 'sampleHasRedundancy' => $tmp & 0x3); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o sampleDependsOn -- takes one of the following four values: + * 0: the dependency of this sample is unknown; + * 1: this sample does depend on others (not an I picture); + * 2: this sample does not depend on others (I picture); + * 3: reserved + * o sampleIsDependedOn -- takes one of the following four values: + * 0: the dependency of other samples on this sample is unknown; + * 1: other samples depend on this one (not disposable); + * 2: no other sample depends on this one (disposable); + * 3: reserved + * o sampleHasRedundancy -- takes one of the following four values: + * 0: it is unknown whether there is redundant coding in this sample; + * 1: there is redundant coding in this sample; + * 2: there is no redundant coding in this sample; + * 3: reserved + * + * @return Array + */ + public function getSampleDependencyTypeTable() + { + return $this->_sampleDependencyTypeTable; + } + + /** + * Sets the array of values. Each entry must be an array containing the + * following keys. + * o sampleDependsOn -- takes one of the following four values: + * 0: the dependency of this sample is unknown; + * 1: this sample does depend on others (not an I picture); + * 2: this sample does not depend on others (I picture); + * 3: reserved + * o sampleIsDependedOn -- takes one of the following four values: + * 0: the dependency of other samples on this sample is unknown; + * 1: other samples depend on this one (not disposable); + * 2: no other sample depends on this one (disposable); + * 3: reserved + * o sampleHasRedundancy -- takes one of the following four values: + * 0: it is unknown whether there is redundant coding in this sample; + * 1: there is redundant coding in this sample; + * 2: there is no redundant coding in this sample; + * 3: reserved + * + * @param Array $sampleDependencyTypeTable The array of values + */ + public function setSampleDependencyTypeTable($sampleDependencyTypeTable) + { + $this->_sampleDependencyTypeTable = $sampleDependencyTypeTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_sampleDependencyTypeTable); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 1; $i <= count($this->_sampleDependencyTypeTable); $i++) { + $writer->write(chr( + (($this->_sampleDependencyTypeTable[$i] + ['sampleDependsOn'] & 0x3) << 4) | + (($this->_sampleDependencyTypeTable[$i] + ['sampleIsDependedOn'] & 0x3) << 2) | + (($this->_sampleDependencyTypeTable[$i] + ['sampleHasRedundancy'] & 0x3)))); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Sinf.php b/src/Zend/Media/Iso14496/Box/Sinf.php new file mode 100644 index 0000000..7cf8ce0 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Sinf.php @@ -0,0 +1,87 @@ +Protection Scheme Information Box contains all the information + * required both to understand the encryption transform applied and its + * parameters, and also to find other information such as the kind and location + * of the key management system. It also documents the original (unencrypted) + * format of the media. The Protection Scheme Info Box is a container Box. It is + * mandatory in a sample entry that uses a code indicating a protected stream. + * + * When used in a protected sample entry, this box must contain the original + * format box to document the original format. At least one of the following + * signaling methods must be used to identify the protection applied: + * + * a) MPEG-4 systems with IPMP: no other boxes, when IPMP descriptors in MPEG-4 + * systems streams are used; + * b) Standalone IPMP: an {@link Zend_Media_Iso14496_Box_Imif IPMP Info Box}, + * when IPMP descriptors outside MPEG-4 systems are used; + * c) Scheme signaling: a {@link Zend_Media_Iso14496_Box_Schm Scheme Type Box} + * and {@link Zend_Media_Iso14496_Box_Schi Scheme Information Box}, when + * these are used (either both must occur, or neither). + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Sinf extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Skip.php b/src/Zend/Media/Iso14496/Box/Skip.php new file mode 100644 index 0000000..f44ed12 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Skip.php @@ -0,0 +1,73 @@ +Free Space Box are irrelevant and may be ignored, or + * the object deleted, without affecting the presentation. (Care should be + * exercised when deleting the object, as this may invalidate the offsets used + * in the sample table, unless this object is after all the media data). + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Skip extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Smhd.php b/src/Zend/Media/Iso14496/Box/Smhd.php new file mode 100644 index 0000000..01688a5 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Smhd.php @@ -0,0 +1,123 @@ +Sound Media Header Box contains general presentation information, + * independent of the coding, for audio media. This header is used for all + * tracks containing audio. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Smhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_balance = 0; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_balance = + ((($tmp = $this->_reader->readUInt16BE()) >> 8) & 0xff) + + (float)("0." . ((string)($tmp & 0xff))); + $this->_reader->skip(2); + } + + /** + * Returns the number that places mono audio tracks in a stereo space; 0 is + * center (the normal value); full left is -1.0 and full right is 1.0. + * + * @return integer + */ + public function getBalance() + { + return $this->_balance; + } + + /** + * Sets the number that places mono audio tracks in a stereo space; 0 is + * center (the normal value); full left is -1.0 and full right is 1.0. + * + * @param integer $balance The balance. + */ + public function setBalance($balance) + { + $this->_balance = $balance; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + @list(, $balanceDecimals) = explode('.', (float)$this->_balance); + $writer->writeInt16BE(floor($this->_balance) << 8 | $balanceDecimals) + ->writeInt16BE(0); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stbl.php b/src/Zend/Media/Iso14496/Box/Stbl.php new file mode 100644 index 0000000..e4e7ed3 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stbl.php @@ -0,0 +1,92 @@ +Sample Table Box contains all the time and data indexing of the + * media samples in a track. Using the tables here, it is possible to locate + * samples in time, determine their type (e.g. I-frame or not), and determine + * their size, container, and offset into that container. + * + * If the track that contains the Sample Table Box references no data, then the + * Sample Table Box does not need to contain any sub-boxes (this is not a very + * useful media track). + * + * If the track that the Sample Table Box is contained in does reference data, + * then the following sub-boxes are required: + * {@link Zend_Media_Iso14496_Box_Stsd Sample Description}, + * {@link Zend_Media_Iso14496_Box_Stsz Sample Size}, + * {@link Zend_Media_Iso14496_Box_Stsc Sample To Chunk}, and + * {@link Zend_Media_Iso14496_Box_Stco Chunk Offset}. Further, the + * {@link Zend_Media_Iso14496_Box_Stsd Sample Description Box} shall contain at + * least one entry. A Sample Description Box is required because it contains + * the data reference index field which indicates which + * {@link Zend_Media_Iso14496_Box_Dref Data Reference Box} to use to retrieve + * the media samples. Without the Sample Description, it is not possible to + * determine where the media samples are stored. The + * {@link Zend_Media_Iso14496_Box_Stss Sync Sample Box} is optional. If the + * Sync Sample Box is not present, all samples are sync samples. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stbl extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stco.php b/src/Zend/Media/Iso14496/Box/Stco.php new file mode 100644 index 0000000..248b331 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stco.php @@ -0,0 +1,134 @@ +Chunk Offset Box table gives the index of each chunk into the + * containing file. There are two variants, permitting the use of 32-bit or + * 64-bit offsets. The latter is useful when managing very large presentations. + * At most one of these variants will occur in any single instance of a sample + * table. + * + * Offsets are file offsets, not the offset into any box within the file (e.g. + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Box}). This permits referring + * to media data in files without any box structure. It does also mean that care + * must be taken when constructing a self-contained ISO file with its metadata + * ({@link Zend_Media_Iso14496_Box_Moov Movie Box}) at the front, as the size of + * the {@link Zend_Media_Iso14496_Box_Moov Movie Box} will affect the chunk + * offsets to the media data. + * + * This box variant contains 32-bit offsets. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stco extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_chunkOffsetTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_chunkOffsetTable[$i] = $reader->readUInt32BE(); + } + } + + /** + * Returns an array of values. Each entry has 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. + * + * @return Array + */ + 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) + { + $this->_chunkOffsetTable = $chunkOffsetTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_chunkOffsetTable) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_chunkOffsetTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE($this->_chunkOffsetTable[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stdp.php b/src/Zend/Media/Iso14496/Box/Stdp.php new file mode 100644 index 0000000..7e20ae6 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stdp.php @@ -0,0 +1,122 @@ +Degradation Priority Box contains the degradation priority of each + * sample. Specifications derived from this define the exact meaning and + * acceptable range of the priority field. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stdp extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_values = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset() < + $this->getOffset() + $this->getSize()) { + $this->_values[] = array + ('priority' => $this->_reader->readUInt16BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o priority: specifies the degradation priority for each sample segment. + * + * @return Array + */ + public function getValues() + { + return $this->_values; + } + + /** + * Sets an array of values. Each entry must have an array containing the + * following keys. + * o priority: specifies the degradation priority for each sample segment. + * + * @param Array $values The array of values. + */ + public function setValues($values) + { + $this->_values = $values; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_values) * 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_values); $i++) { + $writer->writeUInt16BE($this->_values[$i]['priority']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stsc.php b/src/Zend/Media/Iso14496/Box/Stsc.php new file mode 100644 index 0000000..5eedcf6 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stsc.php @@ -0,0 +1,161 @@ +Sample To Chunk Box table can be used to find the chunk that + * contains a sample, its position, and the associated sample description. + * + * The table is compactly coded. Each entry gives the index of the first chunk + * of a run of chunks with the same characteristics. By subtracting one entry + * here from the previous one, you can compute how many chunks are in this run. + * You can convert this to a sample count by multiplying by the appropriate + * samplesPerChunk. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stsc extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_sampleToChunkTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_sampleToChunkTable[$i] = array + ('firstChunk' => $this->_reader->readUInt32BE(), + 'samplesPerChunk' => $this->_reader->readUInt32BE(), + 'sampleDescriptionIndex' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o firstChunk -- an integer that gives the index of the first chunk in + * this run of chunks that share the same samplesPerChunk and + * sampleDescriptionIndex; the index of the first chunk in a track has + * the value 1 (the firstChunk field in the first record of this box + * has the value 1, identifying that the first sample maps to the first + * chunk). + * o samplesPerChunk is an integer that gives the number of samples in + * each of these chunks. + * o sampleDescriptionIndex is an integer that gives the index of the + * sample entry that describes the samples in this chunk. The index + * ranges from 1 to the number of sample entries in the + * {@link Zend_Media_Iso14496_Box_Stsd Sample Description Box}. + * + * @return Array + */ + public function getSampleToChunkTable() + { + return $this->_sampleToChunkTable; + } + + /** + * Sets an array of values. Each entry is an array containing the + * following keys. + * o firstChunk -- an integer that gives the index of the first chunk in + * this run of chunks that share the same samplesPerChunk and + * sampleDescriptionIndex; the index of the first chunk in a track has + * the value 1 (the firstChunk field in the first record of this box + * has the value 1, identifying that the first sample maps to the first + * chunk). + * o samplesPerChunk is an integer that gives the number of samples in + * each of these chunks. + * o sampleDescriptionIndex is an integer that gives the index of the + * sample entry that describes the samples in this chunk. The index + * ranges from 1 to the number of sample entries in the + * {@link Zend_Media_Iso14496_Box_Stsd Sample Description Box}. + * + * @param Array $sampleToChunkTable The array of values. + */ + public function setSampleToChunkTable($sampleToChunkTable) + { + $this->_sampleToChunkTable = $sampleToChunkTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + + count($this->_sampleToChunkTable) * 12; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_sampleToChunkTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE + ($this->_sampleToChunkTable[$i]['firstChunk']) + ->writeUInt32BE + ($this->_sampleToChunkTable[$i]['samplesPerChunk']) + ->writeUInt32BE + ($this->_sampleToChunkTable[$i] + ['sampleDescriptionIndex']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stsd.php b/src/Zend/Media/Iso14496/Box/Stsd.php new file mode 100644 index 0000000..10c4c57 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stsd.php @@ -0,0 +1,91 @@ +Sample Description Box table gives detailed information about the + * coding type used, and any initialization information needed for that coding. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @todo Implementation + */ +final class Zend_Media_Iso14496_Box_Stsd extends Zend_Media_Iso14496_FullBox +{ + private $_data; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_data = $reader->read($this->getSize() - 12); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + $this->getSize() - 12; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write($this->_data); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stsh.php b/src/Zend/Media/Iso14496/Box/Stsh.php new file mode 100644 index 0000000..dc781d3 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stsh.php @@ -0,0 +1,158 @@ +Shadow Sync Sample Box table provides an optional set of sync + * samples that can be used when seeking or for similar purposes. In normal + * forward play they are ignored. + * + * Each entry in the Shadow Sync Table consists of a pair of sample numbers. The + * first entry (shadowedSampleNumber) indicates the number of the sample that a + * shadow sync will be defined for. This should always be a non-sync sample + * (e.g. a frame difference). The second sample number (syncSampleNumber) + * indicates the sample number of the sync sample (i.e. key frame) that can be + * used when there is a random access at, or before, the shadowedSampleNumber. + * + * The shadow sync samples are normally placed in an area of the track that is + * not presented during normal play (edited out by means of an edit list), + * though this is not a requirement. The shadow sync table can be ignored and + * the track will play (and seek) correctly if it is ignored (though perhaps not + * optimally). + * + * The Shadow Sync Sample replaces, not augments, the sample that it shadows + * (i.e. the next sample sent is shadowedSampleNumber+1). The shadow sync sample + * is treated as if it occurred at the time of the sample it shadows, having the + * duration of the sample it shadows. + * + * Hinting and transmission might become more complex if a shadow sample is used + * also as part of normal playback, or is used more than once as a shadow. In + * this case the hint track might need separate shadow syncs, all of which can + * get their media data from the one shadow sync in the media track, to allow + * for the different time-stamps etc. needed in their headers. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stsh extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_shadowSyncSampleTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 0; $i < $entryCount; $i++) { + $this->_shadowSyncSampleTable[$i] = array + ('shadowedSampleNumber' => $this->_reader->readUInt32BE(), + 'syncSampleNumber' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o shadowedSampleNumber - gives the number of a sample for which there + * is an alternative sync sample. + * o syncSampleNumber - gives the number of the alternative sync sample. + * + * @return Array + */ + public function getShadowSyncSampleTable() + { + return $this->_shadowSyncSampleTable; + } + + /** + * Sets an array of values. Each entry must be an array containing the + * following keys. + * o shadowedSampleNumber - gives the number of a sample for which there + * is an alternative sync sample. + * o syncSampleNumber - gives the number of the alternative sync sample. + * + * @param Array $shadowSyncSampleTable The array of values. + */ + public function setShadowSyncSampleTable($shadowSyncSampleTable) + { + $this->_shadowSyncSampleTable = $shadowSyncSampleTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + + count($this->_shadowSyncSampleTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE + ($entryCount = count($this->_shadowSyncSampleTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE + ($this->_shadowSyncSampleTable[$i] + ['shadowedSampleNumber']) + ->writeUInt32BE + ($this->_shadowSyncSampleTable[$i]['syncSampleNumber']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stss.php b/src/Zend/Media/Iso14496/Box/Stss.php new file mode 100644 index 0000000..7c8e660 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stss.php @@ -0,0 +1,123 @@ +Sync Sample Box provides a compact marking of the random access + * points within the stream. The table is arranged in strictly increasing order + * of sample number. If the sync sample box is not present, every sample is a + * random access point. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stss extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_syncSampleTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_syncSampleTable[$i] = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns an array of values. Each entry has the entry number as its index + * and an integer that gives the numbers of the samples that are random + * access points in the stream as its value. + * + * @return Array + */ + public function getSyncSampleTable() + { + return $this->_syncSampleTable; + } + + /** + * Sets an array of values. Each entry has the entry number as its index + * and an integer that gives the numbers of the samples that are random + * access points in the stream as its value. + * + * @param Array $syncSampleTable The array of values. + */ + public function setSyncSampleTable($syncSampleTable) + { + $this->_syncSampleTable = $syncSampleTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_syncSampleTable) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_syncSampleTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE($this->_syncSampleTable[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stsz.php b/src/Zend/Media/Iso14496/Box/Stsz.php new file mode 100644 index 0000000..78424e4 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stsz.php @@ -0,0 +1,164 @@ +Sample Size Box contains the sample count and a table giving the + * size in bytes of each sample. This allows the media data itself to be + * unframed. The total number of samples in the media is always indicated in the + * sample count. + * + * There are two variants of the sample size box. The first variant has a fixed + * size 32-bit field for representing the sample sizes; it permits defining a + * constant size for all samples in a track. The second variant permits smaller + * size fields, to save space when the sizes are varying but small. One of these + * boxes must be present; the first version is preferred for maximum + * compatibility. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stsz extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_sampleSize; + + /** @var Array */ + private $_sampleSizeTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + 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(); + } + } + } + + /** + * Returns the default sample size. If all the samples are the same size, + * this field contains that size value. If this field is set to 0, then the + * samples have different sizes, and those sizes are stored in the sample + * size table. + * + * @return integer + */ + public function getSampleSize() + { + return $this->_sampleSize; + } + + /** + * Sets the default sample size. If all the samples are the same size, + * this field contains that size value. If this field is set to 0, then the + * samples have different sizes, and those sizes are stored in the sample + * size table. + * + * @param integer $sampleSize The default sample size. + */ + public function setSampleSize($sampleSize) + { + $this->_sampleSize = $sampleSize; + } + + /** + * Returns an array of sample sizes specifying the size of a sample, indexed + * by its number. + * + * @return Array + */ + public function getSampleSizeTable() + { + return $this->_sampleSizeTable; + } + + /** + * Sets an array of sample sizes specifying the size of a sample, indexed + * by its number. + * + * @param Array $sampleSizeTable The array of sample sizes. + */ + public function setSampleSizeTable($sampleSizeTable) + { + $this->_sampleSizeTable = $sampleSizeTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8 + + ($this->_sampleSize == 0 ? count($this->_sampleSizeTable) * 4 : 0); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_sampleSize); + $writer->writeUInt32BE($entryCount = count($this->_sampleSizeTable)); + if ($this->_sampleSize == 0) { + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE($this->_sampleSizeTable[$i]); + } + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Stts.php b/src/Zend/Media/Iso14496/Box/Stts.php new file mode 100644 index 0000000..60f5b20 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Stts.php @@ -0,0 +1,148 @@ +Decoding Time to Sample Box contains a compact version of a table + * that allows indexing from decoding time to sample number. Other tables give + * sample sizes and pointers, from the sample number. Each entry in the table + * gives the number of consecutive samples with the same time delta, and the + * delta of those samples. By adding the deltas a complete time-to-sample map + * may be built. + * + * The Decoding Time to Sample Box contains decode time delta's: DT(n+1) = DT(n) + * + STTS(n) where STTS(n) is the (uncompressed) table entry for sample n. + * + * The sample entries are ordered by decoding time stamps; therefore the deltas + * are all non-negative. + * + * The DT axis has a zero origin; DT(i) = SUM(for j=0 to i-1 of delta(j)), and + * the sum of all deltas gives the length of the media in the track (not mapped + * to the overall timescale, and not considering any edit list). + * + * The {@link Zend_Media_Iso14496_Box_Elst Edit List Box} provides the initial + * CT value if it is non-empty (non-zero). + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Stts extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_timeToSampleTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_timeToSampleTable[$i] = array + ('sampleCount' => $this->_reader->readUInt32BE(), + 'sampleDelta' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given duration. + * o sampleDelta -- an integer that gives the delta of these samples in + * the time-scale of the media. + * + * @return Array + */ + public function getTimeToSampleTable() + { + return $this->_timeToSampleTable; + } + + /** + * Sets an array of values. Each entry must be an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given duration. + * o sampleDelta -- an integer that gives the delta of these samples in + * the time-scale of the media. + * + * @param Array $timeToSampleTable The array of values. + */ + public function setTimeToSampleTable($timeToSampleTable) + { + $this->_timeToSampleTable = $timeToSampleTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_timeToSampleTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_timeToSampleTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE($this->_timeToSampleTable[$i]['sampleCount']) + ->writeUInt32BE + ($this->_timeToSampleTable[$i]['sampleDelta']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Tkhd.php b/src/Zend/Media/Iso14496/Box/Tkhd.php new file mode 100644 index 0000000..8e9bfce --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Tkhd.php @@ -0,0 +1,432 @@ +Track Header Box specifies the characteristics of a single track. + * Exactly one Track Header Box is contained in a track. + * + * In the absence of an edit list, the presentation of a track starts at the + * beginning of the overall presentation. An empty edit is used to offset the + * start time of a track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Tkhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_creationTime; + + /** @var integer */ + private $_modificationTime; + + /** @var integer */ + private $_trackId; + + /** @var integer */ + private $_duration; + + /** @var integer */ + private $_layer = 0; + + /** @var integer */ + private $_alternateGroup = 0; + + /** @var integer */ + private $_volume = 0; + + /** @var Array */ + private $_matrix = array + (0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000); + + /** @var integer */ + private $_width; + + /** @var integer */ + private $_height; + + /** + * Indicates that the track is enabled. A disabled track is treated as if it + * were not present. + */ + const TRACK_ENABLED = 1; + + /** Indicates that the track is used in the presentation. */ + const TRACK_IN_MOVIE = 2; + + /** Indicates that the track is used when previewing the presentation. */ + const TRACK_IN_PREVIEW = 4; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->getVersion() == 1) { + $this->_creationTime = $this->_reader->readInt64BE(); + $this->_modificationTime = $this->_reader->readInt64BE(); + $this->_trackId = $this->_reader->readUInt32BE(); + $this->_reader->skip(4); + $this->_duration = $this->_reader->readInt64BE(); + } else { + $this->_creationTime = $this->_reader->readUInt32BE(); + $this->_modificationTime = $this->_reader->readUInt32BE(); + $this->_trackId = $this->_reader->readUInt32BE(); + $this->_reader->skip(4); + $this->_duration = $this->_reader->readUInt32BE(); + } + $this->_reader->skip(8); + $this->_layer = $this->_reader->readInt16BE(); + $this->_alternateGroup = $this->_reader->readInt16BE(); + $this->_volume = + ((($tmp = $this->_reader->readUInt16BE()) >> 8) & 0xff) + + (float)("0." . ((string)($tmp & 0xff))); + $this->_reader->skip(2); + for ($i = 0; $i < 9; $i++) { + $this->_matrix[$i] = $this->_reader->readUInt32BE(); + } + $this->_width = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + $this->_height = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + } + + /** + * Returns the creation time of this track in seconds since midnight, Jan. 1, + * 1904, in UTC time. + * + * @return integer + */ + public function getCreationTime() + { + return $this->_creationTime; + } + + /** + * Sets the creation time of this track in seconds since midnight, Jan. 1, + * 1904, in UTC time. + * + * @param integer $creationTime The creation time. + */ + public function setCreationTime() + { + $this->_creationTime = $creationTime; + } + + /** + * Returns the most recent time the track was modified in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getModificationTime() + { + return $this->_modificationTime; + } + + /** + * Sets the most recent time the track was modified in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @param integer $modificationTime The modification time. + */ + public function setModificationTime($modificationTime) + { + $this->_modificationTime = $modificationTime; + } + + /** + * Returns a number that uniquely identifies this track over the entire + * life-time of this presentation. Track IDs are never re-used and cannot be + * zero. + * + * @return integer + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Returns a number that uniquely identifies this track over the entire + * life-time of this presentation. Track IDs are never re-used and cannot be + * zero. + * + * @param integer $trackId The track identification. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the duration of this track (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of this + * field is equal to the sum of the durations of all of the track's edits. + * If there is no edit list, then the duration is the sum of the sample + * durations, converted into the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. If the duration + * of this track cannot be determined then duration is set to all 32-bit + * maxint. + * + * @return integer + */ + public function getDuration() + { + return $this->_duration; + } + + /** + * Sets the duration of this track (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of this + * field must be equal to the sum of the durations of all of the track's + * edits. If there is no edit list, then the duration must be the sum of the + * sample durations, converted into the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. If the duration + * of this track cannot be determined then duration is set to all 32-bit + * maxint. + * + * @param integer $duration The duration of this track. + */ + public function setDuration($duration) + { + $this->_duration = $duration; + } + + /** + * Returns the front-to-back ordering of video tracks; tracks with lower + * numbers are closer to the viewer. 0 is the normal value, and -1 would be + * in front of track 0, and so on. + * + * @return integer + */ + public function getLayer() + { + return $this->_layer; + } + + /** + * Sets the front-to-back ordering of video tracks; tracks with lower + * numbers are closer to the viewer. 0 is the normal value, and -1 would be + * in front of track 0, and so on. + * + * @param integer $layer The layer. + */ + public function setLayer($layer) + { + $this->_layer = $layer; + } + + /** + * Returns an integer that specifies a group or collection of tracks. If + * this field is 0 there is no information on possible relations to other + * tracks. If this field is not 0, it should be the same for tracks that + * contain alternate data for one another and different for tracks belonging + * to different such groups. Only one track within an alternate group + * should be played or streamed at any one time, and must be distinguishable + * from other tracks in the group via attributes such as bitrate, codec, + * language, packet size etc. A group may have only one member. + * + * @return integer + */ + public function getAlternateGroup() + { + return $this->_alternateGroup; + } + + /** + * Returns an integer that specifies a group or collection of tracks. If + * this field is 0 there is no information on possible relations to other + * tracks. If this field is not 0, it should be the same for tracks that + * contain alternate data for one another and different for tracks belonging + * to different such groups. Only one track within an alternate group + * should be played or streamed at any one time, and must be distinguishable + * from other tracks in the group via attributes such as bitrate, codec, + * language, packet size etc. A group may have only one member. + * + * @param integer $alternateGroup The alternate group. + */ + public function setAlternateGroup($alternateGroup) + { + $this->_alternateGroup = $alternateGroup; + } + + /** + * Returns track's relative audio volume. Full volume is 1.0 (0x0100) and + * is the normal value. Its value is irrelevant for a purely visual track. + * Tracks may be composed by combining them according to their volume, and + * then using the overall Movie Header Box volume setting; or more complex + * audio composition (e.g. MPEG-4 BIFS) may be used. + * + * @return integer + */ + public function getVolume() + { + return $this->_volume; + } + + /** + * Sets track's relative audio volume. Full volume is 1.0 (0x0100) and + * is the normal value. Its value is irrelevant for a purely visual track. + * Tracks may be composed by combining them according to their volume, and + * then using the overall Movie Header Box volume setting; or more complex + * audio composition (e.g. MPEG-4 BIFS) may be used. + * + * @param integer $volume The volume. + */ + public function setVolume($volume) + { + $this->_volume = $volume; + } + + /** + * Returns the track's visual presentation width. This needs not be the same + * as the pixel width of the images; all images in the sequence are scaled + * to this width, before any overall transformation of the track represented + * by the matrix. The pixel width of the images is the default value. + * + * @return integer + */ + public function getWidth() + { + return $this->_width; + } + + /** + * Set the track's visual presentation width. This needs not be the same + * as the pixel width of the images; all images in the sequence are scaled + * to this width, before any overall transformation of the track represented + * by the matrix. The pixel width of the images should be the default value. + * + * @param integer $width The width. + */ + public function setWidth($width) + { + $this->_width = $width; + } + + /** + * Returns the track's visual presentation height. This needs not be the + * same as the pixel height of the images; all images in the sequence are + * scaled to this height, before any overall transformation of the track + * represented by the matrix. The pixel height of the images is the default + * value. + * + * @return integer + */ + public function getHeight() + { + return $this->_height; + } + + /** + * Sets the track's visual presentation height. This needs not be the + * same as the pixel height of the images; all images in the sequence are + * scaled to this height, before any overall transformation of the track + * represented by the matrix. The pixel height of the images should be the + * default value. + * + * @param integer $height The height. + */ + public function setHeight($height) + { + $this->_height = $height; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + ($this->getVersion() == 1 ? 32 : 20) + 60; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_creationTime) + ->writeInt64BE($this->_modificationTime) + ->writeUInt32BE($this->_trackId) + ->writeUInt32BE(0) + ->writeInt64BE($this->_duration); + } else { + $writer->writeUInt32BE($this->_creationTime) + ->writeUInt32BE($this->_modificationTime) + ->writeUInt32BE($this->_trackId) + ->writeUInt32BE(0) + ->writeUInt32BE($this->_duration); + } + + @list(, $volumeDecimals) = explode('.', (float)$this->_volume); + $writer->write(str_pad('', 8, "\0")) + ->writeInt16BE($this->_layer) + ->writeInt16BE($this->_alternateGroup) + ->writeUInt16BE(floor($this->_volume) << 8 | $volumeDecimals) + ->write(str_pad('', 2, "\0")); + for ($i = 0; $i < 9; $i++) { + $writer->writeUInt32BE($this->_matrix[$i]); + } + @list(, $widthDecimals) = explode('.', (float)$this->_width); + @list(, $heightDecimals) = explode('.', (float)$this->_height); + $writer->writeUInt32BE(floor($this->_width) << 16 | $widthDecimals) + ->writeUInt32BE(floor($this->_height) << 16 | $heightDecimals); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Traf.php b/src/Zend/Media/Iso14496/Box/Traf.php new file mode 100644 index 0000000..cc27cbd --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Traf.php @@ -0,0 +1,77 @@ +Track Fragment Box there is a set of track fragments, zero + * or more per track. The track fragments in turn contain zero or more track + * runs, each of which document a contiguous run of samples for that track. + * + * Within these structures, many fields are optional and can be defaulted. It is + * possible to add empty time to a track using these structures, as well as + * adding samples. Empty inserts can be used in audio tracks doing silence + * suppression, for example. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Traf extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Trak.php b/src/Zend/Media/Iso14496/Box/Trak.php new file mode 100644 index 0000000..8d8d671 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Trak.php @@ -0,0 +1,83 @@ +Track Box is a container box for a single track of a presentation. + * A presentation consists of one or more tracks. Each track is independent of + * the other tracks in the presentation and carries its own temporal and spatial + * information. Each track will contain its associated + * {@link Zend_Media_Iso14496_Box_Mdia Media Box}. + * + * Tracks are used for two purposes: + * (a) to contain media data (media tracks) and + * (b) to contain packetization information for streaming protocols + * (hint tracks). + * There shall be at least one media track within an ISO file, and all the media + * tracks that contributed to the hint tracks shall remain in the file, even if + * the media data within them is not referenced by the hint tracks; after + * deleting all hint tracks, the entire un-hinted presentation shall remain. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Trak extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Tref.php b/src/Zend/Media/Iso14496/Box/Tref.php new file mode 100644 index 0000000..b20e04b --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Tref.php @@ -0,0 +1,81 @@ +Track Reference Box provides a reference from the containing track + * to another track in the presentation. These references are typed. A + * {@link Zend_Media_Iso14496_Box_Hint hint} reference links from the containing + * hint track to the media data that it hints. A content description reference + * {@link Zend_Media_Iso14496_Box_Cdsc cdsc} links a descriptive or metadata + * track to the content which it describes. + * + * Exactly one Track Reference Box can be contained within the + * {@link Zend_Media_Iso14496_Box_Trak Track Box}. + * + * If this box is not present, the track is not referencing any other track in + * any way. The reference array is sized to fill the reference type box. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Tref extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Trex.php b/src/Zend/Media/Iso14496/Box/Trex.php new file mode 100644 index 0000000..a98331e --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Trex.php @@ -0,0 +1,214 @@ +Track Extends Box sets up default values used by the movie + * fragments. By setting defaults in this way, space and complexity can be saved + * in each {@link Zend_Media_Iso14496_Box_Traf Track Fragment Box}. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Trex extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_trackId; + + /** @var integer */ + private $_defaultSampleDescriptionIndex; + + /** @var integer */ + private $_defaultSampleDuration; + + /** @var integer */ + private $_defaultSampleSize; + + /** @var integer */ + private $_defaultSampleFlags; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + * @todo The sample flags could be parsed further + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_trackId = $this->_reader->readUInt32BE(); + $this->_defaultSampleDescriptionIndex = $this->_reader->readUInt32BE(); + $this->_defaultSampleDuration = $this->_reader->readUInt32BE(); + $this->_defaultSampleSize = $this->_reader->readUInt32BE(); + $this->_defaultSampleFlags = $this->_reader->readUInt32BE(); + } + + /** + * Returns the default track identifier. + * + * @return integer + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Sets the default track identifier. + * + * @param integer $trackId The track identifier. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the default sample description index. + * + * @return integer + */ + public function getDefaultSampleDescriptionIndex() + { + return $this->_defaultSampleDescriptionIndex; + } + + /** + * Sets the default sample description index. + * + * @param integer $defaultSampleDescriptionIndex The description index. + */ + public function getDefaultSampleDescriptionIndex + ($defaultSampleDescriptionIndex) + { + $this->_defaultSampleDescriptionIndex = $defaultSampleDescriptionIndex; + } + + /** + * Returns the default sample duration. + * + * @return integer + */ + public function getDefaultSampleDuration() + { + return $this->_defaultSampleDuration; + } + + /** + * Sets the default sample duration. + * + * @param integer $defaultSampleDuration The sample duration. + */ + public function setDefaultSampleDuration($defaultSampleDuration) + { + $this->_defaultSampleDuration = $defaultSampleDuration; + } + + /** + * Returns the default sample size. + * + * @return integer + */ + public function getDefaultSampleSize() + { + return $this->_defaultSampleSize; + } + + /** + * Sets the default sample size. + * + * @param integer $defaultSampleSize The sample size. + */ + public function setDefaultSampleSize($defaultSampleSize) + { + $this->_defaultSampleSize = $defaultSampleSize; + } + + /** + * Returns the default sample flags. + * + * @return integer + */ + public function getDefaultSampleFlags() + { + return $this->_defaultSampleFlags; + } + + /** + * Sets the default sample flags. + * + * @param integer $defaultSampleFlags The sample flags. + */ + public function setDefaultSampleFlags() + { + $this->_defaultSampleFlags = $defaultSampleFlags; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 20; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_trackId) + ->writeUInt32BE($this->_defaultSampleDescriptionIndex) + ->writeUInt32BE($this->_defaultSampleDuration) + ->writeUInt32BE($this->_defaultSampleSize) + ->writeUInt32BE($this->_defaultSampleFlags); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Udta.php b/src/Zend/Media/Iso14496/Box/Udta.php new file mode 100644 index 0000000..f155761 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Udta.php @@ -0,0 +1,75 @@ +User Data Box contains objects that declare user information about + * the containing box and its data (presentation or track). + * + * The User Data Box is a container box for informative user-data. This user + * data is formatted as a set of boxes with more specific box types, which + * declare more precisely their content. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Udta extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + $this->setContainer(true); + + if ($reader === null) { + return; + } + + $this->constructBoxes(); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Url.php b/src/Zend/Media/Iso14496/Box/Url.php new file mode 100644 index 0000000..0368511 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Url.php @@ -0,0 +1,122 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Url extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_location; + + /** + * Indicates that the media data is in the same file as the Movie Box + * containing this data reference. + */ + const SELF_CONTAINED = 1; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_location = $this->_reader->read + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the location. + * + * @return string + */ + public function getLocation() + { + return $this->_location; + } + + /** + * Sets the location. + * + * @param string $location The location string. + */ + public function setLocation($location) + { + $this->_location = $location; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + strlen($this->_location); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write($this->_location); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Urn.php b/src/Zend/Media/Iso14496/Box/Urn.php new file mode 100644 index 0000000..d7d742a --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Urn.php @@ -0,0 +1,148 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Urn extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_name; + + /** @var string */ + private $_location; + + /** + * Indicates that the media data is in the same file as the Movie Box + * containing this data reference. + */ + const SELF_CONTAINED = 1; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + list ($this->_name, $this->_location) = preg_split + ("/\\x00/", $this->_reader->read + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset())); + } + + /** + * Returns the name. + * + * @return string + */ + public function getName() + { + return $this->_name; + } + + /** + * Sets the name. + * + * @param string $name The name. + */ + public function setName($name) + { + $this->_name = $name; + } + + /** + * Returns the location. + * + * @return string + */ + public function getLocation() + { + return $this->_location; + } + + /** + * Sets the location. + * + * @param string $location The location. + */ + public function setLocation($location) + { + $this->_location = $location; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + strlen($this->_name) + 1 + strlen($this->_location); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeString8($this->_name, 1) + ->write($this->_location); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Vmhd.php b/src/Zend/Media/Iso14496/Box/Vmhd.php new file mode 100644 index 0000000..bb35de9 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Vmhd.php @@ -0,0 +1,153 @@ +Video Media Header Box contains general presentation information, + * independent of the coding, for video media. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Vmhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_graphicsMode = 0; + + /** @var Array */ + private $_opcolor = array(0, 0, 0); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + $this->setFlags(1); + return; + } + + $this->_graphicsMode = $this->_reader->readUInt16BE(); + $this->_opcolor = array + ($this->_reader->readUInt16BE(), + $this->_reader->readUInt16BE(), + $this->_reader->readUInt16BE()); + } + + /** + * Returns the composition mode for this video track, from the following + * enumerated set, which may be extended by derived specifications: + * + *
      + *
    • copy = 0 copy over the existing image
    • + *
    + * + * @return integer + */ + public function getGraphicsMode() + { + return $this->_graphicsMode; + } + + /** + * Sets the composition mode for this video track. + * + * @param integer $graphicsMode The composition mode. + */ + public function setGraphicsMode($graphicsMode) + { + $this->_graphicsMode = $graphicsMode; + } + + /** + * Returns an array of 3 colour values (red, green, blue) available for use + * by graphics modes. + * + * @return Array + */ + public function getOpcolor() + { + return $this->_opcolor; + } + + /** + * Sets the array of 3 colour values (red, green, blue) available for use + * by graphics modes. + * + * @param Array $opcolor An array of 3 colour values + */ + public function setOpcolor($opcolor) + { + $this->_opcolor = $opcolor; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE($this->_graphicsMode) + ->writeUInt16BE($this->_opcolor[0]) + ->writeUInt16BE($this->_opcolor[1]) + ->writeUInt16BE($this->_opcolor[2]); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Xml.php b/src/Zend/Media/Iso14496/Box/Xml.php new file mode 100644 index 0000000..cfdd267 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Xml.php @@ -0,0 +1,123 @@ +XML Box forms may be used. + * The {@link Zend_Media_Iso14496_Box_Bxml Binary XML Box} may only be used when + * there is a single well-defined binarization of the XML for that defined + * format as identified by the handler. + * + * Within an XML box the data is in UTF-8 format unless the data starts with a + * byte-order-mark (BOM), which indicates that the data is in UTF-16 format. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Xml extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_xml; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_xml = $this->_reader->read + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the XML data. + * + * @return string + */ + public function getXml() + { + return $this->_xml; + } + + /** + * Sets the XML data. + * + * @param string $xml The XML data. + */ + public function setXml($xml) + { + $this->_xml = $xml; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + strlen($this->_xml); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write($this->_xml); + } +} diff --git a/src/Zend/Media/Iso14496/Exception.php b/src/Zend/Media/Iso14496/Exception.php new file mode 100644 index 0000000..de3510e --- /dev/null +++ b/src/Zend/Media/Iso14496/Exception.php @@ -0,0 +1,52 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Iso14496_Exception extends Zend_Media_Exception +{} diff --git a/src/Zend/Media/Iso14496/FullBox.php b/src/Zend/Media/Iso14496/FullBox.php new file mode 100644 index 0000000..b07a9fa --- /dev/null +++ b/src/Zend/Media/Iso14496/FullBox.php @@ -0,0 +1,150 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Iso14496_FullBox extends Zend_Media_Iso14496_Box +{ + /** @var integer */ + protected $_version = 0; + + /** @var integer */ + protected $_flags = 0; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + + if ($reader === null) { + return; + } + + $this->_version = + (($field = $this->_reader->readUInt32BE()) >> 24) & 0xff; + $this->_flags = $field & 0xffffff; + } + + /** + * Returns the version of this format of the box. + * + * @return integer + */ + 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. + * + * @param integer $flag The flag to query. + * @return boolean + */ + public function hasFlag($flag) + { + return ($this->_flags & $flag) == $flag; + } + + /** + * Returns the map of flags. + * + * @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 heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data without the header. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($this->_version << 24 | $this->_flags); + } +} diff --git a/src/Zend/Media/Mpeg/Abs.php b/src/Zend/Media/Mpeg/Abs.php new file mode 100644 index 0000000..c8600e5 --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs.php @@ -0,0 +1,425 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @todo Implement validation routines + */ +final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object +{ + /** @var integer */ + private $_bytes; + + /** @var Array */ + private $_frames = array(); + + /** @var Zend_Media_Mpeg_Abs_XingHeader */ + private $_xingHeader = null; + + /** @var Zend_Media_Mpeg_Abs_LameHeader */ + private $_lameHeader = null; + + /** @var Zend_Media_Mpeg_Abs_VbriHeader */ + private $_vbriHeader = null; + + /** @var integer */ + private $_cumulativeBitrate = 0; + + /** @var integer */ + private $_cumulativePlayDuration = 0; + + /** @var integer */ + private $_estimatedBitrate = 0; + + /** @var integer */ + private $_estimatedPlayDuration = 0; + + /** @var integer */ + private $_lastFrameOffset = false; + + /** + * Constructs the Zend_Media_Mpeg_ABS class with given file and options. + * + * The following options are currently recognized: + * o readmode -- Can be one of full or lazy and determines when the read + * of frames and their data happens. When in full mode the data is read + * automatically during the instantiation of the frame and all the + * frames are read during the instantiation of this class. While this + * allows faster validation and data fetching, it is unnecessary in + * terms of determining just the play duration of the file. Defaults to + * lazy. + * + * o estimatePrecision -- Only applicaple with lazy read mode to determine + * the precision of play duration estimate. This precision is equal to + * how many frames are read before fixing the average bitrate that is + * used to calculate the play duration estimate of the whole file. Each + * frame adds about 0.1-0.2ms to the processing of the file. Defaults to + * 1000. + * + * When in lazy data reading mode it is first checked whether a VBR header + * is found in a file. If so, the play duration is calculated based no its + * data and no further frames are read from the file. If no VBR header is + * found, frames up to estimatePrecision are read to calculate an average + * bitrate. + * + * Hence, only zero or estimatePrecision number of frames are + * read in lazy data reading mode. The rest of the frames are read + * automatically when directly referenced, ie the data is read when it is + * needed. + * + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @param Array $options The options array. + */ + public function __construct($filename, $options = array()) + { + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + require_once 'Zend/Io/FileReader.php'; + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception($e->getMessage()); + } + } + $this->setOptions($options); + + $offset = $this->_reader->getOffset(); + $this->_bytes = $this->_reader->getSize(); + + /* Skip ID3v1 tag */ + $this->_reader->setOffset(-128); + if ($this->_reader->read(3) == 'TAG') { + $this->_bytes -= 128; + } + $this->_reader->setOffset($offset); + + /* Skip ID3v2 tag */ + if ($this->_reader->readString8(3) == 'ID3') { + require_once 'Zend/Media/Id3/Header.php'; + $header = new Zend_Media_Id3_Header($this->_reader); + $this->_reader->skip + ($header->getSize() + + ($header->hasFlag(Zend_Media_Id3_Header::FOOTER) ? 10 : 0)); + } else { + $this->_reader->setOffset($offset); + } + + /* Check for VBR headers */ + $offset = $this->_reader->getOffset(); + + $this->_frames[] = $firstFrame = + new Zend_Media_Mpeg_Abs_Frame($this->_reader, $options); + + $postoffset = $this->_reader->getOffset(); + + $this->_reader->setOffset + ($offset + 4 + self::$sidesizes + [$firstFrame->getFrequencyType()][$firstFrame->getMode()]); + if (($xing = $this->_reader->readString8(4)) == 'Xing' || + $xing == 'Info') { + require_once 'Zend/Media/Mpeg/Abs/XingHeader.php'; + $this->_xingHeader = + new Zend_Media_Mpeg_Abs_XingHeader($this->_reader, $options); + if ($this->_reader->readString8(4) == 'LAME') { + require_once 'Zend/Media/Mpeg/Abs/LameHeader.php'; + $this->_lameHeader = + new Zend_Media_Mpeg_Abs_LameHeader + ($this->_reader, $options); + } + + // A header frame is not counted as an audio frame + array_pop($this->_frames); + } + + $this->_reader->setOffset($offset + 4 + 32); + if ($this->_reader->readString8(4) == 'VBRI') { + require_once 'Zend/Media/Mpeg/Abs/VbriHeader.php'; + $this->_vbriHeader = + new Zend_Media_Mpeg_Abs_VbriHeader($this->_reader, $options); + + // A header frame is not counted as an audio frame + array_pop($this->_frames); + } + + $this->_reader->setOffset($postoffset); + + // Ensure we always have read at least one frame + if (empty($this->_frames)) { + $this->_readFrames(1); + } + + /* Read necessary frames */ + if ($this->getOption('readmode', 'lazy') == 'lazy') { + if (($header = $this->_xingHeader) !== null || + ($header = $this->_vbriHeader) !== null) { + $this->_estimatedPlayDuration = $header->getFrames() * + $firstFrame->getSamples() / + $firstFrame->getSamplingFrequency(); + if ($this->_lameHeader !== null) { + $this->_estimatedBitrate = $this->_lameHeader->getBitrate(); + if ($this->_estimatedBitrate == 255) { + $this->_estimatedBitrate = round + (($this->_lameHeader->getMusicLength()) / + (($header->getFrames() * + $firstFrame->getSamples()) / + $firstFrame->getSamplingFrequency()) / 1000 * 8); + } + } else { + $this->_estimatedBitrate = ($this->_bytes - $offset) / + $this->_estimatedPlayDuration / 1000 * 8; + } + } else { + $this->_readFrames($this->getOption('estimatePrecision', 1000)); + + $this->_estimatedBitrate = + $this->_cumulativeBitrate / count($this->_frames); + $this->_estimatedPlayDuration = + ($this->_bytes - $offset) / + ($this->_estimatedBitrate * 1000 / 8); + } + } else { + $this->_readFrames(); + + $this->_estimatedBitrate = + $this->_cumulativeBitrate / count($this->_frames); + $this->_estimatedPlayDuration = $this->_cumulativePlayDuration; + } + } + + /** + * Returns true if the audio bitstream contains the Xing VBR + * header, or false otherwise. + * + * @return boolean + */ + public function hasXingHeader() + { + return $this->_xingHeader === null; + } + + /** + * Returns the Xing VBR header, or null if not found in the audio + * bitstream. + * + * @return Zend_Media_Mpeg_Abs_XingHeader + */ + public function getXingHeader() + { + return $this->_xingHeader; + } + + /** + * Returns true if the audio bitstream contains the LAME VBR + * header, or false otherwise. + * + * @return boolean + */ + public function hasLameHeader() + { + return $this->_lameHeader === null; + } + + /** + * Returns the LAME VBR header, or null if not found in the audio + * bitstream. + * + * @return Zend_Media_Mpeg_Abs_LameHeader + */ + public function getLameHeader() + { + return $this->_lameHeader; + } + + /** + * Returns true if the audio bitstream contains the Fraunhofer IIS + * VBR header, or false otherwise. + * + * @return boolean + */ + public function hasVbriHeader() + { + return $this->_vbriHeader === null; + } + + /** + * Returns the Fraunhofer IIS VBR header, or null if not found in + * the audio bitstream. + * + * @return Zend_Media_Mpeg_Abs_VbriHeader + */ + public function getVbriHeader() + { + return $this->_vbriHeader; + } + + /** + * Returns the bitrate estimate. This value is either fetched from one of the + * headers or calculated based on the read frames. + * + * @return integer + */ + public function getBitrateEstimate() + { + return $this->_estimatedBitrate; + } + + /** + * For variable bitrate files this method returns the exact average bitrate of + * the whole file. + * + * @return integer + */ + public function getBitrate() + { + if ($this->getOption('readmode', 'lazy') == 'lazy') { + $this->_readFrames(); + } + return $this->_cumulativeBitrate / count($this->_frames); + } + + /** + * Returns the playtime estimate, in seconds. + * + * @return integer + */ + public function getLengthEstimate() + { + return $this->_estimatedPlayDuration; + } + + /** + * Returns the exact playtime in seconds. In lazy reading mode the frames + * are read from the file the first time you call this method to get the + * exact playtime of the file. + * + * @return integer + */ + public function getLength() + { + if ($this->getOption('readmode', 'lazy') == 'lazy') { + $this->_readFrames(); + } + return $this->_cumulativePlayDuration; + } + + /** + * Returns the playtime estimate as a string in the form of + * [hours:]minutes:seconds.milliseconds. + * + * @param integer $seconds The playtime in seconds. + * @return string + */ + public function getFormattedLengthEstimate() + { + return $this->formatTime($this->getLengthEstimate()); + } + + /** + * Returns the exact playtime given in seconds as a string in the form of + * [hours:]minutes:seconds.milliseconds. In lazy reading mode the frames are + * read from the file the first time you call this method to get the exact + * playtime of the file. + * + * @param integer $seconds The playtime in seconds. + * @return string + */ + public function getFormattedLength() + { + return $this->formatTime($this->getLength()); + } + + /** + * Returns all the frames of the audio bitstream as an array. In lazy + * reading mode the frames are read from the file the first time you call + * this method. + * + * @return Array + */ + public function getFrames() + { + if ($this->getOption('readmode', 'lazy') == 'lazy') { + $this->_readFrames(); + } + return $this->_frames; + } + + /** + * Reads frames up to given limit. If called subsequently the method + * continues after the last frame read in the last call, again to read up + * to the limit or just the rest of the frames. + * + * @param integer $limit The maximum number of frames read from the + * bitstream + */ + private function _readFrames($limit = null) + { + if ($this->_lastFrameOffset !== false) { + $this->_reader->setOffset($this->_lastFrameOffset); + } + + for ($i = 0; $this->_reader->getOffset() < $this->_bytes; $i++) { + $options = $this->getOptions(); + $frame = new Zend_Media_Mpeg_Abs_Frame($this->_reader, $options); + + $this->_cumulativePlayDuration += + (double)($frame->getLength() / + ($frame->getBitrate() * 1000 / 8)); + $this->_cumulativeBitrate += $frame->getBitrate(); + $this->_frames[] = $frame; + + if ($limit === null) { + $this->_lastFrameOffset = $this->_reader->getOffset(); + } + if ($limit !== null && ($i + 1) == $limit) { + $this->_lastFrameOffset = $this->_reader->getOffset(); + break; + } + } + } +} diff --git a/src/Zend/Media/Mpeg/Abs/Frame.php b/src/Zend/Media/Mpeg/Abs/Frame.php new file mode 100644 index 0000000..ea1d2fa --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs/Frame.php @@ -0,0 +1,550 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object +{ + /** + * The bitrate lookup table. The table has the following format. + * + * + * array ( + * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( + * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) + * ) + * ) + * + * + * @var Array + */ + private static $bitrates = array ( + self::SAMPLING_FREQUENCY_HIGH => array ( + self::LAYER_ONE => array ( + 1 => 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, + 416, 448 + ), + self::LAYER_TWO => array ( + 1 => 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, + 384 + ), + self::LAYER_THREE => array ( + 1 => 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, + 320 + ) + ), + self::SAMPLING_FREQUENCY_LOW => array ( + self::LAYER_ONE => array ( + 1 => 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, + 256 + ), + self::LAYER_TWO => array ( + 1 => 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 + ), + self::LAYER_THREE => array ( + 1 => 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 + ) + ) + ); + + /** + * Sample rate lookup table. The table has the following format. + * + * + * array ( + * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) + * ) + * + * + * @var Array + */ + private static $samplingFrequencies = array ( + self::VERSION_ONE => array (44100, 48000, 32000), + self::VERSION_TWO => array (22050, 24000, 16000), + self::VERSION_TWO_FIVE => array (11025, 12000, 8000) + ); + + /** + * Samples per frame lookup table. The table has the following format. + * + * + * array ( + * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( + * LAYER_ONE | LAYER_TWO | LAYER_TREE => + * ) + * ) + * + * + * @var Array + */ + private static $samples = array ( + self::SAMPLING_FREQUENCY_HIGH => array ( + self::LAYER_ONE => 384, + self::LAYER_TWO => 1152, + self::LAYER_THREE => 1152), + self::SAMPLING_FREQUENCY_LOW => array ( + self::LAYER_ONE => 384, + self::LAYER_TWO => 1152, + self::LAYER_THREE => 576)); + + /** + * Coefficient lookup table. The table has the following format. + * + * + * array ( + * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( + * LAYER_ONE | LAYER_TWO | LAYER_TREE => array ( ) + * ) + * ) + * + * + * @var Array + */ + private static $coefficients = array ( + self::SAMPLING_FREQUENCY_HIGH => array ( + self::LAYER_ONE => 12, self::LAYER_TWO => 144, + self::LAYER_THREE => 144 + ), + self::SAMPLING_FREQUENCY_LOW => array ( + self::LAYER_ONE => 12, self::LAYER_TWO => 144, + self::LAYER_THREE => 72 + ) + ); + + /** + * Slot size per layer lookup table. The table has the following format. + * + * + * array ( + * LAYER_ONE | LAYER_TWO | LAYER_TREE => + * ) + * + * + * @var Array + */ + private static $slotsizes = array ( + self::LAYER_ONE => 4, self::LAYER_TWO => 1, self::LAYER_THREE => 1 + ); + + /** @var integer */ + private $_offset; + + /** @var integer */ + private $_version; + + /** @var integer */ + private $_frequencyType; + + /** @var integer */ + private $_layer; + + /** @var integer */ + private $_redundancy; + + /** @var integer */ + private $_bitrate; + + /** @var integer */ + private $_samplingFrequency; + + /** @var integer */ + private $_padding; + + /** @var integer */ + private $_mode; + + /** @var integer */ + private $_modeExtension; + + /** @var integer */ + private $_copyright; + + /** @var integer */ + private $_original; + + /** @var integer */ + private $_emphasis; + + /** @var integer */ + private $_length; + + /** @var integer */ + private $_samples; + + /** @var integer */ + private $_crc = false; + + /** @var string */ + private $_data = false; + + /** + * Constructs the class with given parameters and reads object related data + * from the frame. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options Array of options. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_offset = $this->_reader->getOffset(); + + $header = $this->_reader->readUInt32BE(); + $this->_version = Zend_Bit_Twiddling::getValue($header, 19, 20); + $this->_frequencyType = Zend_Bit_Twiddling::testBit($header, 19); + $this->_layer = Zend_Bit_Twiddling::getValue($header, 17, 18); + $this->_redundancy = !Zend_Bit_Twiddling::testBit($header, 16); + $this->_bitrate = isset + (self::$bitrates[$this->_frequencyType][$this->_layer] + [$index = Zend_Bit_Twiddling::getValue($header, 12, 15)]) ? + self::$bitrates[$this->_frequencyType][$this->_layer][$index] : + false; + $this->_samplingFrequency = isset + (self::$samplingFrequencies[$this->_version] + [$index = Zend_Bit_Twiddling::getValue($header, 10, 11)]) ? + self::$samplingFrequencies[$this->_version][$index] : false; + $this->_padding = Zend_Bit_Twiddling::testBit($header, 9); + $this->_mode = Zend_Bit_Twiddling::getValue($header, 6, 7); + $this->_modeExtension = Zend_Bit_Twiddling::getValue($header, 4, 5); + $this->_copyright = Zend_Bit_Twiddling::testBit($header, 3); + $this->_original = Zend_Bit_Twiddling::testBit($header, 2); + $this->_emphasis = Zend_Bit_Twiddling::getValue($header, 0, 1); + + $this->_length = (int) + ((self::$coefficients[$this->_frequencyType][$this->_layer] * + ($this->_bitrate * 1000) / $this->_samplingFrequency) + + ($this->_padding ? 1 : 0)) * self::$slotsizes[$this->_layer]; + $this->_samples = self::$samples[$this->_frequencyType][$this->_layer]; + + if ($this->getOption('readmode', 'lazy') == 'full') { + $this->_readCrc(); + $this->_readData(); + } + $this->_reader->skip($this->_length - 4); + } + + /** + * Returns the version identifier of the algorithm. + * + * @see VERSION_ONE, VERSION_TWO, VERSION_TWO_FIVE + * @return integer + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Returns the sampling frequency type. This can be one of the following + * values. + * + * o {@link SAMPLING_FREQUENCY_HIGH} -- Higher Sampling Frequency + * (Version 1) + * o {@link SAMPLING_FREQUENCY_LOW} -- Lower Sampling Frequency + * (Version 2 and 2.5) + * + * @see SAMPLING_FREQUENCY_LOW, SAMPLING_FREQUENCY_HIGH + * @return integer + */ + public function getFrequencyType() + { + return $this->_frequencyType; + } + + /** + * Returns the type of layer used. + * + * @see LAYER_ONE, LAYER_TWO, LAYER_THREE + * @return integer + */ + public function getLayer() + { + return $this->_layer; + } + + /** + * An alias to getRedundancy(). + * + * @see getRedundancy + * @return boolean + */ + public function hasRedundancy() + { + return $this->getRedundancy(); + } + + /** + * Returns boolean corresponding to whether redundancy has been added in the + * audio bitstream to facilitate error detection and concealment. Equals + * false if no redundancy has been added, true if + * redundancy has been added. + * + * @return boolean + */ + public function getRedundancy() + { + return $this->_redundancy; + } + + /** + * Returns the bitrate in kbps. The returned value indicates the total bitrate + * irrespective of the mode (stereo, joint_stereo, dual_channel, + * single_channel). + * + * @return integer + */ + public function getBitrate() + { + return $this->_bitrate; + } + + /** + * Returns the sampling frequency in Hz. + * + * @return integer + */ + public function getSamplingFrequency() + { + return $this->_samplingFrequency; + } + + /** + * An alias to getPadding(). + * + * @see getPadding + * @return boolean + */ + public function hasPadding() + { + return $this->getPadding(); + } + + /** + * Returns boolean corresponding the frame contains an additional slot to + * adjust the mean bitrate to the sampling frequency. Equals to + * true if padding has been added, false otherwise. + * + * Padding is only necessary with a sampling frequency of 44.1kHz. + * + * @return boolean + */ + public function getPadding() + { + return $this->_padding; + } + + /** + * Returns the mode. In Layer I and II the CHANNEL_JOINT_STEREO mode is + * intensity_stereo, in Layer III it is intensity_stereo and/or ms_stereo. + * + * @see CHANNEL_STEREO, CHANNEL_JOINT_STEREO, CHANNEL_DUAL_CHANNEL, + * CHANNEL_SINGLE_CHANNEL + * @return integer + */ + public function getMode() + { + return $this->_mode; + } + + /** + * Returns the mode extension used in CHANNEL_JOINT_STEREO mode. + * + * In Layer I and II the return type indicates which subbands are in + * intensity_stereo. All other subbands are coded in stereo. + * + * o {@link MODE_SUBBAND_4_TO_31} -- subbands 4-31 in + * intensity_stereo, bound==4 + * o {@link MODE_SUBBAND_8_TO_31} -- subbands 8-31 in + * intensity_stereo, bound==8 + * o {@link MODE_SUBBAND_12_TO_31} -- subbands 12-31 in + * intensity_stereo, bound==12 + * o {@link MODE_SUBBAND_16_TO_31} -- subbands 16-31 in + * intensity_stereo, bound==16 + * + * In Layer III they indicate which type of joint stereo coding method is + * applied. The frequency ranges over which the intensity_stereo and + * ms_stereo modes are applied are implicit in the algorithm. Please see + * {@link MODE_ISOFF_MSSOFF}, {@link MODE_ISON_MSSOFF}, + * {@link MODE_ISOFF_MSSON}, and {@link MODE_ISON_MSSON}. + * + * @return integer + */ + public function getModeExtension() + { + return $this->_modeExtension; + } + + /** + * An alias to getCopyright(). + * + * @see getCopyright + * @return boolean + */ + public function hasCopyright() + { + return $this->getCopyright(); + } + + /** + * Returns true if the coded bitstream is copyright protected, + * false otherwise. + * + * @return boolean + */ + public function getCopyright() + { + return $this->_copyright; + } + + /** + * An alias to getOriginal(). + * + * @see getOriginal + * @return boolean + */ + public function isOriginal() + { + return $this->getOriginal(); + } + + /** + * Returns whether the bitstream is original or home made. + * + * @return boolean + */ + public function getOriginal() + { + return $this->_original; + } + + /** + * Returns the type of de-emphasis that shall be used. The value is one of + * the following. + * + * o {@link EMPHASIS_NONE} -- No emphasis + * o {@link EMPHASIS_50_15} -- 50/15 microsec. emphasis + * o {@link EMPHASIS_CCIT_J17} -- CCITT J.17 + * + * @see EMPHASIS_NONE, EMPHASIS_50_15, EMPHASIS_CCIT_J17 + * @return integer + */ + public function getEmphasis() + { + return $this->_emphasis; + } + + /** + * Returns the length of the frame based on the current layer, bit rate, + * sampling frequency and padding, in bytes. + * + * @return integer + */ + public function getLength() + { + return $this->_length; + } + + /** + * Returns the number of samples contained in the frame. + * + * @return integer + */ + public function getSamples() + { + return $this->_samples; + } + + /** + * Returns the 16-bit CRC of the frame or false if not present. + * + * @return integer + */ + public function getCrc() + { + if ($this->getOption('readmode', 'lazy') == 'lazy' && + $this->hasRedundancy() && $this->_crc === false) { + $this->_readCrc(); + } + return $this->_crc; + } + + /** + * Reads the CRC data. + */ + private function _readCrc() + { + if ($this->hasRedundancy()) { + $offset = $this->_reader->getOffset(); + $this->_reader->setOffset($this->_offset + 4); + $this->_crc = $this->_reader->readUInt16BE(); + $this->_reader->setOffset($offset); + } + } + + /** + * Returns the audio data. + * + * @return string + */ + public function getData() + { + if ($this->getOption('readmode', 'lazy') == 'lazy' && + $this->_data === false) { + $this->_readData(); + } + return $this->_data; + } + + /** + * Reads the frame data. + */ + private function _readData() + { + $offset = $this->_reader->getOffset(); + $this->_reader->setOffset + ($this->_offset + 4 + ($this->hasRedundancy() ? 2 : 0)); + $this->_data = $this->_reader->read + ($this->getLength() - 4 - ($this->hasRedundancy() ? 2 : 0)); + $this->_reader->setOffset($offset); + } +} diff --git a/src/Zend/Media/Mpeg/Abs/LameHeader.php b/src/Zend/Media/Mpeg/Abs/LameHeader.php new file mode 100644 index 0000000..78d7ab4 --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs/LameHeader.php @@ -0,0 +1,527 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Mpeg_Abs_LameHeader extends Zend_Media_Mpeg_Abs_Object +{ + /** @var integer */ + const VBR_METHOD_CONSTANT = 1; + + /** @var integer */ + const VBR_METHOD_ABR = 2; + + /** @var integer */ + const VBR_METHOD_RH = 3; + + /** @var integer */ + const VBR_METHOD_MTRH = 4; + + /** @var integer */ + const VBR_METHOD_MT = 5; + + /** @var integer */ + const ENCODING_FLAG_NSPSYTUNE = 1; + + /** @var integer */ + const ENCODING_FLAG_NSSAFEJOINT = 2; + + /** @var integer */ + const ENCODING_FLAG_NOGAP_CONTINUED = 4; + + /** @var integer */ + const ENCODING_FLAG_NOGAP_CONTINUATION = 8; + + /** @var integer */ + const MODE_MONO = 0; + + /** @var integer */ + const MODE_STEREO = 1; + + /** @var integer */ + const MODE_DUAL = 2; + + /** @var integer */ + const MODE_JOINT = 3; + + /** @var integer */ + const MODE_FORCE = 4; + + /** @var integer */ + const MODE_AUTO = 5; + + /** @var integer */ + const MODE_INTENSITY = 6; + + /** @var integer */ + const MODE_UNDEFINED = 7; + + /** @var integer */ + const SOURCE_FREQUENCY_32000_OR_LOWER = 0; + + /** @var integer */ + const SOURCE_FREQUENCY_44100 = 1; + + /** @var integer */ + const SOURCE_FREQUENCY_48000 = 2; + + /** @var integer */ + const SOURCE_FREQUENCY_HIGHER = 3; + + /** @var integer */ + const SURROUND_NONE = 0; + + /** @var integer */ + const SURROUND_DPL = 1; + + /** @var integer */ + const SURROUND_DPL2 = 2; + + /** @var integer */ + const SURROUND_AMBISONIC = 3; + + /** @var string */ + private $_version; + + /** @var integer */ + private $_revision; + + /** @var integer */ + private $_vbrMethod; + + /** @var integer */ + private $_lowpass; + + /** @var integer */ + private $_peakSignalAmplitude; + + /** @var integer */ + private $_radioReplayGain; + + /** @var integer */ + private $_audiophileReplayGain; + + /** @var integer */ + private $_encodingFlags; + + /** @var integer */ + private $_athType; + + /** @var integer */ + private $_bitrate; + + /** @var integer */ + private $_encoderDelaySamples; + + /** @var integer */ + private $_paddedSamples; + + /** @var integer */ + private $_sourceSampleFrequency; + + /** @var boolean */ + private $_unwiseSettingsUsed; + + /** @var integer */ + private $_mode; + + /** @var integer */ + private $_noiseShaping; + + /** @var integer */ + private $_mp3Gain; + + /** @var integer */ + private $_surroundInfo; + + /** @var integer */ + private $_presetUsed; + + /** @var integer */ + private $_musicLength; + + /** @var integer */ + private $_musicCrc; + + /** @var integer */ + private $_crc; + + /** + * Constructs the class with given parameters and reads object related data + * from the bitstream. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options Array of options. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_version = $this->_reader->readString8(5); + + $tmp = $this->_reader->readUInt8(); + $this->_revision = Zend_Bit_Twiddling::getValue($tmp, 4, 8); + $this->_vbrMethod = Zend_Bit_Twiddling::getValue($tmp, 0, 3); + + $this->_lowpass = $this->_reader->readUInt8() * 100; + + $this->_peakSignalAmplitude = $this->_reader->readUInt32BE(); + + $tmp = $this->_reader->readUInt16BE(); + $this->_radioReplayGain = array( + 'name' => Zend_Bit_Twiddling::getValue($tmp, 0, 2), + 'originator' => Zend_Bit_Twiddling::getValue($tmp, 3, 5), + 'absoluteGainAdjustment' => + Zend_Bit_Twiddling::getValue($tmp, 7, 15) / 10 + ); + + $tmp = $this->_reader->readUInt16BE(); + $this->_audiophileReplayGain = array( + 'name' => Zend_Bit_Twiddling::getValue($tmp, 0, 2), + 'originator' => Zend_Bit_Twiddling::getValue($tmp, 3, 5), + 'absoluteGainAdjustment' => + Zend_Bit_Twiddling::getValue($tmp, 7, 15) / 10 + ); + + $tmp = $this->_reader->readUInt8(); + $this->_encodingFlags = Zend_Bit_Twiddling::getValue($tmp, 4, 8); + $this->_athType = Zend_Bit_Twiddling::getValue($tmp, 0, 3); + + $this->_bitrate = $this->_reader->readUInt8(); + + $tmp = $this->_reader->readUInt32BE(); + // Encoder delay fields + $this->_encoderDelaySamples = + Zend_Bit_Twiddling::getValue($tmp, 20, 31); + $this->_paddedSamples = Zend_Bit_Twiddling::getValue($tmp, 8, 19); + // Misc field + $this->_sourceSampleFrequency = + Zend_Bit_Twiddling::getValue($tmp, 6, 7); + $this->_unwiseSettingsUsed = Zend_Bit_Twiddling::testBit($tmp, 5); + $this->_mode = Zend_Bit_Twiddling::getValue($tmp, 2, 4); + $this->_noiseShaping = Zend_Bit_Twiddling::getValue($tmp, 0, 1); + + $this->_mp3Gain = pow(2, $this->_reader->readInt8() / 4); + + $tmp = $this->_reader->readUInt16BE(); + $this->_surroundInfo = Zend_Bit_Twiddling::getValue($tmp, 11, 14); + $this->_presetUsed = Zend_Bit_Twiddling::getValue($tmp, 0, 10); + + $this->_musicLength = $this->_reader->readUInt32BE(); + + $this->_musicCrc = $this->_reader->readUInt16BE(); + $this->_crc = $this->_reader->readUInt16BE(); + } + + /** + * Returns the version string of the header. + * + * @return string + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Returns the info tag revision. + * + * @return integer + */ + public function getRevision() + { + return $this->_revision; + } + + /** + * Returns the VBR method used for encoding. See the corresponding constants + * for possible return values. + * + * @return integer + */ + public function getVbrMethod() + { + return $this->_vbrMethod; + } + + /** + * Returns the lowpass filter value. + * + * @return integer + */ + public function getLowpass() + { + return $this->_lowpass; + } + + /** + * Returns the peak signal amplitude field of replay gain. The value of 1.0 + * (ie 100%) represents maximal signal amplitude storeable in decoding + * format. + * + * @return integer + */ + public function getPeakSignalAmplitude() + { + return $this->_peakSignalAmplitude; + } + + /** + * Returns the radio replay gain field of replay gain, required to make all + * tracks equal loudness, as an array that consists of the following keys. + * + * o name -- Specifies the name of the gain adjustment. Can be one of the + * following values: 0 = not set, 1 = radio, or 2 = audiophile. + * + * o originator -- Specifies the originator of the gain adjustment. Can be + * one of the following values: 0 = not set, 1 = set by artist, 2 = set + * by user, 3 = set by my model, 4 = set by simple RMS average. + * + * o absoluteGainAdjustment -- Speficies the absolute gain adjustment. + * + * @return Array + */ + public function getRadioReplayGain() + { + return $this->_radioReplayGain; + } + + /** + * Returns the audiophile replay gain field of replay gain, required to give + * ideal listening loudness, as an array that consists of the following + * keys. + * + * o name -- Specifies the name of the gain adjustment. Can be one of the + * following values: 0 = not set, 1 = radio, or 2 = audiophile. + * + * o originator -- Specifies the originator of the gain adjustment. Can be + * one of the following values: 0 = not set, 1 = set by artist, 2 = set + * by user, 3 = set by my model, 4 = set by simple RMS average. + * + * o absoluteGainAdjustment -- Speficies the absolute gain adjustment. + * + * @return Array + */ + public function getAudiophileReplayGain() + { + return $this->_audiophileReplayGain; + } + + /** + * Returns the encoding flags. See the corresponding flag constants for + * possible values. + * + * @return integer + */ + public function getEncodingFlags() + { + return $this->_encodingFlags; + } + + /** + * Returns the ATH type. + * + * @return integer + */ + public function getAthType() + { + return $this->_athType; + } + + /** + * Returns the bitrate for CBR encoded files and the minimal birate for + * VBR encoded file. The maximum value of this field is 255 even with higher + * actual bitrates. + * + * @return integer + */ + public function getBitrate() + { + return $this->_bitrate; + } + + /** + * Returns the encoder delay or number of samples added at start. + * + * @return integer + */ + public function getEncoderDelaySamples() + { + return $this->_encoderDelaySamples; + } + + /** + * Returns the number of padded samples to complete the last frame. + * + * @return integer + */ + public function getPaddedSamples() + { + return $this->_paddedSamples; + } + + /** + * Returns the source sample frequency. See corresponding constants for + * possible values. + * + * @return integer + */ + public function getSourceSampleFrequency() + { + return $this->_sourceSampleFrequency; + } + + /** + * An alias to getUnwiseSettingsUsed(). + * + * @see getUnwiseSettingsUsed + * @return boolean + */ + public function areUnwiseSettingsUsed() + { + return $this->getUnwiseSettingsUsed(); + } + + /** + * Returns whether unwise settings were used to encode the file. + * + * @return boolean + */ + public function getUnwiseSettingsUsed() + { + return $this->_unwiseSettingsUsed; + } + + /** + * Returns the stereo mode. See corresponding constants for possible values. + * + * @return integer + */ + public function getMode() + { + return $this->_mode; + } + + /** + * Returns the noise shaping. + * + * @return integer + */ + public function getNoiseShaping() + { + return $this->_noiseShaping; + } + + /** + * Returns the MP3 gain change. Any MP3 can be amplified in a lossless + * manner. If done so, this field can be used to log such transformation + * happened so that any given time it can be undone. + * + * @return integer + */ + public function getMp3Gain() + { + return $this->_mp3Gain; + } + + /** + * Returns the surround info. See corresponding contants for possible + * values. + * + * @return integer + */ + public function getSurroundInfo() + { + return $this->_surroundInfo; + } + + /** + * Returns the preset used in encoding. + * + * @return integer + */ + public function getPresetUsed() + { + return $this->_presetUsed; + } + + /** + * Returns the exact length in bytes of the MP3 file originally made by LAME + * excluded ID3 tag info at the end. + * + * The first byte it counts is the first byte of this LAME header and the + * last byte it counts is the last byte of the last MP3 frame containing + * music. The value should be equal to file length at the time of LAME + * encoding, except when using ID3 tags. + * + * @return integer + */ + public function getMusicLength() + { + return $this->_musicLength; + } + + /** + * Returns the CRC-16 of the complete MP3 music data as made originally by + * LAME. + * + * @return integer + */ + public function getMusicCrc() + { + return $this->_musicCrc; + } + + /** + * Returns the CRC-16 of the first 190 bytes of the header frame. + * + * @return integer + */ + public function getCrc() + { + return $this->_crc; + } +} diff --git a/src/Zend/Media/Mpeg/Abs/Object.php b/src/Zend/Media/Mpeg/Abs/Object.php new file mode 100644 index 0000000..b4550f8 --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs/Object.php @@ -0,0 +1,150 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Mpeg_Abs_Object extends Zend_Media_Mpeg_Object +{ + /** @var integer */ + const VERSION_ONE = 3; + + /** @var integer */ + const VERSION_TWO = 2; + + /** @var integer */ + const VERSION_TWO_FIVE = 0; + + /** @var integer */ + const SAMPLING_FREQUENCY_LOW = 0; + + /** @var integer */ + const SAMPLING_FREQUENCY_HIGH = 1; + + /** @var integer */ + const LAYER_ONE = 3; + + /** @var integer */ + const LAYER_TWO = 2; + + /** @var integer */ + const LAYER_THREE = 1; + + /** @var integer */ + const CHANNEL_STEREO = 0; + + /** @var integer */ + const CHANNEL_JOINT_STEREO = 1; + + /** @var integer */ + const CHANNEL_DUAL_CHANNEL = 2; + + /** @var integer */ + const CHANNEL_SINGLE_CHANNEL = 3; + + /** @var integer */ + const MODE_SUBBAND_4_TO_31 = 0; + + /** @var integer */ + const MODE_SUBBAND_8_TO_31 = 1; + + /** @var integer */ + const MODE_SUBBAND_12_TO_31 = 2; + + /** @var integer */ + const MODE_SUBBAND_16_TO_31 = 3; + + /** @var integer */ + const MODE_ISOFF_MSSOFF = 0; + + /** @var integer */ + const MODE_ISON_MSSOFF = 1; + + /** @var integer */ + const MODE_ISOFF_MSSON = 2; + + /** @var integer */ + const MODE_ISON_MSSON = 3; + + /** @var integer */ + const EMPHASIS_NONE = 0; + + /** @var integer */ + const EMPHASIS_50_15 = 1; + + /** @var integer */ + const EMPHASIS_CCIT_J17 = 3; + + /** + * Layer III side information size lookup table. The table has the + * following format. + * + * + * array ( + * SAMPLING_FREQUENCY_HIGH | SAMPLING_FREQUENCY_LOW => array ( + * CHANNEL_STEREO | CHANNEL_JOINT_STEREO | CHANNEL_DUAL_CHANNEL | + * CHANNEL_SINGLE_CHANNEL => + * ) + * ) + * + * + * @var Array + */ + protected static $sidesizes = array( + self::SAMPLING_FREQUENCY_HIGH => array( + self::CHANNEL_STEREO => 32, + self::CHANNEL_JOINT_STEREO => 32, + self::CHANNEL_DUAL_CHANNEL => 32, + self::CHANNEL_SINGLE_CHANNEL => 17 + ), + self::SAMPLING_FREQUENCY_LOW => array( + self::CHANNEL_STEREO => 17, + self::CHANNEL_JOINT_STEREO => 17, + self::CHANNEL_DUAL_CHANNEL => 17, + self::CHANNEL_SINGLE_CHANNEL => 9 + ) + ); + + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + } +} diff --git a/src/Zend/Media/Mpeg/Abs/VbriHeader.php b/src/Zend/Media/Mpeg/Abs/VbriHeader.php new file mode 100644 index 0000000..057085e --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs/VbriHeader.php @@ -0,0 +1,175 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Mpeg_Abs_VbriHeader extends Zend_Media_Mpeg_Abs_Object +{ + /** @var integer */ + private $_version; + + /** @var integer */ + private $_delay; + + /** @var integer */ + private $_qualityIndicator; + + /** @var integer */ + private $_bytes; + + /** @var integer */ + private $_frames; + + /** @var Array */ + private $_toc = array(); + + /** @var integer */ + private $_tocFramesPerEntry; + + /** @var integer */ + private $_length; + + /** + * Constructs the class with given parameters and reads object related data + * from the bitstream. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options Array of options. + */ + public function __construct($reader, &$options = array()) + { + $offset = $this->_reader->getOffset(); + $this->_version = $this->_reader->readUInt16BE(); + $this->_delay = $this->_reader->readUInt16BE(); + $this->_qualityIndicator = $this->_reader->readUInt16BE(); + $this->_bytes = $this->_reader->readUInt32BE(); + $this->_frames = $this->_reader->readUInt32BE(); + $tocEntries = $this->_reader->readUInt16BE(); + $tocEntryScale = $this->_reader->readUInt16BE(); + $tocEntrySize = $this->_reader->readUInt16BE(); + $this->_tocFramesPerEntry = $this->_reader->readUInt16BE(); + $this->_toc = array_merge(unpack(($tocEntrySize == 1) ? 'C*' : + ($tocEntrySize == 2) ? 'n*' : 'N*', + $this->_reader->read($tocCount * $tocEntrySize))); + foreach ($this->_toc as $key => $value) { + $this->_toc[$key] = $tocEntryScale * $value; + } + $this->_length = $this->_reader->getOffset() - $offset; + } + + /** + * Returns the header version. + * + * @return integer + */ + public function getVersion() + { + return $this->_version; + } + + /** + * Returns the delay. + * + * @return integer + */ + public function getDelay() + { + return $this->_delay; + } + + /** + * Returns the quality indicator. Return value varies from 0 (best quality) + * to 100 (worst quality). + * + * @return integer + */ + public function getQualityIndicator() + { + return $this->_qualityIndicator; + } + + /** + * Returns the number of bytes in the file. + * + * @return integer + */ + public function getBytes() + { + return $this->_bytes; + } + + /** + * Returns the number of frames in the file. + * + * @return integer + */ + public function getFrames() + { + return $this->_frames; + } + + /** + * Returns the table of contents array. + * + * @return Array + */ + public function getToc() + { + return $this->_toc; + } + + /** + * Returns the number of frames per TOC entry. + * + * @return integer + */ + public function getTocFramesPerEntry() + { + return $this->_tocFramesPerEntry; + } + + /** + * Returns the length of the header in bytes. + * + * @return integer + */ + public function getLength() + { + return $this->_length; + } +} diff --git a/src/Zend/Media/Mpeg/Abs/XingHeader.php b/src/Zend/Media/Mpeg/Abs/XingHeader.php new file mode 100644 index 0000000..b6bc97b --- /dev/null +++ b/src/Zend/Media/Mpeg/Abs/XingHeader.php @@ -0,0 +1,137 @@ + + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Mpeg_Abs_XingHeader extends Zend_Media_Mpeg_Abs_Object +{ + /** @var integer */ + private $_frames = false; + + /** @var integer */ + private $_bytes = false; + + /** @var Array */ + private $_toc = array(); + + /** @var integer */ + private $_qualityIndicator = false; + + /** + * Constructs the class with given parameters and reads object related data + * from the bitstream. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options Array of options. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $flags = $reader->readUInt32BE(); + + if (Zend_Bit_Twiddling::testAnyBits($flags, 0x1)) { + $this->_frames = $this->_reader->readUInt32BE(); + } + if (Zend_Bit_Twiddling::testAnyBits($flags, 0x2)) { + $this->_bytes = $this->_reader->readUInt32BE(); + } + if (Zend_Bit_Twiddling::testAnyBits($flags, 0x4)) { + $this->_toc = array_merge(unpack('C*', $this->_reader->read(100))); + } + if (Zend_Bit_Twiddling::testAnyBits($flags, 0x8)) { + $this->_qualityIndicator = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns the number of frames in the file. + * + * @return integer + */ + public function getFrames() + { + return $this->_frames; + } + + /** + * Returns the number of bytes in the file. + * + * @return integer + */ + public function getBytes() + { + return $this->_bytes; + } + + /** + * Returns the table of contents array. The returned array has a fixed + * amount of 100 seek points to the file. + * + * @return Array + */ + public function getToc() + { + return $this->_toc; + } + + /** + * Returns the quality indicator. The indicator is from 0 (best quality) to + * 100 (worst quality). + * + * @return integer + */ + public function getQualityIndicator() + { + return $this->_qualityIndicator; + } + + /** + * Returns the length of the header in bytes. + * + * @return integer + */ + public function getLength() + { + return 4 + + ($this->_frames !== false ? 4 : 0) + + ($this->_bytes !== false ? 4 : 0) + + (empty($this->_toc) ? 0 : 100) + + ($this->_qualityIndicator !== false ? 4 : 0); + } +} diff --git a/src/Zend/Media/Mpeg/Exception.php b/src/Zend/Media/Mpeg/Exception.php new file mode 100644 index 0000000..236b27b --- /dev/null +++ b/src/Zend/Media/Mpeg/Exception.php @@ -0,0 +1,40 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +class Zend_Media_Mpeg_Exception extends Zend_Media_Exception +{} diff --git a/src/Zend/Media/Mpeg/Object.php b/src/Zend/Media/Mpeg/Object.php new file mode 100644 index 0000000..925c256 --- /dev/null +++ b/src/Zend/Media/Mpeg/Object.php @@ -0,0 +1,267 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +abstract class Zend_Media_Mpeg_Object +{ + /** + * The reader object. + * + * @var Reader + */ + protected $_reader; + + /** + * The options array. + * + * @var Array + */ + private $_options; + + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + $this->_reader = $reader; + $this->_options = &$options; + } + + /** + * Returns the options array. + * + * @return Array + */ + public final 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 final function getOption($option, $defaultValue = null) + { + if (isset($this->_options[$option])) { + return $this->_options[$option]; + } + return $defaultValue; + } + + /** + * Sets the options array. See main class for available options. + * + * @param Array $options The options array. + */ + public final 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 final function setOption($option, $value) + { + $this->_options[$option] = $value; + } + + /** + * Clears the given option value. + * + * @param string $option The name of the option. + */ + public final function clearOption($option) + { + unset($this->_options[$option]); + } + + /** + * Finds and returns the next start code. Start codes are reserved bit + * patterns in the video file that do not otherwise occur in the video stream. + * + * All start codes are byte aligned and start with the following byte + * sequence: 0x00 0x00 0x01. + * + * @return integer + */ + protected final function nextStartCode() + { + $buffer = ' '; + for ($i = 0; $i < 4; $i++) { + $start = $this->_reader->getOffset(); + if (($buffer = substr($buffer, -4) . + $this->_reader->read(512)) === false) { + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception('Invalid data'); + } + $limit = strlen($buffer); + $pos = 0; + while ($pos < $limit - 3) { + if (ord($buffer{$pos++}) == 0) { + list(, $int) = unpack('n*', substr($buffer, $pos, 2)); + if ($int == 1) { + if (($pos += 2) < $limit - 2) { + list(, $int) = + unpack('n*', substr($buffer, $pos, 2)); + if ($int == 0 && ord($buffer{$pos + 2}) == 1) { + continue; + } + } + $this->_reader->setOffset($start + $pos - 3); + return ord($buffer{$pos++}) & 0xff | 0x100; + } + } + } + $this->_reader->setOffset($start + $limit); + } + + /* No start code found within 2048 bytes, the maximum size of a pack */ + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception('Invalid data'); + } + + /** + * Finds and returns the previous start code. Start codes are reserved bit + * patterns in the video file that do not otherwise occur in the video + * stream. + * + * All start codes are byte aligned and start with the following byte + * sequence: 0x00 0x00 0x01. + * + * @return integer + */ + protected final function prevStartCode() + { + $buffer = ' '; + $start; + $position = $this->_reader->getOffset(); + while ($position > 0) { + $start = 0; + $position = $position - 512; + if ($position < 0) { + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception('Invalid data'); + } + $this->_reader->setOffset($position); + $buffer = $this->_reader->read(512) . substr($buffer, 0, 4); + $pos = 512 - 8; + while ($pos > 3) { + list(, $int) = unpack('n*', substr($buffer, $pos + 1, 2)); + if (ord($buffer{$pos}) == 0 && $int == 1) { + list(, $int) = unpack('n*', substr($buffer, $pos + 3, 2)); + if ($pos + 2 < 512 && $int == 0 && + ord($buffer{$pos + 5}) == 1) { + $pos--; + continue; + } + $this->_reader->setOffset($position + $pos); + return ord($buffer{$pos + 3}) & 0xff | 0x100; + } + $pos--; + } + $this->_reader->setOffset($position = $position + 3); + } + return 0; + } + + /** + * Formats given time in seconds into the form of + * [hours:]minutes:seconds.milliseconds. + * + * @param integer $seconds The time to format, in seconds + * @return string + */ + protected final function formatTime($seconds) + { + $milliseconds = round(($seconds - floor($seconds)) * 1000); + $seconds = floor($seconds); + $minutes = floor($seconds / 60); + $hours = floor($minutes / 60); + return + ($minutes > 0 ? + ($hours > 0 ? $hours . ':' . + str_pad($minutes % 60, 2, '0', STR_PAD_LEFT) : $minutes % 60) . + ':' . + str_pad($seconds % 60, 2, '0', STR_PAD_LEFT) : $seconds % 60) . + '.' . + str_pad($milliseconds, 3, '0', STR_PAD_LEFT); + } + + /** + * Magic function so that $obj->value will work. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (method_exists($this, 'get' . ucfirst($name))) { + return call_user_func(array($this, 'get' . ucfirst($name))); + } else { + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception('Unknown 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 { + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Media/Mpeg/Ps.php b/src/Zend/Media/Mpeg/Ps.php new file mode 100644 index 0000000..5e4e870 --- /dev/null +++ b/src/Zend/Media/Mpeg/Ps.php @@ -0,0 +1,152 @@ + + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @todo Full implementation + */ +final class Zend_Media_Mpeg_Ps extends Zend_Media_Mpeg_Object +{ + /** @var integer */ + private $_length; + + /** + * Constructs the class with given file and options. + * + * @param string|resource|Zend_Io_Reader $filename The path to the file, + * file descriptor of an opened file, or a {@link Zend_Io_Reader} instance. + * @param Array $options The options array. + */ + public function __construct($filename, $options = array()) + { + if ($filename instanceof Zend_Io_Reader) { + $this->_reader = &$filename; + } else { + require_once 'Zend/Io/FileReader.php'; + try { + $this->_reader = new Zend_Io_FileReader($filename); + } catch (Zend_Io_Exception $e) { + $this->_reader = null; + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception($e->getMessage()); + } + } + $this->setOptions($options); + + $startCode = 0; + $startTime = 0; + $pictureCount = 0; + $pictureRate = 0; + $rates = array ( 0, 23.976, 24, 25, 29.97, 30, 50, 59.94, 60 ); + $foundSeqHdr = false; + $foundGOP = false; + + do { + do { + $startCode = $this->nextStartCode(); + echo "STARTCODE: $startCode\n"; + } while ($startCode != 0x1b3 && $startCode != 0x1b8); + + if ($startCode == 0x1b3 /* sequence_header_code */ && + $pictureRate == 0) { + $i1 = $this->_reader->readUInt32BE(); + $i2 = $this->_reader->readUInt32BE(); + if (!Zend_Bit_Twiddling::testAllBits($i2, 0x2000)) { + throw new RuntimeException('Invalid mark'); + } + $pictureRate = $rates[Zend_Bit_Twiddling::getValue($i1, 4, 8)]; + $foundSeqHdr = true; + } + if ($startCode == 0x1b8 /* group_start_code */) { + $tmp = $this->_reader->readUInt32BE(); + $startTime = + (($tmp >> 26) & 0x1f) * 60 * 60 * 1000 /* hours */ + + (($tmp >> 20) & 0x3f) * 60 * 1000 /* minutes */ + + (($tmp >> 13) & 0x3f) * 1000 /* seconds */ + + (int)(1 / $pictureRate * (($tmp >> 7) & 0x3f) * 1000); + $foundGOP = true; + } + } while (!$foundSeqHdr || !$foundGOP); + + $this->_reader->setOffset($this->_reader->getSize()); + + do { + if (($startCode = $this->prevStartCode()) == 0x100) { + $pictureCount++; + } + } while ($startCode != 0x1b8); + + $this->_reader->skip(4); + $tmp = $this->_reader->readUInt32BE(); + $this->_length = + (((($tmp >> 26) & 0x1f) * 60 * 60 * 1000 /* hours */ + + (($tmp >> 20) & 0x3f) * 60 * 1000 /* minutes */ + + (($tmp >> 13) & 0x3f) * 1000 /* seconds */ + + (int)(1 / $pictureRate * (($tmp >> 7) & 0x3f) * 1000)) - + $startTime + + (int)(1 / $pictureRate * $pictureCount * 1000)) / 1000; + } + + /** + * Returns the exact playtime in seconds. + * + * @return integer + */ + public function getLength() + { + return $this->_length; + } + + /** + * Returns the exact playtime given in seconds as a string in the form of + * [hours:]minutes:seconds.milliseconds. + * + * @param integer $seconds The playtime in seconds. + * @return string + */ + public function getFormattedLength() + { + return $this->formatTime($this->getLength()); + } +} diff --git a/src/Zend/Mime/Magic.php b/src/Zend/Mime/Magic.php new file mode 100644 index 0000000..e09788e --- /dev/null +++ b/src/Zend/Mime/Magic.php @@ -0,0 +1,194 @@ +1 -- byte number to begin checking from. '>' indicates a dependency + * upon the previous non-'>' line + * o 2 -- type of data to match. Can be one of following + * - byte (single character) + * - short (machine-order 16-bit integer) + * - long (machine-order 32-bit integer) + * - string (arbitrary-length string) + * - date (long integer date (seconds since Unix epoch/1970)) + * - beshort (big-endian 16-bit integer) + * - belong (big-endian 32-bit integer) + * - bedate (big-endian 32-bit integer date) + * - leshort (little-endian 16-bit integer) + * - lelong (little-endian 32-bit integer) + * - ledate (little-endian 32-bit integer date) + * o 3 -- contents of data to match + * o 4 -- file description/MIME type if matched + * o 5 -- optional MIME encoding if matched and if above was a MIME type + * + * @category Zend + * @package Zend_Mime + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Mime_Magic +{ + /** @var string */ + private $_magic; + + /** + * Reads the magic information from given magic file. + * + * @param string $filename The path to the magic file. + */ + public function __construct($filename) + { + $reader = new Zend_Io_FileReader($filename); + $this->_magic = $reader->read($reader->getSize()); + } + + /** + * Returns the recognized MIME type/description of the given file. The type + * is determined by the content using magic bytes characteristic for the + * particular file type. + * + * If the type could not be found, the function returns the default value, + * or null. + * + * @param string $filename The file path whose type to determine. + * @param string $default The default value. + * @return string|false + */ + public function getMimeType($filename, $default = null) + { + $reader = new Zend_Io_FileReader($filename); + + $parentOffset = 0; + foreach (preg_split('/^/m', $this->_magic) as $line) { + $chunks = array(); + if (!preg_match("/^(?P>?)(?P\d+)\s+(?P\S+)\s+(?P\S+)(?:\s+(?P[a-" . + "z]+\/[a-z-0-9]+)?(?:\s+(?P.?+))?)?$/", + $line, $chunks)) { + continue; + } + + if ($chunks['Dependant']) { + $reader->setOffset($parentOffset); + $reader->skip($chunks['Byte']); + } else { + $reader->setOffset($parentOffset = $chunks['Byte']); + } + + $matchType = strtolower($chunks['MatchType']); + $matchData = preg_replace + (array("/\\\\ /", "/\\\\\\\\/", "/\\\\([0-7]{1,3})/e", + "/\\\\x([0-9A-Fa-f]{1,2})/e", "/0x([0-9A-Fa-f]+)/e"), + array(" ", "\\\\", + "pack(\"H*\", base_convert(\"$1\", 8, 16));", + "pack(\"H*\", \"$1\");", "hexdec(\"$1\");"), + $chunks["MatchData"]); + + switch ($matchType) { + case 'byte': // single character + $data = $reader->readInt8(); + break; + case 'short': // machine-order 16-bit integer + $data = $reader->readInt16(); + break; + case 'long': // machine-order 32-bit integer + $data = $reader->readInt32(); + break; + case 'string': // arbitrary-length string + $data = $reader->readString8(strlen($matchData)); + break; + case 'date': // long integer date (seconds since Unix epoch) + $data = $reader->readInt64BE(); + break; + case 'beshort': // big-endian 16-bit integer + $data = $reader->readUInt16BE(); + break; + case 'belong': // big-endian 32-bit integer + // break intentionally omitted + case 'bedate': // big-endian 32-bit integer date + $data = $reader->readUInt32BE(); + break; + case 'leshort': // little-endian 16-bit integer + $data = $reader->readUInt16LE(); + break; + case 'lelong': // little-endian 32-bit integer + // break intentionally omitted + case 'ledate': // little-endian 32-bit integer date + $data = $reader->readUInt32LE(); + break; + default: + $data = null; + break; + } + + if (strcmp($data, $matchData) == 0) { + if (!empty($chunks['MIMEType'])) { + return $chunks['MIMEType']; + } + if (!empty($chunks['Description'])) { + return rtrim($chunks['Description'], "\n"); + } + } + } + return $default; + } + + /** + * Returns the results of the mime type check either as a boolean or an + * array of boolean values. + * + * @param string|Array $filename The file path whose type to test. + * @param string|Array $mimeType The mime type to test against. + * @return boolean|Array + */ + public function isMimeType($filename, $mimeType) + { + if (is_array($filename)) { + $result = array(); + foreach ($filename as $key => $value) { + $result[] = + ($this->getMimeType($value) == + (is_array($mimeType) ? $mimeType[$key] : $mimeType)) ? + true : false; + } + return $result; + } else { + return $this->getMimeType($filename) == $mimeType ? true : false; + } + } +}