diff --git a/src/MPEG/Audio.php b/src/MPEG/Audio.php
index 7c92889..78bdb10 100644
--- a/src/MPEG/Audio.php
+++ b/src/MPEG/Audio.php
@@ -151,11 +151,13 @@ final class MPEG_Audio extends MPEG_Audio_Object
else
$this->_reader->setOffset($offset);
-
+ /* Check for VBR headers */
$offset = $this->_reader->getOffset();
- /* Check for VBR headers */
- $firstFrame = new MPEG_Audio_Frame($this->_reader, $options);
+ $this->_frames[] =
+ $firstFrame = new MPEG_Audio_Frame($this->_reader, $options);
+
+ $postoffset = $this->_reader->getOffset();
$this->_reader->setOffset
($offset + 4 + self::$sidesizes
@@ -168,15 +170,25 @@ final class MPEG_Audio extends MPEG_Audio_Object
$this->_lameHeader =
new MPEG_Audio_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/Audio/VBRIHeader.php");
$this->_vbriHeader = new MPEG_Audio_VBRIHeader($this->_reader, $options);
+
+ // A header frame is not counted as an audio frame
+ array_pop($this->_frames);
}
- $this->_reader->setOffset($offset);
+ $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") {
@@ -214,6 +226,54 @@ final class MPEG_Audio extends MPEG_Audio_Object
}
}
+ /**
+ * 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_Audio_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_Audio_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_Audio_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.
@@ -264,7 +324,7 @@ final class MPEG_Audio extends MPEG_Audio_Object
/**
* Returns the playtime estimate as a string in the form of
- * [hours]:minutes:seconds.milliseconds.
+ * [hours:]minutes:seconds.milliseconds.
*
* @param integer $seconds The playtime in seconds.
* @return string
@@ -276,7 +336,7 @@ final class MPEG_Audio extends MPEG_Audio_Object
/**
* 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
+ * [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.
*
@@ -323,7 +383,7 @@ final class MPEG_Audio extends MPEG_Audio_Object
$this->_cumulativeBitrate += $frame->getBitrate();
$this->_frames[] = $frame;
- if ($limit !== false && $i == $limit) {
+ if ($limit !== false && ($i + 1) == $limit) {
$this->_lastFrameOffset = $this->_reader->getOffset();
break;
}
diff --git a/src/MPEG/Object.php b/src/MPEG/Object.php
index 86968ce..d1f8274 100644
--- a/src/MPEG/Object.php
+++ b/src/MPEG/Object.php
@@ -197,7 +197,7 @@ abstract class MPEG_Object
/**
* Formats given time in seconds into the form of
- * [hours]:minutes:seconds.milliseconds.
+ * [hours:]minutes:seconds.milliseconds.
*
* @param integer $seconds The time to format, in seconds
* @return string
diff --git a/src/MPEG/PS.php b/src/MPEG/PS.php
index f954b5a..a53e8e7 100644
--- a/src/MPEG/PS.php
+++ b/src/MPEG/PS.php
@@ -42,7 +42,8 @@ require_once("MPEG/Object.php");
/**
* This class represents a MPEG Program Stream encoded file as described in
- * ISO/IEC 13818-1 Systems standard.
+ * MPEG-1 Systems (ISO/IEC 11172-1) and MPEG-2 Systems (ISO/IEC 13818-1)
+ * standards.
*
* The Program Stream is a stream definition which is tailored for communicating
* or storing one program of coded data and other data in environments where
@@ -65,7 +66,7 @@ final class MPEG_PS extends MPEG_Object
private $_length;
/**
- * Constructs the MPEG_ProgramStream class with given file and options.
+ * 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.
@@ -133,7 +134,7 @@ final class MPEG_PS extends MPEG_Object
/**
* Returns the exact playtime given in seconds as a string in the form of
- * [hours]:minutes:seconds.milliseconds.
+ * [hours:]minutes:seconds.milliseconds.
*
* @param integer $seconds The playtime in seconds.
* @return string