diff --git a/src/ASF.php b/src/ASF.php new file mode 100644 index 0000000..75df1cb --- /dev/null +++ b/src/ASF.php @@ -0,0 +1,119 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +class ASF +{ + /** @var Reader The Reader object */ + private $_reader; + + /** + * The default constructor. Initiates the reader for the given file. + */ + public function __construct($filename) + { + $this->_reader = new Reader($filename); + } + + /** + * Checks whether the reader was successfully initiated and whether there are + * objects left in the stream. + * + * @return Boolean value corresponding whether there is more to read. + */ + public function hasObjects() + { + return $this->_reader->available(); + } + + /** + * Returns the next ASF object or false if end of stream has been reached. + * + * @todo Only the ASF_Header_Object top level object is regognized. + * @return ASFObject Returns the appropriate object. Returned objects are of + * the type ASFObject or of any of the other object types that inherit + * from that base class. + */ + public function nextObject() + { + $object = false; + if ($this->hasObjects()) { + $guid = $this->_reader->getGUID(); + $size = $this->_reader->getInt64LE(); + $offset = $this->_reader->getOffset(); + + switch ($guid) { + case "75b22630-668e-11cf-a6d9-00aa0062ce6c": /* ASF_Header_Object */ + $object = new ASF_HeaderObject($this->_reader, $guid, $size); + break; + default: + $object = new ASF_Object($this->_reader, $guid, $size); + } + + $this->_reader->setOffset($offset - 24 + $size); + } + return $object; + } +} diff --git a/src/ASF/ContentDescriptionObject.php b/src/ASF/ContentDescriptionObject.php new file mode 100644 index 0000000..e0b8aa0 --- /dev/null +++ b/src/ASF/ContentDescriptionObject.php @@ -0,0 +1,134 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ASF_ContentDescriptionObject extends ASF_Object +{ + /** + * @var string The title field. + */ + private $_title; + + /** + * @var string The author field. + */ + private $_author; + + /** + * @var string The copyright field. + */ + private $_copyright; + + /** + * @var string The description field. + */ + private $_description; + + /** + * @var string The rating field. + */ + private $_rating; + + /** + * Default constructor. Initiates the class with given parameters and reads + * object related data from the ASF file. + */ + public function __construct($reader, $id, $size) + { + parent::__construct($reader, $id, $size); + + $titleLen = $this->_reader->getUInt16LE(); + $authorLen = $this->_reader->getUInt16LE(); + $copyrightLen = $this->_reader->getUInt16LE(); + $descriptionLen = $this->_reader->getUInt16LE(); + $ratingLen = $this->_reader->getUInt16LE(); + + $this->_title = $this->_reader->getString16LE($titleLen); + $this->_author = $this->_reader->getString16LE($authorLen); + $this->_copyright = $this->_reader->getString16LE($copyrightLen); + $this->_description = $this->_reader->getString16LE($descriptionLen); + $this->_rating = $this->_reader->getString16LE($ratingLen); + } + + /** + * Returns the title field. + * + * @return string Returns the title field. + */ + public function getTitle() { return $this->_title; } + + /** + * Returns the author field. + * + * @return string Returns the author field. + */ + public function getAuthor() { return $this->_author; } + + /** + * Returns the copyright field. + * + * @return string Returns the copyright field. + */ + public function getCopyright() { return $this->_copyright; } + + /** + * Returns the description field. + * + * @return string Returns the description field. + */ + public function getDescription() { return $this->_description; } + + /** + * Returns the rating field. + * + * @return string Returns the rating field. + */ + public function getRating() { return $this->_rating; } +} diff --git a/src/ASF/ExtendedContentDescriptionObject.php b/src/ASF/ExtendedContentDescriptionObject.php new file mode 100644 index 0000000..d126dcd --- /dev/null +++ b/src/ASF/ExtendedContentDescriptionObject.php @@ -0,0 +1,107 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ASF_ExtendedContentDescriptionObject extends ASF_Object +{ + /** + * @var Array An associate array of descriptors and their values. + */ + private $_contentDescriptors = array(); + + /** + * Initiates the object class with given parameters and reads and processes + * the object information from the ASF file. + */ + public function __construct($reader, $id, $size) + { + parent::__construct($reader, $id, $size); + + $contentDescriptorsCount = $this->_reader->getUInt16LE(); + for ($i = 0; $i < $contentDescriptorsCount; $i++) { + $nameLen = $this->_reader->getUInt16LE(); + $name = $this->_reader->getString16LE($nameLen); + $valueDataType = $this->_reader->getUInt16LE(); + $valueLen = $this->_reader->getUInt16LE(); + switch ($valueDataType) { + case 0: + case 1: // string + $this->_contentDescriptors[$name] = + $this->_reader->getString16LE($valueLen); + break; + case 2: // bool + case 3: // 32-bit integer + $this->_contentDescriptors[$name] = $this->_reader->getUInt32LE(); + break; + case 4: // 64-bit integer + $this->_contentDescriptors[$name] = $this->_reader->getInt64LE(); + break; + case 5: // 16-bit integer + $this->_contentDescriptors[$name] = $this->_reader->getUInt16LE(); + 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 Returns the value of a descriptor. + */ + public function getDescriptor($name) + { + if (isset($this->_contentDescriptors[$name])) + return $this->_contentDescriptors[$name]; + return false; + } +} diff --git a/src/ASF/FilePropertiesObject.php b/src/ASF/FilePropertiesObject.php new file mode 100644 index 0000000..0c3007f --- /dev/null +++ b/src/ASF/FilePropertiesObject.php @@ -0,0 +1,231 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ASF_FilePropertiesObject extends ASF_Object +{ + /** + * @var string The file id field. + */ + private $_fileId; + + /** + * @var string The file size field. + */ + private $_fileSize; + + /** + * @var string The creation date field. + */ + private $_creationDate; + + /** + * @var string The data packets count field. + */ + private $_dataPacketsCount; + + /** + * @var string The play duration field. + */ + private $_playDuration; + + /** + * @var string The send duration field. + */ + private $_sendDuration; + + /** + * @var string The preroll field. + */ + private $_preroll; + + /** + * @var string The flags field. + */ + private $_flags; + + /** + * @var string The minimum data packet size field. + */ + private $_minimumDataPacketSize; + + /** + * @var string The maximum data packet size field. + */ + private $_maximumDataPacketSize; + + /** + * @var string The maximum bitrate field. + */ + private $_maximumBitrate; + + /** + * Initiates the object class with given parameters and reads and processes + * the object information from the ASF file. + */ + public function __construct($reader, $id, $size) + { + parent::__construct($reader, $id, $size); + + $this->_fileId = $this->_reader->getGUID(); + $this->_fileSize = $this->_reader->getInt64LE(); + $this->_creationDate = $this->_reader->getInt64LE(); + $this->_dataPacketsCount = $this->_reader->getInt64LE(); + + $seconds = floor($this->_reader->getInt64LE() / 10000000); + $minutes = floor($seconds / 60); + $hours = floor($minutes / 60); + $this->_playDuration = + ($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); + + $seconds = floor($this->_reader->getInt64LE() / 10000000); + $minutes = floor($seconds / 60); + $hours = floor($minutes / 60); + $this->_sendDuration = + ($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); + + $this->_preroll = $this->_reader->getInt64LE(); + $this->_flags = $this->_reader->getUInt32LE(); + $this->_minimumDataPacketSize = $this->_reader->getUInt32LE(); + $this->_maximumDataPacketSize = $this->_reader->getUInt32LE(); + $this->_maximumBitrate = $this->_reader->getUInt32LE(); + } + + /** + * Returns the file id field. + * + * @return integer Returns the file id field. + */ + public function getFileId() { return $this->_fileId; } + + /** + * Returns the file size field. + * + * @return integer Returns the file size field. + */ + public function getFileSize() { return $this->_fileSize; } + + /** + * Returns the creation date field. + * + * @return integer Returns the creation date field. + */ + public function getCreationDate() { return $this->_creationDate; } + + /** + * Returns the data packets field. + * + * @return integer Returns the data packets field. + */ + public function getDataPacketsCount() { return $this->_dataPacketsCount; } + + /** + * Returns the play duration field. + * + * @return integer Returns the play duration field. + */ + public function getPlayDuration() { return $this->_playDuration; } + + /** + * Returns the send duration field. + * + * @return integer Returns the send duration field. + */ + public function getSendDuration() { return $this->_sendDuration; } + + /** + * Returns the preroll field. + * + * @return integer Returns the preroll field. + */ + public function getPreroll() { return $this->_preroll; } + + /** + * Returns the flags field. + * + * @return integer Returns the flags field. + */ + public function getFlags() { return $this->_flags; } + + /** + * Returns the minimum data packet size field. + * + * @return integer Returns the minimum data packet size field. + */ + public function getMinimumDataPacketSize() + { + return $this->_minimumDataPacketSize; + } + + /** + * Returns the maximum data packet size field. + * + * @return integer Returns the maximum data packet size field. + */ + public function getMaximumDataPacketSize() + { + return $this->_maximumDataPacketSize; + } + + /** + * Returns the maximum bitrate field. + * + * @return integer Returns the maximum bitrate field. + */ + public function getMaximumBitrate() + { + return $this->_maximumBitrate; + } +} diff --git a/src/ASF/HeaderObject.php b/src/ASF/HeaderObject.php new file mode 100644 index 0000000..433fd0a --- /dev/null +++ b/src/ASF/HeaderObject.php @@ -0,0 +1,147 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +final class ASF_HeaderObject extends ASF_Object +{ + /** + * @var integer The number of the objects the header contains. + */ + private $_objectCount; + + /** + * @var integer Internal variable to have the start of the stream stored in. + */ + private $_readerSOffset; + + /** + * @var integer Internal variable to have the current position of the + * stream pointer stored in. + */ + private $_readerCOffset; + + /** + * Default constructor. Initiates the class with given parameters and reads + * object information from the file. + */ + public function __construct($reader, $id, $size) + { + parent::__construct($reader, $id, $size); + + $this->_readerSOffset = $this->_reader->getOffset(); + $this->_objectCount = $this->_reader->getUInt32LE(); + $this->_reader->skip(2); + $this->_readerCOffset = $this->_reader->getOffset(); + } + + /** + * Returns the number of standard ASF header objects this object contains. + * + * @return integer The number of objects the header contains. + */ + public function getObjectCount() { return $this->_objectCount; } + + /** + * Checks whether there is more to be read within the bounds of the parent + * object size. + * + * @return boolean Boolean value corresponding whether there is more to read. + */ + public function hasChildObjects() + { + return ($this->_readerSOffset + $this->_size) > $this->_readerCOffset; + } + + /** + * Returns the next standard ASF object or false if end of stream + * has been reached. + * + * @todo Only limited subset of possible child objects are regognized. + * @return ASF_Object Returns the appropriate object. Returned objects are of + * the type ASFObject or of any of the other object types that inherit + * from that base class. + */ + public function nextChildObject() + { + $object = false; + if ($this->hasChildObjects()) { + $this->_reader->setOffset($this->_readerCOffset); + $guid = $this->_reader->getGUID(); + $size = $this->_reader->getInt64LE(); + $offset = $this->_reader->getOffset(); + switch ($guid) { + /* ASF_Content_Description_Object */ + case "75b22633-668e-11cf-a6d9-00aa0062ce6c": + $object = + new ASF_ContentDescriptionObject($this->_reader, $guid, $size); + break; + /* ASF_Header_Extension_Object */ + case "5fbf03b5-a92e-11cf-8ee3-00c00c205365": + $this->_reader->skip(48); + $this->_readerCOffset = $this->_reader->getOffset(); + $object = $this->nextChildObject(); + break; + /* ASF_Extended_Content_Description_Object */ + case "d2d0a440-e307-11d2-97f0-00a0c95ea850": + $object = new ASF_ExtendedContentDescriptionObject + ($this->_reader, $guid, $size); + break; + /* ASF_File_Properties_Object */ + case "8cabdca1-a947-11cf-8ee4-00c00c205365": + $object = new ASF_FilePropertiesObject($this->_reader, $guid, $size); + break; + default: // not implemented + $object = new ASF_Object($this->_reader, $guid, $size); + } + $this->_reader->setOffset(($this->_readerCOffset = $offset - 24 + $size)); + } + return $object; + } +} diff --git a/src/ASF/Object.php b/src/ASF/Object.php new file mode 100644 index 0000000..8e69d4a --- /dev/null +++ b/src/ASF/Object.php @@ -0,0 +1,79 @@ + + * @copyright 2006, 2007 The Bearpaw Project Work Group + * @copyright 2007, 2008 BEHR Software Systems + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version $Rev$ + */ +class ASF_Object +{ + /** + * @var Reader The reader associated with this object. + */ + protected $_reader; + + /** + * @var string Object's ID + */ + private $_id; + + /** + * @var integer Object size in bytes. + */ + protected $_size; + + /** + * Constructs the object with the given parameters. + */ + public function __construct($reader, $id, $size) + { + $this->_reader = $reader; + $this->_id = $id; + $this->_size = $size; + } + + /** + * Returns the GUID of the ASF object. + * + * @return string Returns the GUID of the ASF object. + */ + public function getID() { return $this->_id; } +}