Syntax Syntax
Return Return
(bool)
Source Source
File: wp-includes/ID3/module.audio.mp3.php
/**
* @return bool
*/
public function Analyze() {
$info = &$this->getid3->info;
$initialOffset = $info['avdataoffset'];
if (!$this->getOnlyMPEGaudioInfo($info['avdataoffset'])) {
if ($this->allow_bruteforce) {
$this->error('Rescanning file in BruteForce mode');
$this->getOnlyMPEGaudioInfoBruteForce();
}
}
if (isset($info['mpeg']['audio']['bitrate_mode'])) {
$info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
}
if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) {
$synchoffsetwarning = 'Unknown data before synch ';
if (isset($info['id3v2']['headerlength'])) {
$synchoffsetwarning .= '(ID3v2 header ends at '.$info['id3v2']['headerlength'].', then '.($info['avdataoffset'] - $info['id3v2']['headerlength']).' bytes garbage, ';
} elseif ($initialOffset > 0) {
$synchoffsetwarning .= '(should be at '.$initialOffset.', ';
} else {
$synchoffsetwarning .= '(should be at beginning of file, ';
}
$synchoffsetwarning .= 'synch detected at '.$info['avdataoffset'].')';
if (isset($info['audio']['bitrate_mode']) && ($info['audio']['bitrate_mode'] == 'cbr')) {
if (!empty($info['id3v2']['headerlength']) && (($info['avdataoffset'] - $info['id3v2']['headerlength']) == $info['mpeg']['audio']['framelength'])) {
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90-3.92) DLL in CBR mode.';
$info['audio']['codec'] = 'LAME';
$CurrentDataLAMEversionString = 'LAME3.';
} elseif (empty($info['id3v2']['headerlength']) && ($info['avdataoffset'] == $info['mpeg']['audio']['framelength'])) {
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90 - 3.92) DLL in CBR mode.';
$info['audio']['codec'] = 'LAME';
$CurrentDataLAMEversionString = 'LAME3.';
}
}
$this->warning($synchoffsetwarning);
}
if (isset($info['mpeg']['audio']['LAME'])) {
$info['audio']['codec'] = 'LAME';
if (!empty($info['mpeg']['audio']['LAME']['long_version'])) {
$info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['long_version'], "\x00");
} elseif (!empty($info['mpeg']['audio']['LAME']['short_version'])) {
$info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['short_version'], "\x00");
}
}
$CurrentDataLAMEversionString = (!empty($CurrentDataLAMEversionString) ? $CurrentDataLAMEversionString : (isset($info['audio']['encoder']) ? $info['audio']['encoder'] : ''));
if (!empty($CurrentDataLAMEversionString) && (substr($CurrentDataLAMEversionString, 0, 6) == 'LAME3.') && !preg_match('[0-9\)]', substr($CurrentDataLAMEversionString, -1))) {
// a version number of LAME that does not end with a number like "LAME3.92"
// or with a closing parenthesis like "LAME3.88 (alpha)"
// or a version of LAME with the LAMEtag-not-filled-in-DLL-mode bug (3.90-3.92)
// not sure what the actual last frame length will be, but will be less than or equal to 1441
$PossiblyLongerLAMEversion_FrameLength = 1441;
// Not sure what version of LAME this is - look in padding of last frame for longer version string
$PossibleLAMEversionStringOffset = $info['avdataend'] - $PossiblyLongerLAMEversion_FrameLength;
$this->fseek($PossibleLAMEversionStringOffset);
$PossiblyLongerLAMEversion_Data = $this->fread($PossiblyLongerLAMEversion_FrameLength);
switch (substr($CurrentDataLAMEversionString, -1)) {
case 'a':
case 'b':
// "LAME3.94a" will have a longer version string of "LAME3.94 (alpha)" for example
// need to trim off "a" to match longer string
$CurrentDataLAMEversionString = substr($CurrentDataLAMEversionString, 0, -1);
break;
}
if (($PossiblyLongerLAMEversion_String = strstr($PossiblyLongerLAMEversion_Data, $CurrentDataLAMEversionString)) !== false) {
if (substr($PossiblyLongerLAMEversion_String, 0, strlen($CurrentDataLAMEversionString)) == $CurrentDataLAMEversionString) {
$PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3" "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) {
$info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
}
}
}
}
if (!empty($info['audio']['encoder'])) {
$info['audio']['encoder'] = rtrim($info['audio']['encoder'], "\x00 ");
}
switch (isset($info['mpeg']['audio']['layer']) ? $info['mpeg']['audio']['layer'] : '') {
case 1:
case 2:
$info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
break;
}
if (isset($info['fileformat']) && ($info['fileformat'] == 'mp3')) {
switch ($info['audio']['dataformat']) {
case 'mp1':
case 'mp2':
case 'mp3':
$info['fileformat'] = $info['audio']['dataformat'];
break;
default:
$this->warning('Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"');
break;
}
}
if (empty($info['fileformat'])) {
unset($info['fileformat']);
unset($info['audio']['bitrate_mode']);
unset($info['avdataoffset']);
unset($info['avdataend']);
return false;
}
$info['mime_type'] = 'audio/mpeg';
$info['audio']['lossless'] = false;
// Calculate playtime
if (!isset($info['playtime_seconds']) && isset($info['audio']['bitrate']) && ($info['audio']['bitrate'] > 0)) {
// https://github.com/JamesHeinrich/getID3/issues/161
// VBR header frame contains ~0.026s of silent audio data, but is not actually part of the original encoding and should be ignored
$xingVBRheaderFrameLength = ((isset($info['mpeg']['audio']['VBR_frames']) && isset($info['mpeg']['audio']['framelength'])) ? $info['mpeg']['audio']['framelength'] : 0);
$info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset'] - $xingVBRheaderFrameLength) * 8 / $info['audio']['bitrate'];
}
$info['audio']['encoder_options'] = $this->GuessEncoderOptions();