Edit File by line
/home/barbar84/public_h.../wp-inclu.../ID3
File: module.audio.mp3.php
<?php
[0] Fix | Delete
[1] Fix | Delete
/////////////////////////////////////////////////////////////////
[2] Fix | Delete
/// getID3() by James Heinrich <info@getid3.org> //
[3] Fix | Delete
// available at https://github.com/JamesHeinrich/getID3 //
[4] Fix | Delete
// or https://www.getid3.org //
[5] Fix | Delete
// or http://getid3.sourceforge.net //
[6] Fix | Delete
// see readme.txt for more details //
[7] Fix | Delete
/////////////////////////////////////////////////////////////////
[8] Fix | Delete
// //
[9] Fix | Delete
// module.audio.mp3.php //
[10] Fix | Delete
// module for analyzing MP3 files //
[11] Fix | Delete
// dependencies: NONE //
[12] Fix | Delete
// ///
[13] Fix | Delete
/////////////////////////////////////////////////////////////////
[14] Fix | Delete
[15] Fix | Delete
if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
[16] Fix | Delete
exit;
[17] Fix | Delete
}
[18] Fix | Delete
[19] Fix | Delete
// number of frames to scan to determine if MPEG-audio sequence is valid
[20] Fix | Delete
// Lower this number to 5-20 for faster scanning
[21] Fix | Delete
// Increase this number to 50+ for most accurate detection of valid VBR/CBR
[22] Fix | Delete
// mpeg-audio streams
[23] Fix | Delete
define('GETID3_MP3_VALID_CHECK_FRAMES', 35);
[24] Fix | Delete
[25] Fix | Delete
[26] Fix | Delete
class getid3_mp3 extends getid3_handler
[27] Fix | Delete
{
[28] Fix | Delete
/**
[29] Fix | Delete
* Forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow,
[30] Fix | Delete
* unrecommended, but may provide data from otherwise-unusable files.
[31] Fix | Delete
*
[32] Fix | Delete
* @var bool
[33] Fix | Delete
*/
[34] Fix | Delete
public $allow_bruteforce = false;
[35] Fix | Delete
[36] Fix | Delete
/**
[37] Fix | Delete
* @return bool
[38] Fix | Delete
*/
[39] Fix | Delete
public function Analyze() {
[40] Fix | Delete
$info = &$this->getid3->info;
[41] Fix | Delete
[42] Fix | Delete
$initialOffset = $info['avdataoffset'];
[43] Fix | Delete
[44] Fix | Delete
if (!$this->getOnlyMPEGaudioInfo($info['avdataoffset'])) {
[45] Fix | Delete
if ($this->allow_bruteforce) {
[46] Fix | Delete
$this->error('Rescanning file in BruteForce mode');
[47] Fix | Delete
$this->getOnlyMPEGaudioInfoBruteForce();
[48] Fix | Delete
}
[49] Fix | Delete
}
[50] Fix | Delete
[51] Fix | Delete
[52] Fix | Delete
if (isset($info['mpeg']['audio']['bitrate_mode'])) {
[53] Fix | Delete
$info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
[54] Fix | Delete
}
[55] Fix | Delete
[56] Fix | Delete
if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) {
[57] Fix | Delete
[58] Fix | Delete
$synchoffsetwarning = 'Unknown data before synch ';
[59] Fix | Delete
if (isset($info['id3v2']['headerlength'])) {
[60] Fix | Delete
$synchoffsetwarning .= '(ID3v2 header ends at '.$info['id3v2']['headerlength'].', then '.($info['avdataoffset'] - $info['id3v2']['headerlength']).' bytes garbage, ';
[61] Fix | Delete
} elseif ($initialOffset > 0) {
[62] Fix | Delete
$synchoffsetwarning .= '(should be at '.$initialOffset.', ';
[63] Fix | Delete
} else {
[64] Fix | Delete
$synchoffsetwarning .= '(should be at beginning of file, ';
[65] Fix | Delete
}
[66] Fix | Delete
$synchoffsetwarning .= 'synch detected at '.$info['avdataoffset'].')';
[67] Fix | Delete
if (isset($info['audio']['bitrate_mode']) && ($info['audio']['bitrate_mode'] == 'cbr')) {
[68] Fix | Delete
[69] Fix | Delete
if (!empty($info['id3v2']['headerlength']) && (($info['avdataoffset'] - $info['id3v2']['headerlength']) == $info['mpeg']['audio']['framelength'])) {
[70] Fix | Delete
[71] Fix | Delete
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90-3.92) DLL in CBR mode.';
[72] Fix | Delete
$info['audio']['codec'] = 'LAME';
[73] Fix | Delete
$CurrentDataLAMEversionString = 'LAME3.';
[74] Fix | Delete
[75] Fix | Delete
} elseif (empty($info['id3v2']['headerlength']) && ($info['avdataoffset'] == $info['mpeg']['audio']['framelength'])) {
[76] Fix | Delete
[77] Fix | Delete
$synchoffsetwarning .= '. This is a known problem with some versions of LAME (3.90 - 3.92) DLL in CBR mode.';
[78] Fix | Delete
$info['audio']['codec'] = 'LAME';
[79] Fix | Delete
$CurrentDataLAMEversionString = 'LAME3.';
[80] Fix | Delete
[81] Fix | Delete
}
[82] Fix | Delete
[83] Fix | Delete
}
[84] Fix | Delete
$this->warning($synchoffsetwarning);
[85] Fix | Delete
[86] Fix | Delete
}
[87] Fix | Delete
[88] Fix | Delete
if (isset($info['mpeg']['audio']['LAME'])) {
[89] Fix | Delete
$info['audio']['codec'] = 'LAME';
[90] Fix | Delete
if (!empty($info['mpeg']['audio']['LAME']['long_version'])) {
[91] Fix | Delete
$info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['long_version'], "\x00");
[92] Fix | Delete
} elseif (!empty($info['mpeg']['audio']['LAME']['short_version'])) {
[93] Fix | Delete
$info['audio']['encoder'] = rtrim($info['mpeg']['audio']['LAME']['short_version'], "\x00");
[94] Fix | Delete
}
[95] Fix | Delete
}
[96] Fix | Delete
[97] Fix | Delete
$CurrentDataLAMEversionString = (!empty($CurrentDataLAMEversionString) ? $CurrentDataLAMEversionString : (isset($info['audio']['encoder']) ? $info['audio']['encoder'] : ''));
[98] Fix | Delete
if (!empty($CurrentDataLAMEversionString) && (substr($CurrentDataLAMEversionString, 0, 6) == 'LAME3.') && !preg_match('[0-9\)]', substr($CurrentDataLAMEversionString, -1))) {
[99] Fix | Delete
// a version number of LAME that does not end with a number like "LAME3.92"
[100] Fix | Delete
// or with a closing parenthesis like "LAME3.88 (alpha)"
[101] Fix | Delete
// or a version of LAME with the LAMEtag-not-filled-in-DLL-mode bug (3.90-3.92)
[102] Fix | Delete
[103] Fix | Delete
// not sure what the actual last frame length will be, but will be less than or equal to 1441
[104] Fix | Delete
$PossiblyLongerLAMEversion_FrameLength = 1441;
[105] Fix | Delete
[106] Fix | Delete
// Not sure what version of LAME this is - look in padding of last frame for longer version string
[107] Fix | Delete
$PossibleLAMEversionStringOffset = $info['avdataend'] - $PossiblyLongerLAMEversion_FrameLength;
[108] Fix | Delete
$this->fseek($PossibleLAMEversionStringOffset);
[109] Fix | Delete
$PossiblyLongerLAMEversion_Data = $this->fread($PossiblyLongerLAMEversion_FrameLength);
[110] Fix | Delete
switch (substr($CurrentDataLAMEversionString, -1)) {
[111] Fix | Delete
case 'a':
[112] Fix | Delete
case 'b':
[113] Fix | Delete
// "LAME3.94a" will have a longer version string of "LAME3.94 (alpha)" for example
[114] Fix | Delete
// need to trim off "a" to match longer string
[115] Fix | Delete
$CurrentDataLAMEversionString = substr($CurrentDataLAMEversionString, 0, -1);
[116] Fix | Delete
break;
[117] Fix | Delete
}
[118] Fix | Delete
if (($PossiblyLongerLAMEversion_String = strstr($PossiblyLongerLAMEversion_Data, $CurrentDataLAMEversionString)) !== false) {
[119] Fix | Delete
if (substr($PossiblyLongerLAMEversion_String, 0, strlen($CurrentDataLAMEversionString)) == $CurrentDataLAMEversionString) {
[120] Fix | Delete
$PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3" "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
[121] Fix | Delete
if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) {
[122] Fix | Delete
$info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
[123] Fix | Delete
}
[124] Fix | Delete
}
[125] Fix | Delete
}
[126] Fix | Delete
}
[127] Fix | Delete
if (!empty($info['audio']['encoder'])) {
[128] Fix | Delete
$info['audio']['encoder'] = rtrim($info['audio']['encoder'], "\x00 ");
[129] Fix | Delete
}
[130] Fix | Delete
[131] Fix | Delete
switch (isset($info['mpeg']['audio']['layer']) ? $info['mpeg']['audio']['layer'] : '') {
[132] Fix | Delete
case 1:
[133] Fix | Delete
case 2:
[134] Fix | Delete
$info['audio']['dataformat'] = 'mp'.$info['mpeg']['audio']['layer'];
[135] Fix | Delete
break;
[136] Fix | Delete
}
[137] Fix | Delete
if (isset($info['fileformat']) && ($info['fileformat'] == 'mp3')) {
[138] Fix | Delete
switch ($info['audio']['dataformat']) {
[139] Fix | Delete
case 'mp1':
[140] Fix | Delete
case 'mp2':
[141] Fix | Delete
case 'mp3':
[142] Fix | Delete
$info['fileformat'] = $info['audio']['dataformat'];
[143] Fix | Delete
break;
[144] Fix | Delete
[145] Fix | Delete
default:
[146] Fix | Delete
$this->warning('Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"');
[147] Fix | Delete
break;
[148] Fix | Delete
}
[149] Fix | Delete
}
[150] Fix | Delete
[151] Fix | Delete
if (empty($info['fileformat'])) {
[152] Fix | Delete
unset($info['fileformat']);
[153] Fix | Delete
unset($info['audio']['bitrate_mode']);
[154] Fix | Delete
unset($info['avdataoffset']);
[155] Fix | Delete
unset($info['avdataend']);
[156] Fix | Delete
return false;
[157] Fix | Delete
}
[158] Fix | Delete
[159] Fix | Delete
$info['mime_type'] = 'audio/mpeg';
[160] Fix | Delete
$info['audio']['lossless'] = false;
[161] Fix | Delete
[162] Fix | Delete
// Calculate playtime
[163] Fix | Delete
if (!isset($info['playtime_seconds']) && isset($info['audio']['bitrate']) && ($info['audio']['bitrate'] > 0)) {
[164] Fix | Delete
// https://github.com/JamesHeinrich/getID3/issues/161
[165] Fix | Delete
// VBR header frame contains ~0.026s of silent audio data, but is not actually part of the original encoding and should be ignored
[166] Fix | Delete
$xingVBRheaderFrameLength = ((isset($info['mpeg']['audio']['VBR_frames']) && isset($info['mpeg']['audio']['framelength'])) ? $info['mpeg']['audio']['framelength'] : 0);
[167] Fix | Delete
[168] Fix | Delete
$info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset'] - $xingVBRheaderFrameLength) * 8 / $info['audio']['bitrate'];
[169] Fix | Delete
}
[170] Fix | Delete
[171] Fix | Delete
$info['audio']['encoder_options'] = $this->GuessEncoderOptions();
[172] Fix | Delete
[173] Fix | Delete
return true;
[174] Fix | Delete
}
[175] Fix | Delete
[176] Fix | Delete
/**
[177] Fix | Delete
* @return string
[178] Fix | Delete
*/
[179] Fix | Delete
public function GuessEncoderOptions() {
[180] Fix | Delete
// shortcuts
[181] Fix | Delete
$info = &$this->getid3->info;
[182] Fix | Delete
$thisfile_mpeg_audio = array();
[183] Fix | Delete
$thisfile_mpeg_audio_lame = array();
[184] Fix | Delete
if (!empty($info['mpeg']['audio'])) {
[185] Fix | Delete
$thisfile_mpeg_audio = &$info['mpeg']['audio'];
[186] Fix | Delete
if (!empty($thisfile_mpeg_audio['LAME'])) {
[187] Fix | Delete
$thisfile_mpeg_audio_lame = &$thisfile_mpeg_audio['LAME'];
[188] Fix | Delete
}
[189] Fix | Delete
}
[190] Fix | Delete
[191] Fix | Delete
$encoder_options = '';
[192] Fix | Delete
static $NamedPresetBitrates = array(16, 24, 40, 56, 112, 128, 160, 192, 256);
[193] Fix | Delete
[194] Fix | Delete
if (isset($thisfile_mpeg_audio['VBR_method']) && ($thisfile_mpeg_audio['VBR_method'] == 'Fraunhofer') && !empty($thisfile_mpeg_audio['VBR_quality'])) {
[195] Fix | Delete
[196] Fix | Delete
$encoder_options = 'VBR q'.$thisfile_mpeg_audio['VBR_quality'];
[197] Fix | Delete
[198] Fix | Delete
} elseif (!empty($thisfile_mpeg_audio_lame['preset_used']) && isset($thisfile_mpeg_audio_lame['preset_used_id']) && (!in_array($thisfile_mpeg_audio_lame['preset_used_id'], $NamedPresetBitrates))) {
[199] Fix | Delete
[200] Fix | Delete
$encoder_options = $thisfile_mpeg_audio_lame['preset_used'];
[201] Fix | Delete
[202] Fix | Delete
} elseif (!empty($thisfile_mpeg_audio_lame['vbr_quality'])) {
[203] Fix | Delete
[204] Fix | Delete
static $KnownEncoderValues = array();
[205] Fix | Delete
if (empty($KnownEncoderValues)) {
[206] Fix | Delete
[207] Fix | Delete
//$KnownEncoderValues[abrbitrate_minbitrate][vbr_quality][raw_vbr_method][raw_noise_shaping][raw_stereo_mode][ath_type][lowpass_frequency] = 'preset name';
[208] Fix | Delete
$KnownEncoderValues[0xFF][58][1][1][3][2][20500] = '--alt-preset insane'; // 3.90, 3.90.1, 3.92
[209] Fix | Delete
$KnownEncoderValues[0xFF][58][1][1][3][2][20600] = '--alt-preset insane'; // 3.90.2, 3.90.3, 3.91
[210] Fix | Delete
$KnownEncoderValues[0xFF][57][1][1][3][4][20500] = '--alt-preset insane'; // 3.94, 3.95
[211] Fix | Delete
$KnownEncoderValues['**'][78][3][2][3][2][19500] = '--alt-preset extreme'; // 3.90, 3.90.1, 3.92
[212] Fix | Delete
$KnownEncoderValues['**'][78][3][2][3][2][19600] = '--alt-preset extreme'; // 3.90.2, 3.91
[213] Fix | Delete
$KnownEncoderValues['**'][78][3][1][3][2][19600] = '--alt-preset extreme'; // 3.90.3
[214] Fix | Delete
$KnownEncoderValues['**'][78][4][2][3][2][19500] = '--alt-preset fast extreme'; // 3.90, 3.90.1, 3.92
[215] Fix | Delete
$KnownEncoderValues['**'][78][4][2][3][2][19600] = '--alt-preset fast extreme'; // 3.90.2, 3.90.3, 3.91
[216] Fix | Delete
$KnownEncoderValues['**'][78][3][2][3][4][19000] = '--alt-preset standard'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[217] Fix | Delete
$KnownEncoderValues['**'][78][3][1][3][4][19000] = '--alt-preset standard'; // 3.90.3
[218] Fix | Delete
$KnownEncoderValues['**'][78][4][2][3][4][19000] = '--alt-preset fast standard'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[219] Fix | Delete
$KnownEncoderValues['**'][78][4][1][3][4][19000] = '--alt-preset fast standard'; // 3.90.3
[220] Fix | Delete
$KnownEncoderValues['**'][88][4][1][3][3][19500] = '--r3mix'; // 3.90, 3.90.1, 3.92
[221] Fix | Delete
$KnownEncoderValues['**'][88][4][1][3][3][19600] = '--r3mix'; // 3.90.2, 3.90.3, 3.91
[222] Fix | Delete
$KnownEncoderValues['**'][67][4][1][3][4][18000] = '--r3mix'; // 3.94, 3.95
[223] Fix | Delete
$KnownEncoderValues['**'][68][3][2][3][4][18000] = '--alt-preset medium'; // 3.90.3
[224] Fix | Delete
$KnownEncoderValues['**'][68][4][2][3][4][18000] = '--alt-preset fast medium'; // 3.90.3
[225] Fix | Delete
[226] Fix | Delete
$KnownEncoderValues[0xFF][99][1][1][1][2][0] = '--preset studio'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[227] Fix | Delete
$KnownEncoderValues[0xFF][58][2][1][3][2][20600] = '--preset studio'; // 3.90.3, 3.93.1
[228] Fix | Delete
$KnownEncoderValues[0xFF][58][2][1][3][2][20500] = '--preset studio'; // 3.93
[229] Fix | Delete
$KnownEncoderValues[0xFF][57][2][1][3][4][20500] = '--preset studio'; // 3.94, 3.95
[230] Fix | Delete
$KnownEncoderValues[0xC0][88][1][1][1][2][0] = '--preset cd'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[231] Fix | Delete
$KnownEncoderValues[0xC0][58][2][2][3][2][19600] = '--preset cd'; // 3.90.3, 3.93.1
[232] Fix | Delete
$KnownEncoderValues[0xC0][58][2][2][3][2][19500] = '--preset cd'; // 3.93
[233] Fix | Delete
$KnownEncoderValues[0xC0][57][2][1][3][4][19500] = '--preset cd'; // 3.94, 3.95
[234] Fix | Delete
$KnownEncoderValues[0xA0][78][1][1][3][2][18000] = '--preset hifi'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[235] Fix | Delete
$KnownEncoderValues[0xA0][58][2][2][3][2][18000] = '--preset hifi'; // 3.90.3, 3.93, 3.93.1
[236] Fix | Delete
$KnownEncoderValues[0xA0][57][2][1][3][4][18000] = '--preset hifi'; // 3.94, 3.95
[237] Fix | Delete
$KnownEncoderValues[0x80][67][1][1][3][2][18000] = '--preset tape'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[238] Fix | Delete
$KnownEncoderValues[0x80][67][1][1][3][2][15000] = '--preset radio'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[239] Fix | Delete
$KnownEncoderValues[0x70][67][1][1][3][2][15000] = '--preset fm'; // 3.90, 3.90.1, 3.90.2, 3.91, 3.92
[240] Fix | Delete
$KnownEncoderValues[0x70][58][2][2][3][2][16000] = '--preset tape/radio/fm'; // 3.90.3, 3.93, 3.93.1
[241] Fix | Delete
$KnownEncoderValues[0x70][57][2][1][3][4][16000] = '--preset tape/radio/fm'; // 3.94, 3.95
[242] Fix | Delete
$KnownEncoderValues[0x38][58][2][2][0][2][10000] = '--preset voice'; // 3.90.3, 3.93, 3.93.1
[243] Fix | Delete
$KnownEncoderValues[0x38][57][2][1][0][4][15000] = '--preset voice'; // 3.94, 3.95
[244] Fix | Delete
$KnownEncoderValues[0x38][57][2][1][0][4][16000] = '--preset voice'; // 3.94a14
[245] Fix | Delete
$KnownEncoderValues[0x28][65][1][1][0][2][7500] = '--preset mw-us'; // 3.90, 3.90.1, 3.92
[246] Fix | Delete
$KnownEncoderValues[0x28][65][1][1][0][2][7600] = '--preset mw-us'; // 3.90.2, 3.91
[247] Fix | Delete
$KnownEncoderValues[0x28][58][2][2][0][2][7000] = '--preset mw-us'; // 3.90.3, 3.93, 3.93.1
[248] Fix | Delete
$KnownEncoderValues[0x28][57][2][1][0][4][10500] = '--preset mw-us'; // 3.94, 3.95
[249] Fix | Delete
$KnownEncoderValues[0x28][57][2][1][0][4][11200] = '--preset mw-us'; // 3.94a14
[250] Fix | Delete
$KnownEncoderValues[0x28][57][2][1][0][4][8800] = '--preset mw-us'; // 3.94a15
[251] Fix | Delete
$KnownEncoderValues[0x18][58][2][2][0][2][4000] = '--preset phon+/lw/mw-eu/sw'; // 3.90.3, 3.93.1
[252] Fix | Delete
$KnownEncoderValues[0x18][58][2][2][0][2][3900] = '--preset phon+/lw/mw-eu/sw'; // 3.93
[253] Fix | Delete
$KnownEncoderValues[0x18][57][2][1][0][4][5900] = '--preset phon+/lw/mw-eu/sw'; // 3.94, 3.95
[254] Fix | Delete
$KnownEncoderValues[0x18][57][2][1][0][4][6200] = '--preset phon+/lw/mw-eu/sw'; // 3.94a14
[255] Fix | Delete
$KnownEncoderValues[0x18][57][2][1][0][4][3200] = '--preset phon+/lw/mw-eu/sw'; // 3.94a15
[256] Fix | Delete
$KnownEncoderValues[0x10][58][2][2][0][2][3800] = '--preset phone'; // 3.90.3, 3.93.1
[257] Fix | Delete
$KnownEncoderValues[0x10][58][2][2][0][2][3700] = '--preset phone'; // 3.93
[258] Fix | Delete
$KnownEncoderValues[0x10][57][2][1][0][4][5600] = '--preset phone'; // 3.94, 3.95
[259] Fix | Delete
}
[260] Fix | Delete
[261] Fix | Delete
if (isset($KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) {
[262] Fix | Delete
[263] Fix | Delete
$encoder_options = $KnownEncoderValues[$thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate']][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']];
[264] Fix | Delete
[265] Fix | Delete
} elseif (isset($KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']])) {
[266] Fix | Delete
[267] Fix | Delete
$encoder_options = $KnownEncoderValues['**'][$thisfile_mpeg_audio_lame['vbr_quality']][$thisfile_mpeg_audio_lame['raw']['vbr_method']][$thisfile_mpeg_audio_lame['raw']['noise_shaping']][$thisfile_mpeg_audio_lame['raw']['stereo_mode']][$thisfile_mpeg_audio_lame['ath_type']][$thisfile_mpeg_audio_lame['lowpass_frequency']];
[268] Fix | Delete
[269] Fix | Delete
} elseif ($info['audio']['bitrate_mode'] == 'vbr') {
[270] Fix | Delete
[271] Fix | Delete
// http://gabriel.mp3-tech.org/mp3infotag.html
[272] Fix | Delete
// int Quality = (100 - 10 * gfp->VBR_q - gfp->quality)h
[273] Fix | Delete
[274] Fix | Delete
[275] Fix | Delete
$LAME_V_value = 10 - ceil($thisfile_mpeg_audio_lame['vbr_quality'] / 10);
[276] Fix | Delete
$LAME_q_value = 100 - $thisfile_mpeg_audio_lame['vbr_quality'] - ($LAME_V_value * 10);
[277] Fix | Delete
$encoder_options = '-V'.$LAME_V_value.' -q'.$LAME_q_value;
[278] Fix | Delete
[279] Fix | Delete
} elseif ($info['audio']['bitrate_mode'] == 'cbr') {
[280] Fix | Delete
[281] Fix | Delete
$encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
[282] Fix | Delete
[283] Fix | Delete
} else {
[284] Fix | Delete
[285] Fix | Delete
$encoder_options = strtoupper($info['audio']['bitrate_mode']);
[286] Fix | Delete
[287] Fix | Delete
}
[288] Fix | Delete
[289] Fix | Delete
} elseif (!empty($thisfile_mpeg_audio_lame['bitrate_abr'])) {
[290] Fix | Delete
[291] Fix | Delete
$encoder_options = 'ABR'.$thisfile_mpeg_audio_lame['bitrate_abr'];
[292] Fix | Delete
[293] Fix | Delete
} elseif (!empty($info['audio']['bitrate'])) {
[294] Fix | Delete
[295] Fix | Delete
if ($info['audio']['bitrate_mode'] == 'cbr') {
[296] Fix | Delete
$encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
[297] Fix | Delete
} else {
[298] Fix | Delete
$encoder_options = strtoupper($info['audio']['bitrate_mode']);
[299] Fix | Delete
}
[300] Fix | Delete
[301] Fix | Delete
}
[302] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame['bitrate_min'])) {
[303] Fix | Delete
$encoder_options .= ' -b'.$thisfile_mpeg_audio_lame['bitrate_min'];
[304] Fix | Delete
}
[305] Fix | Delete
[306] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']) || !empty($thisfile_mpeg_audio_lame['encoding_flags']['nogap_next'])) {
[307] Fix | Delete
$encoder_options .= ' --nogap';
[308] Fix | Delete
}
[309] Fix | Delete
[310] Fix | Delete
if (!empty($thisfile_mpeg_audio_lame['lowpass_frequency'])) {
[311] Fix | Delete
$ExplodedOptions = explode(' ', $encoder_options, 4);
[312] Fix | Delete
if ($ExplodedOptions[0] == '--r3mix') {
[313] Fix | Delete
$ExplodedOptions[1] = 'r3mix';
[314] Fix | Delete
}
[315] Fix | Delete
switch ($ExplodedOptions[0]) {
[316] Fix | Delete
case '--preset':
[317] Fix | Delete
case '--alt-preset':
[318] Fix | Delete
case '--r3mix':
[319] Fix | Delete
if ($ExplodedOptions[1] == 'fast') {
[320] Fix | Delete
$ExplodedOptions[1] .= ' '.$ExplodedOptions[2];
[321] Fix | Delete
}
[322] Fix | Delete
switch ($ExplodedOptions[1]) {
[323] Fix | Delete
case 'portable':
[324] Fix | Delete
case 'medium':
[325] Fix | Delete
case 'standard':
[326] Fix | Delete
case 'extreme':
[327] Fix | Delete
case 'insane':
[328] Fix | Delete
case 'fast portable':
[329] Fix | Delete
case 'fast medium':
[330] Fix | Delete
case 'fast standard':
[331] Fix | Delete
case 'fast extreme':
[332] Fix | Delete
case 'fast insane':
[333] Fix | Delete
case 'r3mix':
[334] Fix | Delete
static $ExpectedLowpass = array(
[335] Fix | Delete
'insane|20500' => 20500,
[336] Fix | Delete
'insane|20600' => 20600, // 3.90.2, 3.90.3, 3.91
[337] Fix | Delete
'medium|18000' => 18000,
[338] Fix | Delete
'fast medium|18000' => 18000,
[339] Fix | Delete
'extreme|19500' => 19500, // 3.90, 3.90.1, 3.92, 3.95
[340] Fix | Delete
'extreme|19600' => 19600, // 3.90.2, 3.90.3, 3.91, 3.93.1
[341] Fix | Delete
'fast extreme|19500' => 19500, // 3.90, 3.90.1, 3.92, 3.95
[342] Fix | Delete
'fast extreme|19600' => 19600, // 3.90.2, 3.90.3, 3.91, 3.93.1
[343] Fix | Delete
'standard|19000' => 19000,
[344] Fix | Delete
'fast standard|19000' => 19000,
[345] Fix | Delete
'r3mix|19500' => 19500, // 3.90, 3.90.1, 3.92
[346] Fix | Delete
'r3mix|19600' => 19600, // 3.90.2, 3.90.3, 3.91
[347] Fix | Delete
'r3mix|18000' => 18000, // 3.94, 3.95
[348] Fix | Delete
);
[349] Fix | Delete
if (!isset($ExpectedLowpass[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio_lame['lowpass_frequency']]) && ($thisfile_mpeg_audio_lame['lowpass_frequency'] < 22050) && (round($thisfile_mpeg_audio_lame['lowpass_frequency'] / 1000) < round($thisfile_mpeg_audio['sample_rate'] / 2000))) {
[350] Fix | Delete
$encoder_options .= ' --lowpass '.$thisfile_mpeg_audio_lame['lowpass_frequency'];
[351] Fix | Delete
}
[352] Fix | Delete
break;
[353] Fix | Delete
[354] Fix | Delete
default:
[355] Fix | Delete
break;
[356] Fix | Delete
}
[357] Fix | Delete
break;
[358] Fix | Delete
}
[359] Fix | Delete
}
[360] Fix | Delete
[361] Fix | Delete
if (isset($thisfile_mpeg_audio_lame['raw']['source_sample_freq'])) {
[362] Fix | Delete
if (($thisfile_mpeg_audio['sample_rate'] == 44100) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 1)) {
[363] Fix | Delete
$encoder_options .= ' --resample 44100';
[364] Fix | Delete
} elseif (($thisfile_mpeg_audio['sample_rate'] == 48000) && ($thisfile_mpeg_audio_lame['raw']['source_sample_freq'] != 2)) {
[365] Fix | Delete
$encoder_options .= ' --resample 48000';
[366] Fix | Delete
} elseif ($thisfile_mpeg_audio['sample_rate'] < 44100) {
[367] Fix | Delete
switch ($thisfile_mpeg_audio_lame['raw']['source_sample_freq']) {
[368] Fix | Delete
case 0: // <= 32000
[369] Fix | Delete
// may or may not be same as source frequency - ignore
[370] Fix | Delete
break;
[371] Fix | Delete
case 1: // 44100
[372] Fix | Delete
case 2: // 48000
[373] Fix | Delete
case 3: // 48000+
[374] Fix | Delete
$ExplodedOptions = explode(' ', $encoder_options, 4);
[375] Fix | Delete
switch ($ExplodedOptions[0]) {
[376] Fix | Delete
case '--preset':
[377] Fix | Delete
case '--alt-preset':
[378] Fix | Delete
switch ($ExplodedOptions[1]) {
[379] Fix | Delete
case 'fast':
[380] Fix | Delete
case 'portable':
[381] Fix | Delete
case 'medium':
[382] Fix | Delete
case 'standard':
[383] Fix | Delete
case 'extreme':
[384] Fix | Delete
case 'insane':
[385] Fix | Delete
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
[386] Fix | Delete
break;
[387] Fix | Delete
[388] Fix | Delete
default:
[389] Fix | Delete
static $ExpectedResampledRate = array(
[390] Fix | Delete
'phon+/lw/mw-eu/sw|16000' => 16000,
[391] Fix | Delete
'mw-us|24000' => 24000, // 3.95
[392] Fix | Delete
'mw-us|32000' => 32000, // 3.93
[393] Fix | Delete
'mw-us|16000' => 16000, // 3.92
[394] Fix | Delete
'phone|16000' => 16000,
[395] Fix | Delete
'phone|11025' => 11025, // 3.94a15
[396] Fix | Delete
'radio|32000' => 32000, // 3.94a15
[397] Fix | Delete
'fm/radio|32000' => 32000, // 3.92
[398] Fix | Delete
'fm|32000' => 32000, // 3.90
[399] Fix | Delete
'voice|32000' => 32000);
[400] Fix | Delete
if (!isset($ExpectedResampledRate[$ExplodedOptions[1].'|'.$thisfile_mpeg_audio['sample_rate']])) {
[401] Fix | Delete
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
[402] Fix | Delete
}
[403] Fix | Delete
break;
[404] Fix | Delete
}
[405] Fix | Delete
break;
[406] Fix | Delete
[407] Fix | Delete
case '--r3mix':
[408] Fix | Delete
default:
[409] Fix | Delete
$encoder_options .= ' --resample '.$thisfile_mpeg_audio['sample_rate'];
[410] Fix | Delete
break;
[411] Fix | Delete
}
[412] Fix | Delete
break;
[413] Fix | Delete
}
[414] Fix | Delete
}
[415] Fix | Delete
}
[416] Fix | Delete
if (empty($encoder_options) && !empty($info['audio']['bitrate']) && !empty($info['audio']['bitrate_mode'])) {
[417] Fix | Delete
//$encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
[418] Fix | Delete
$encoder_options = strtoupper($info['audio']['bitrate_mode']);
[419] Fix | Delete
}
[420] Fix | Delete
[421] Fix | Delete
return $encoder_options;
[422] Fix | Delete
}
[423] Fix | Delete
[424] Fix | Delete
/**
[425] Fix | Delete
* @param int $offset
[426] Fix | Delete
* @param array $info
[427] Fix | Delete
* @param bool $recursivesearch
[428] Fix | Delete
* @param bool $ScanAsCBR
[429] Fix | Delete
* @param bool $FastMPEGheaderScan
[430] Fix | Delete
*
[431] Fix | Delete
* @return bool
[432] Fix | Delete
*/
[433] Fix | Delete
public function decodeMPEGaudioHeader($offset, &$info, $recursivesearch=true, $ScanAsCBR=false, $FastMPEGheaderScan=false) {
[434] Fix | Delete
static $MPEGaudioVersionLookup;
[435] Fix | Delete
static $MPEGaudioLayerLookup;
[436] Fix | Delete
static $MPEGaudioBitrateLookup;
[437] Fix | Delete
static $MPEGaudioFrequencyLookup;
[438] Fix | Delete
static $MPEGaudioChannelModeLookup;
[439] Fix | Delete
static $MPEGaudioModeExtensionLookup;
[440] Fix | Delete
static $MPEGaudioEmphasisLookup;
[441] Fix | Delete
if (empty($MPEGaudioVersionLookup)) {
[442] Fix | Delete
$MPEGaudioVersionLookup = self::MPEGaudioVersionArray();
[443] Fix | Delete
$MPEGaudioLayerLookup = self::MPEGaudioLayerArray();
[444] Fix | Delete
$MPEGaudioBitrateLookup = self::MPEGaudioBitrateArray();
[445] Fix | Delete
$MPEGaudioFrequencyLookup = self::MPEGaudioFrequencyArray();
[446] Fix | Delete
$MPEGaudioChannelModeLookup = self::MPEGaudioChannelModeArray();
[447] Fix | Delete
$MPEGaudioModeExtensionLookup = self::MPEGaudioModeExtensionArray();
[448] Fix | Delete
$MPEGaudioEmphasisLookup = self::MPEGaudioEmphasisArray();
[449] Fix | Delete
}
[450] Fix | Delete
[451] Fix | Delete
if ($this->fseek($offset) != 0) {
[452] Fix | Delete
$this->error('decodeMPEGaudioHeader() failed to seek to next offset at '.$offset);
[453] Fix | Delete
return false;
[454] Fix | Delete
}
[455] Fix | Delete
//$headerstring = $this->fread(1441); // worst-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame
[456] Fix | Delete
$headerstring = $this->fread(226); // LAME header at offset 36 + 190 bytes of Xing/LAME data
[457] Fix | Delete
[458] Fix | Delete
// MP3 audio frame structure:
[459] Fix | Delete
// $aa $aa $aa $aa [$bb $bb] $cc...
[460] Fix | Delete
// where $aa..$aa is the four-byte mpeg-audio header (below)
[461] Fix | Delete
// $bb $bb is the optional 2-byte CRC
[462] Fix | Delete
// and $cc... is the audio data
[463] Fix | Delete
[464] Fix | Delete
$head4 = substr($headerstring, 0, 4);
[465] Fix | Delete
$head4_key = getid3_lib::PrintHexBytes($head4, true, false, false);
[466] Fix | Delete
static $MPEGaudioHeaderDecodeCache = array();
[467] Fix | Delete
if (isset($MPEGaudioHeaderDecodeCache[$head4_key])) {
[468] Fix | Delete
$MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4_key];
[469] Fix | Delete
} else {
[470] Fix | Delete
$MPEGheaderRawArray = self::MPEGaudioHeaderDecode($head4);
[471] Fix | Delete
$MPEGaudioHeaderDecodeCache[$head4_key] = $MPEGheaderRawArray;
[472] Fix | Delete
}
[473] Fix | Delete
[474] Fix | Delete
static $MPEGaudioHeaderValidCache = array();
[475] Fix | Delete
if (!isset($MPEGaudioHeaderValidCache[$head4_key])) { // Not in cache
[476] Fix | Delete
//$MPEGaudioHeaderValidCache[$head4_key] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, true); // allow badly-formatted freeformat (from LAME 3.90 - 3.93.1)
[477] Fix | Delete
$MPEGaudioHeaderValidCache[$head4_key] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, false);
[478] Fix | Delete
}
[479] Fix | Delete
[480] Fix | Delete
// shortcut
[481] Fix | Delete
if (!isset($info['mpeg']['audio'])) {
[482] Fix | Delete
$info['mpeg']['audio'] = array();
[483] Fix | Delete
}
[484] Fix | Delete
$thisfile_mpeg_audio = &$info['mpeg']['audio'];
[485] Fix | Delete
[486] Fix | Delete
if ($MPEGaudioHeaderValidCache[$head4_key]) {
[487] Fix | Delete
$thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
[488] Fix | Delete
} else {
[489] Fix | Delete
$this->error('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
[490] Fix | Delete
return false;
[491] Fix | Delete
}
[492] Fix | Delete
[493] Fix | Delete
if (!$FastMPEGheaderScan) {
[494] Fix | Delete
$thisfile_mpeg_audio['version'] = $MPEGaudioVersionLookup[$thisfile_mpeg_audio['raw']['version']];
[495] Fix | Delete
$thisfile_mpeg_audio['layer'] = $MPEGaudioLayerLookup[$thisfile_mpeg_audio['raw']['layer']];
[496] Fix | Delete
[497] Fix | Delete
$thisfile_mpeg_audio['channelmode'] = $MPEGaudioChannelModeLookup[$thisfile_mpeg_audio['raw']['channelmode']];
[498] Fix | Delete
$thisfile_mpeg_audio['channels'] = (($thisfile_mpeg_audio['channelmode'] == 'mono') ? 1 : 2);
[499] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function