Exemple #1
0
 /**
  * @return bool
  */
 public function getOnlyMPEGaudioInfoBruteForce()
 {
     $MPEGaudioHeaderDecodeCache = array();
     $MPEGaudioHeaderValidCache = array();
     $MPEGaudioHeaderLengthCache = array();
     $MPEGaudioVersionLookup = self::MPEGaudioVersionArray();
     $MPEGaudioLayerLookup = self::MPEGaudioLayerArray();
     $MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray();
     $MPEGaudioFrequencyLookup = self::MPEGaudioFrequencyArray();
     $MPEGaudioChannelModeLookup = self::MPEGaudioChannelModeArray();
     $MPEGaudioModeExtensionLookup = self::MPEGaudioModeExtensionArray();
     $MPEGaudioEmphasisLookup = self::MPEGaudioEmphasisArray();
     $LongMPEGversionLookup = array();
     $LongMPEGlayerLookup = array();
     $LongMPEGbitrateLookup = array();
     $LongMPEGpaddingLookup = array();
     $LongMPEGfrequencyLookup = array();
     $Distribution['bitrate'] = array();
     $Distribution['frequency'] = array();
     $Distribution['layer'] = array();
     $Distribution['version'] = array();
     $Distribution['padding'] = array();
     $info =& $this->getGetId3()->info;
     fseek($this->getGetId3()->fp, $info['avdataoffset'], SEEK_SET);
     $max_frames_scan = 5000;
     $frames_scanned = 0;
     $previousvalidframe = $info['avdataoffset'];
     while (ftell($this->getGetId3()->fp) < $info['avdataend']) {
         set_time_limit(30);
         $head4 = fread($this->getGetId3()->fp, 4);
         if (strlen($head4) < 4) {
             break;
         }
         if ($head4[0] != "ÿ") {
             for ($i = 1; $i < 4; ++$i) {
                 if ($head4[$i] == "ÿ") {
                     fseek($this->getGetId3()->fp, $i - 4, SEEK_CUR);
                     continue 2;
                 }
             }
             continue;
         }
         if (!isset($MPEGaudioHeaderDecodeCache[$head4])) {
             $MPEGaudioHeaderDecodeCache[$head4] = self::MPEGaudioHeaderDecode($head4);
         }
         if (!isset($MPEGaudioHeaderValidCache[$head4])) {
             $MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGaudioHeaderDecodeCache[$head4], false, false);
         }
         if ($MPEGaudioHeaderValidCache[$head4]) {
             if (!isset($MPEGaudioHeaderLengthCache[$head4])) {
                 $LongMPEGversionLookup[$head4] = $MPEGaudioVersionLookup[$MPEGaudioHeaderDecodeCache[$head4]['version']];
                 $LongMPEGlayerLookup[$head4] = $MPEGaudioLayerLookup[$MPEGaudioHeaderDecodeCache[$head4]['layer']];
                 $LongMPEGbitrateLookup[$head4] = $MPEGaudioBitrateLookup[$LongMPEGversionLookup[$head4]][$LongMPEGlayerLookup[$head4]][$MPEGaudioHeaderDecodeCache[$head4]['bitrate']];
                 $LongMPEGpaddingLookup[$head4] = (bool) $MPEGaudioHeaderDecodeCache[$head4]['padding'];
                 $LongMPEGfrequencyLookup[$head4] = $MPEGaudioFrequencyLookup[$LongMPEGversionLookup[$head4]][$MPEGaudioHeaderDecodeCache[$head4]['sample_rate']];
                 $MPEGaudioHeaderLengthCache[$head4] = self::MPEGaudioFrameLength($LongMPEGbitrateLookup[$head4], $LongMPEGversionLookup[$head4], $LongMPEGlayerLookup[$head4], $LongMPEGpaddingLookup[$head4], $LongMPEGfrequencyLookup[$head4]);
             }
             if ($MPEGaudioHeaderLengthCache[$head4] > 4) {
                 $WhereWeWere = ftell($this->getGetId3()->fp);
                 fseek($this->getGetId3()->fp, $MPEGaudioHeaderLengthCache[$head4] - 4, SEEK_CUR);
                 $next4 = fread($this->getGetId3()->fp, 4);
                 if ($next4[0] == "ÿ") {
                     if (!isset($MPEGaudioHeaderDecodeCache[$next4])) {
                         $MPEGaudioHeaderDecodeCache[$next4] = self::MPEGaudioHeaderDecode($next4);
                     }
                     if (!isset($MPEGaudioHeaderValidCache[$next4])) {
                         $MPEGaudioHeaderValidCache[$next4] = self::MPEGaudioHeaderValid($MPEGaudioHeaderDecodeCache[$next4], false, false);
                     }
                     if ($MPEGaudioHeaderValidCache[$next4]) {
                         fseek($this->getGetId3()->fp, -4, SEEK_CUR);
                         Helper::safe_inc($Distribution['bitrate'][$LongMPEGbitrateLookup[$head4]]);
                         Helper::safe_inc($Distribution['layer'][$LongMPEGlayerLookup[$head4]]);
                         Helper::safe_inc($Distribution['version'][$LongMPEGversionLookup[$head4]]);
                         Helper::safe_inc($Distribution['padding'][intval($LongMPEGpaddingLookup[$head4])]);
                         Helper::safe_inc($Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]);
                         if ($max_frames_scan && ++$frames_scanned >= $max_frames_scan) {
                             $pct_data_scanned = (ftell($this->getGetId3()->fp) - $info['avdataoffset']) / ($info['avdataend'] - $info['avdataoffset']);
                             $info['warning'][] = 'too many MPEG audio frames to scan, only scanned first ' . $max_frames_scan . ' frames (' . number_format($pct_data_scanned * 100, 1) . '% of file) and extrapolated distribution, playtime and bitrate may be incorrect.';
                             foreach ($Distribution as $key1 => $value1) {
                                 foreach ($value1 as $key2 => $value2) {
                                     $Distribution[$key1][$key2] = round($value2 / $pct_data_scanned);
                                 }
                             }
                             break;
                         }
                         continue;
                     }
                 }
                 unset($next4);
                 fseek($this->getGetId3()->fp, $WhereWeWere - 3, SEEK_SET);
             }
         }
     }
     foreach ($Distribution as $key => $value) {
         ksort($Distribution[$key], SORT_NUMERIC);
     }
     ksort($Distribution['version'], SORT_STRING);
     $info['mpeg']['audio']['bitrate_distribution'] = $Distribution['bitrate'];
     $info['mpeg']['audio']['frequency_distribution'] = $Distribution['frequency'];
     $info['mpeg']['audio']['layer_distribution'] = $Distribution['layer'];
     $info['mpeg']['audio']['version_distribution'] = $Distribution['version'];
     $info['mpeg']['audio']['padding_distribution'] = $Distribution['padding'];
     if (count($Distribution['version']) > 1) {
         $info['error'][] = 'Corrupt file - more than one MPEG version detected';
     }
     if (count($Distribution['layer']) > 1) {
         $info['error'][] = 'Corrupt file - more than one MPEG layer detected';
     }
     if (count($Distribution['frequency']) > 1) {
         $info['error'][] = 'Corrupt file - more than one MPEG sample rate detected';
     }
     $bittotal = 0;
     foreach ($Distribution['bitrate'] as $bitratevalue => $bitratecount) {
         if ($bitratevalue != 'free') {
             $bittotal += $bitratevalue * $bitratecount;
         }
     }
     $info['mpeg']['audio']['frame_count'] = array_sum($Distribution['bitrate']);
     if ($info['mpeg']['audio']['frame_count'] == 0) {
         $info['error'][] = 'no MPEG audio frames found';
         return false;
     }
     $info['mpeg']['audio']['bitrate'] = $bittotal / $info['mpeg']['audio']['frame_count'];
     $info['mpeg']['audio']['bitrate_mode'] = count($Distribution['bitrate']) > 0 ? 'vbr' : 'cbr';
     $info['mpeg']['audio']['sample_rate'] = Helper::array_max($Distribution['frequency'], true);
     $info['audio']['bitrate'] = $info['mpeg']['audio']['bitrate'];
     $info['audio']['bitrate_mode'] = $info['mpeg']['audio']['bitrate_mode'];
     $info['audio']['sample_rate'] = $info['mpeg']['audio']['sample_rate'];
     $info['audio']['dataformat'] = 'mp' . Helper::array_max($Distribution['layer'], true);
     $info['fileformat'] = $info['audio']['dataformat'];
     return true;
 }