/** * @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; }