diff --git a/src/Zend/Media/Ogg/Reader.php b/src/Zend/Media/Ogg/Reader.php index e1bf5ed..2d050fc 100644 --- a/src/Zend/Media/Ogg/Reader.php +++ b/src/Zend/Media/Ogg/Reader.php @@ -39,6 +39,7 @@ require_once 'Zend/Media/Ogg/Page.php'; * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id$ + * @todo Currently supports only one logical bitstream */ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader { @@ -51,9 +52,6 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader /** @var integer */ private $_currentPagePosition = 0; - /** @var integer */ - private $_streamSize = 0; - /** * Constructs the Ogg class with given file. * @@ -70,7 +68,7 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader 'page' => $page = new Zend_Media_Ogg_Page($reader), 'offset' => $reader->getOffset() ); - $this->_streamSize += $page->getPageSize(); + $this->_size += $page->getPageSize(); $reader->skip($page->getPageSize()); } $reader->setOffset($this->_pages[$this->_currentPage]['offset']); @@ -113,17 +111,6 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader } } - /** - * Overwrite the method to return the Ogg bitstream size in bytes. - * - * @return integer - */ - public function getSize() - { - echo "getSize\n"; - return $this->_streamSize; - } - /** * Overwrite the method to jump size amount of bytes in the Ogg bitstream. * diff --git a/src/Zend/Media/Vorbis.php b/src/Zend/Media/Vorbis.php new file mode 100644 index 0000000..28aa779 --- /dev/null +++ b/src/Zend/Media/Vorbis.php @@ -0,0 +1,143 @@ + + * @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + * @todo Setup header is not yet supported + */ +final class Zend_Media_Vorbis +{ + /** @var Zend_Io_Reader */ + private $_reader; + + /** @var string */ + private $_filename = null; + + /** @var Zend_Media_Vorbis_Header_Identification */ + private $_identificationHeader; + + /** @var Zend_Media_Vorbis_Header_Comment */ + private $_commentHeader; + +// /** @var Zend_Media_Vorbis_Header_Setup */ +// private $_setupHeader; + + /** + * Constructs the . + * + * @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_Io_Exception if an error occur in stream handling. + * @throws Zend_Media_Vorbis_Exception if an error occurs in vorbis bitstream reading. + */ + public function __construct($filename) + { + 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/Vorbis/Exception.php'; + throw new Zend_Media_Vorbis_Exception($e->getMessage()); + } + } + + $this->_identificationHeader = new Zend_Media_Vorbis_Header_Identification($this->_reader); + $this->_commentHeader = new Zend_Media_Vorbis_Header_Comment($this->_reader); +// $this->_setupHeader = new Zend_Media_Vorbis_Header_Setup($this->_reader); + } + + /** + * Returns the identification header. + * + * @return Zend_Media_Vorbis_Header_Identification + */ + public function getIdentificationHeader() + { + return $this->_identificationHeader; + } + + /** + * Returns the comment header. + * + * @return Zend_Media_Vorbis_Header_Comment + */ + public function getCommentHeader() + { + return $this->_commentHeader; + } + + /** + * Returns the setup header. + * + * @return Zend_Media_Vorbis_Header_Setup + */ + public function getSetupHeader() + { + require_once 'Zend/Media/Vorbis/Exception.php'; + throw new Zend_Media_Vorbis_Exception('Not yet supported'); +// return $this->_setupHeader; + } + + /** + * 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/Vorbis/Exception.php'); + throw new Zend_Media_Vorbis_Exception('Unknown field: ' . $name); + } + } +} diff --git a/src/Zend/Media/Vorbis/Header.php b/src/Zend/Media/Vorbis/Header.php index fd385fd..b07c9bf 100644 --- a/src/Zend/Media/Vorbis/Header.php +++ b/src/Zend/Media/Vorbis/Header.php @@ -46,13 +46,6 @@ abstract class Zend_Media_Vorbis_Header */ protected $_reader; - /** - * The options array. - * - * @var Array - */ - private $_options; - /** * The packet type; the identication header is type 1, the comment header type 3 and the setup header type 5. * @@ -66,10 +59,9 @@ abstract class Zend_Media_Vorbis_Header * @param Zend_Io_Reader $reader The reader object. * @param Array $options The options array. */ - public function __construct($reader, &$options = array()) + public function __construct($reader) { $this->_reader = $reader; - $this->_options = &$options; if (!in_array($this->_packetType = $this->_reader->readUInt8(), array(1, 3, 5))) { require_once 'Zend/Media/Vorbis/Exception.php'; @@ -81,62 +73,6 @@ abstract class Zend_Media_Vorbis_Header } } - /** - * 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]); - } - /** * Magic function so that $obj->value will work. * @@ -152,22 +88,4 @@ abstract class Zend_Media_Vorbis_Header throw new Zend_Media_Vorbis_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/Vorbis/Exception.php'; - throw new Zend_Media_Vorbis_Exception('Unknown field: ' . $name); - } - } } diff --git a/src/Zend/Media/Vorbis/Header/Comment.php b/src/Zend/Media/Vorbis/Header/Comment.php new file mode 100644 index 0000000..75aa16a --- /dev/null +++ b/src/Zend/Media/Vorbis/Header/Comment.php @@ -0,0 +1,139 @@ + + * @copyright Copyright (c) 2005-2011 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_Vorbis_Header_Comment extends Zend_Media_Vorbis_Header +{ + /** @var string */ + private $_vendor; + + /** @var Array */ + private $_comments; + + /** @var integer */ + private $_framingFlag; + + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_vendor = $this->_reader->read($this->_reader->readUInt32LE()); + $userCommentListLength = $this->_reader->readUInt32LE(); + for ($i = 0; $i < $userCommentListLength; $i++) { + list ($name, $value) = preg_split('/=/', $this->_reader->read($this->_reader->readUInt32LE()), 2); + if (!isset($this->_comments[strtoupper($name)])) { + $this->_comments[strtoupper($name)] = array(); + } + $this->_comments[strtoupper($name)][] = $value; + } + $this->_framingFlag = $this->_reader->readUInt8() & 0x1; + if ($this->_framingFlag == 0) { + require_once 'Zend/Media/Vorbis/Exception.php'; + throw new Zend_Media_Vorbis_Exception('Undecodable Vorbis stream'); + } + } + + /** + * Returns an array of comments having the field names as keys and an array of values as a value. + * + * @return Array + */ + public function getComments() + { + return $this->_comments; + } + + /** + * Magic function so that $obj->value will work. The method will attempt to return the first field by the given + * name from the comment. If there is no field with given name, functionality of the parent method is executed. + * + * @param string $name The field name. + * @return mixed + */ + public function __get($name) + { + if (!empty($this->_comments[strtoupper($name)])) { + return $this->_comments[strtoupper($name)][0]; + } + parent::__get($name); + } + + /** + * Magic function so that isset($obj->value) will work. This method checks whether the comment contains a field by + * the given name. + * + * @param string $name The field name. + * @return boolean + */ + public function __isset($name) + { + return empty($this->_comments[strtoupper($name)]); + } + + /** + * Magic function so that unset($obj->value) will work. This method removes all the comments matching the field + * name. + * + * @param string $name The field name. + */ + public function __unset($name) + { + unset($this->_comments[strtoupper($name)]); + } +} diff --git a/src/Zend/Media/Vorbis/Header/Identification.php b/src/Zend/Media/Vorbis/Header/Identification.php new file mode 100644 index 0000000..8a13aa1 --- /dev/null +++ b/src/Zend/Media/Vorbis/Header/Identification.php @@ -0,0 +1,170 @@ + + * @copyright Copyright (c) 2005-2011 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_Vorbis_Header_Identification extends Zend_Media_Vorbis_Header +{ + /** @var integer */ + private $_vorbisVersion; + + /** @var integer */ + private $_audioChannels; + + /** @var integer */ + private $_audioSampleRate; + + /** @var integer */ + private $_bitrateMaximum; + + /** @var integer */ + private $_bitrateNominal; + + /** @var integer */ + private $_bitrateMinimum; + + /** @var integer */ + private $_blocksize0; + + /** @var integer */ + private $_blocksize1; + + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + */ + public function __construct($reader) + { + parent::__construct($reader); + + $this->_vorbisVersion = $this->_reader->readUInt32LE(); + $this->_audioChannels = $this->_reader->readUInt8(); + $this->_audioSampleRate = $this->_reader->readUInt32LE(); + $this->_bitrateMaximum = $this->_reader->readInt32LE(); + $this->_bitrateNominal = $this->_reader->readInt32LE(); + $this->_bitrateMinimum = $this->_reader->readInt32LE(); + $this->_blocksize0 = pow(2, ($tmp = $this->_reader->readUInt8()) & 0xf); + $this->_blocksize1 = pow(2, ($tmp >> 4) & 0xf); + $framingFlag = $this->_reader->readUInt8() & 0x1; + if ($this->_blocksize0 > $this->_blocksize1 || $framingFlag == 0) { + require_once 'Zend/Media/Vorbis/Exception.php'; + throw new Zend_Media_Vorbis_Exception('Undecodable Vorbis stream'); + } + } + + /** + * Returns the vorbis version. + * + * @return integer + */ + public function getVorbisVersion() + { + return $this->_vorbisVersion; + } + + /** + * Returns the number of audio channels. + * + * @return integer + */ + public function getAudioChannels() + { + return $this->_audioChannels; + } + + /** + * Returns the audio sample rate. + * + * @return integer + */ + public function getAudioSampleRate() + { + return $this->_audioSampleRate; + } + + /** + * Returns the maximum bitrate. + * + * @return integer + */ + public function getBitrateMaximum() + { + return $this->_bitrateMaximum; + } + + /** + * Returns the nominal bitrate. + * + * @return integer + */ + public function getBitrateNominal() + { + return $this->_bitrateNominal; + } + + /** + * Returns the minimum bitrate. + * + * @return integer + */ + public function getBitrateMinimum() + { + return $this->_bitrateMinimum; + } + + /** + * Returns the first block size. Allowed final blocksize values are 64, 128, 256, 512, 1024, 2048, 4096 and 8192 in + * Vorbis I. + * + * @return integer + */ + public function getBlocksize1() + { + return $this->_blocksize1; + } + + /** + * Returns the second block size. Allowed final blocksize values are 64, 128, 256, 512, 1024, 2048, 4096 and 8192 in + * Vorbis I. + * + * @return integer + */ + public function getBlocksize2() + { + return $this->_blocksize2; + } +}