diff --git a/src/Zend/Media/Mpeg/Abs.php b/src/Zend/Media/Mpeg/Abs.php index 31e1d70..f9fba0e 100644 --- a/src/Zend/Media/Mpeg/Abs.php +++ b/src/Zend/Media/Mpeg/Abs.php @@ -42,7 +42,7 @@ require_once 'Zend/Media/Mpeg/Abs/Frame.php'; * @subpackage MPEG * @author Ryan Butterfield * @author Sven Vollbehr - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2012 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 @@ -181,15 +181,13 @@ final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object } /* Check for VBR headers */ - $offset = $this->_reader->getOffset(); - $this->_frames[] = $firstFrame = new Zend_Media_Mpeg_Abs_Frame($this->_reader, $options); - $postoffset = $this->_reader->getOffset(); + $offset = $this->_reader->getOffset(); $this->_reader->setOffset - ($offset + 4 + self::$sidesizes + ($firstFrame->getOffset() + 4 + self::$sidesizes [$firstFrame->getFrequencyType()][$firstFrame->getMode()]); if (($xing = $this->_reader->readString8(4)) == 'Xing' || $xing == 'Info') { @@ -207,7 +205,7 @@ final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object array_pop($this->_frames); } - $this->_reader->setOffset($offset + 4 + 32); + $this->_reader->setOffset($firstFrame->getOffset() + 4 + 32); if ($this->_reader->readString8(4) == 'VBRI') { require_once 'Zend/Media/Mpeg/Abs/VbriHeader.php'; $this->_vbriHeader = @@ -217,7 +215,7 @@ final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object array_pop($this->_frames); } - $this->_reader->setOffset($postoffset); + $this->_reader->setOffset($offset); // Ensure we always have read at least one frame if (empty($this->_frames)) { @@ -242,7 +240,7 @@ final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object $firstFrame->getSamplingFrequency()) / 1000 * 8); } } else { - $this->_estimatedBitrate = ($this->_bytes - $offset) / + $this->_estimatedBitrate = ($this->_bytes - $firstFrame->getOffset()) / $this->_estimatedPlayDuration / 1000 * 8; } } else { @@ -251,7 +249,7 @@ final class Zend_Media_Mpeg_Abs extends Zend_Media_Mpeg_Abs_Object $this->_estimatedBitrate = $this->_cumulativeBitrate / count($this->_frames); $this->_estimatedPlayDuration = - ($this->_bytes - $offset) / + ($this->_bytes - $firstFrame->getOffset()) / ($this->_estimatedBitrate * 1000 / 8); } } else { diff --git a/src/Zend/Media/Mpeg/Abs/Frame.php b/src/Zend/Media/Mpeg/Abs/Frame.php index bb05552..804e917 100644 --- a/src/Zend/Media/Mpeg/Abs/Frame.php +++ b/src/Zend/Media/Mpeg/Abs/Frame.php @@ -38,7 +38,7 @@ require_once 'Zend/Media/Mpeg/Abs/Object.php'; * @subpackage MPEG * @author Ryan Butterfield * @author Sven Vollbehr - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License * @version $Id$ */ @@ -228,13 +228,21 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object parent::__construct($reader, $options); $this->_offset = $this->_reader->getOffset(); - - $header = $this->_reader->readUInt32BE(); - if (!Zend_Bit_Twiddling::testAllBits(Zend_Bit_Twiddling::getValue($header, 21, 32), 0xffe)) { - require_once 'Zend/Media/Mpeg/Exception.php'; - throw new Zend_Media_Mpeg_Exception - ('File does not contain a valid MPEG Audio Bit Stream (Invalid frame sync)'); + + $header = null; + for ($i = 0; $i < 5775 /* max attempts: max frame size x2 */; $i++) { + $header = $this->_reader->readUInt32BE(); + if (Zend_Bit_Twiddling::testAllBits(Zend_Bit_Twiddling::getValue($header, 21, 32), 0xffe)) { + break; + } + $this->_reader->setOffset(++$this->_offset + 1); + if ($this->_offset == $this->_reader->getSize() || $i == (5775 - 1)) { + require_once 'Zend/Media/Mpeg/Exception.php'; + throw new Zend_Media_Mpeg_Exception + ('File does not contain a valid MPEG Audio Bit Stream (Invalid frame sync and resynchronization failed)'); + } } + $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); @@ -268,15 +276,26 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object $this->_reader->skip($this->_length - 4); } + /** + * Returns the offset where the frame actually begins (stream error may + * cause resynchronization). + * + * @return integer + */ + public function getOffset() + { + return $this->_offset; + } + /** * Returns the version identifier of the algorithm. * * @see VERSION_ONE, VERSION_TWO, VERSION_TWO_FIVE * @return integer */ - public function getVersion() + public function getVersion() { - return $this->_version; + return $this->_version; } /** @@ -291,9 +310,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see SAMPLING_FREQUENCY_LOW, SAMPLING_FREQUENCY_HIGH * @return integer */ - public function getFrequencyType() + public function getFrequencyType() { - return $this->_frequencyType; + return $this->_frequencyType; } /** @@ -302,9 +321,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see LAYER_ONE, LAYER_TWO, LAYER_THREE * @return integer */ - public function getLayer() + public function getLayer() { - return $this->_layer; + return $this->_layer; } /** @@ -313,9 +332,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see getRedundancy * @return boolean */ - public function hasRedundancy() + public function hasRedundancy() { - return $this->getRedundancy(); + return $this->getRedundancy(); } /** @@ -326,9 +345,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return boolean */ - public function getRedundancy() + public function getRedundancy() { - return $this->_redundancy; + return $this->_redundancy; } /** @@ -338,9 +357,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return integer */ - public function getBitrate() + public function getBitrate() { - return $this->_bitrate; + return $this->_bitrate; } /** @@ -348,9 +367,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return integer */ - public function getSamplingFrequency() + public function getSamplingFrequency() { - return $this->_samplingFrequency; + return $this->_samplingFrequency; } /** @@ -359,9 +378,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see getPadding * @return boolean */ - public function hasPadding() + public function hasPadding() { - return $this->getPadding(); + return $this->getPadding(); } /** @@ -373,9 +392,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return boolean */ - public function getPadding() + public function getPadding() { - return $this->_padding; + return $this->_padding; } /** @@ -386,9 +405,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * CHANNEL_SINGLE_CHANNEL * @return integer */ - public function getMode() + public function getMode() { - return $this->_mode; + return $this->_mode; } /** @@ -414,9 +433,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return integer */ - public function getModeExtension() + public function getModeExtension() { - return $this->_modeExtension; + return $this->_modeExtension; } /** @@ -425,9 +444,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see getCopyright * @return boolean */ - public function hasCopyright() + public function hasCopyright() { - return $this->getCopyright(); + return $this->getCopyright(); } /** @@ -436,9 +455,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return boolean */ - public function getCopyright() + public function getCopyright() { - return $this->_copyright; + return $this->_copyright; } /** @@ -447,9 +466,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see getOriginal * @return boolean */ - public function isOriginal() + public function isOriginal() { - return $this->getOriginal(); + return $this->getOriginal(); } /** @@ -457,9 +476,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return boolean */ - public function getOriginal() + public function getOriginal() { - return $this->_original; + return $this->_original; } /** @@ -473,9 +492,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * @see EMPHASIS_NONE, EMPHASIS_50_15, EMPHASIS_CCIT_J17 * @return integer */ - public function getEmphasis() + public function getEmphasis() { - return $this->_emphasis; + return $this->_emphasis; } /** @@ -484,9 +503,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return integer */ - public function getLength() + public function getLength() { - return $this->_length; + return $this->_length; } /** @@ -494,9 +513,9 @@ final class Zend_Media_Mpeg_Abs_Frame extends Zend_Media_Mpeg_Abs_Object * * @return integer */ - public function getSamples() + public function getSamples() { - return $this->_samples; + return $this->_samples; } /**