Пример #1
0
 public function analyze()
 {
     /**
      * Overall tag structure:
      *        +-----------------------------+
      *        |      Header (10 bytes)      |
      *        +-----------------------------+
      *        |       Extended Header       |
      *        | (variable length, OPTIONAL) |
      *        +-----------------------------+
      *        |   Frames (variable length)  |
      *        +-----------------------------+
      *        |           Padding           |
      *        | (variable length, OPTIONAL) |
      *        +-----------------------------+
      *        | Footer (10 bytes, OPTIONAL) |
      *        +-----------------------------+
      *
      *    Header
      *        ID3v2/file identifier      "ID3"
      *        ID3v2 version              $04 00
      *        ID3v2 flags                (%ab000000 in v2.2, %abc00000 in v2.3, %abcd0000 in v2.4.x)
      *        ID3v2 size                 4 * %0xxxxxxx
      */
     //$fp = $this->_id3->getFilePointer();
     $this->_tagInfo = $this->_id3->getFileInfo();
     $this->_tagInfo['id3v2']['flags'] = array();
     $this->fseek($this->_startingOffset, SEEK_SET);
     $header = $this->fread(10);
     if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) {
         $this->_tagInfo['id3v2']['majorversion'] = ord($header[3]);
         $this->_tagInfo['id3v2']['minorversion'] = ord($header[4]);
         $this->_tagMajorVersion = $this->_tagInfo['id3v2']['majorversion'];
     } else {
         return false;
     }
     /**
      * The current max major version is 4 so that's what we support up to.
      */
     if ($this->_tagMajorVersion > 4) {
         include_once 'Zend/Id3/Adapter/Exception.php';
         throw new Zend_Id3_Adapter_Exception('Zend_Id3_Adapter_Id3v2 can only parse upt to Id3v2.4');
     }
     $this->_tagInfo['id3v2']['flags'] = $this->_processTagFlags(ord($header[5]));
     // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length
     $this->_tagInfo['id3v2']['headerlength'] = Zend_Id3_ByteConvert::bigEndianSyncSafe2Int(substr($header, 6, 4)) + 10;
     $this->_tagInfo['id3v2']['tag_offset_start'] = $this->_startingOffset;
     $this->_tagInfo['id3v2']['tag_offset_end'] = $this->_tagInfo['id3v2']['tag_offset_start'] + $this->_tagInfo['id3v2']['headerlength'];
     $this->_parseFrameData();
     $this->_id3->setFileInfo($this->_tagInfo);
     return true;
 }
Пример #2
0
 /**
  * Parse frame out from v2.3 and higher tags
  *
  * Frame ID  $xx xx xx xx (four characters)
  * Size      $xx xx xx xx (32-bit integer in v2.3, 28-bit synchsafe in v2.4+)
  * Flags     $xx xx
  *
  * @param string $frameData
  */
 protected function _getFrame($frameData)
 {
     $info = array();
     // take next 10 bytes for header
     $info['frameHeader'] = substr($frameData, 0, 10);
     // and leave the rest in $frame_data
     $info['frameData'] = substr($frameData, 10);
     $info['frameName'] = substr($info['frameHeader'], 0, 4);
     $info['frameSize'] = $this->_tagVersion == 3 ? Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4)) : Zend_Id3_ByteConvert::bigEndianSyncSafe2Int(substr($info['frameHeader'], 4, 4));
     if ($info['frameSize'] < strlen($frameData) + 4) {
         $arrBrokenMP3extFrames = array("" . 'MP3', "" . 'MP', ' MP3', 'MP3e');
         $nextFrameID = substr($frameData, $info['frameSize'], 4);
         if ($this->_isValidID3v2FrameName($nextFrameID)) {
             // next frame is OK
         } else {
             if (in_array($info['frameName'], $arrBrokenMP3extFrames)) {
                 // MP3ext known broken frames - "ok" for the purposes of this test
             } else {
                 if ($this->_tagVersion == 4 && $this->_isValidID3v2FrameName(substr($info['frameData'], Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4)), 4), 3)) {
                     $this->_tagVersion = 3;
                     $info['frameSize'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 4, 4));
                     // 32-bit integer
                 }
             }
         }
     }
     $info['frameFlag'] = Zend_Id3_ByteConvert::bigEndian2Int(substr($info['frameHeader'], 8, 2));
     // padding encountered
     if ($info['frameName'] == "") {
         return $this->_parsePadding($info['frameData'], $info['frameHeader']);
     }
     return $info;
 }