📄 module.tag.id3v2.php
字号:
$thisfile_id3v2['padding']['start'] = $framedataoffset; $thisfile_id3v2['padding']['length'] = strlen($framedata); $thisfile_id3v2['padding']['valid'] = true; for ($i = 0; $i < $thisfile_id3v2['padding']['length']; $i++) { if ($framedata{$i} != "\x00") { $thisfile_id3v2['padding']['valid'] = false; $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i; $ThisFileInfo['warning'][] = 'Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)'; break; } } break; // skip rest of ID3v2 header } if ($frame_name == 'COM ') { $ThisFileInfo['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1" are known-guilty, probably others too)]'; $frame_name = 'COMM'; } if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) { unset($parsedFrame); $parsedFrame['frame_name'] = $frame_name; $parsedFrame['frame_flags_raw'] = $frame_flags; $parsedFrame['data'] = substr($framedata, 0, $frame_size); $parsedFrame['datalength'] = getid3_lib::CastAsInt($frame_size); $parsedFrame['dataoffset'] = $framedataoffset; $this->ParseID3v2Frame($parsedFrame, $ThisFileInfo); $thisfile_id3v2[$frame_name][] = $parsedFrame; $framedata = substr($framedata, $frame_size); } else { // invalid frame length or FrameID if ($frame_size <= strlen($framedata)) { if ($this->IsValidID3v2FrameName(substr($framedata, $frame_size, 4), $id3v2_majorversion)) { // next frame is valid, just skip the current frame $framedata = substr($framedata, $frame_size); $ThisFileInfo['warning'][] = 'Next ID3v2 frame is valid, skipping current frame.'; } else { // next frame is invalid too, abort processing //unset($framedata); $framedata = null; $ThisFileInfo['error'][] = 'Next ID3v2 frame is also invalid, aborting processing.'; } } elseif ($frame_size == strlen($framedata)) { // this is the last frame, just skip $ThisFileInfo['warning'][] = 'This was the last ID3v2 frame.'; } else { // next frame is invalid too, abort processing //unset($framedata); $framedata = null; $ThisFileInfo['warning'][] = 'Invalid ID3v2 frame size, aborting.'; } if (!$this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion)) { switch ($frame_name) { case "\x00\x00".'MP': case "\x00".'MP3': case ' MP3': case 'MP3e': case "\x00".'MP': case ' MP': case 'MP3': $ThisFileInfo['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by "MP3ext (www.mutschler.de/mp3ext/)"]'; break; default: $ThisFileInfo['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))).'; break; } } elseif ($frame_size > strlen($framedata)){ $ThisFileInfo['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.strlen($framedata).')).'; } else { $ThisFileInfo['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag).'; } } $framedataoffset += ($frame_size + $this->ID3v2HeaderLength($id3v2_majorversion)); } } // Footer // The footer is a copy of the header, but with a different identifier. // ID3v2 identifier "3DI" // ID3v2 version $04 00 // ID3v2 flags %abcd0000 // ID3v2 size 4 * %0xxxxxxx if (isset($thisfile_id3v2_flags['isfooter']) && $thisfile_id3v2_flags['isfooter']) { $footer = fread($fd, 10); if (substr($footer, 0, 3) == '3DI') { $thisfile_id3v2['footer'] = true; $thisfile_id3v2['majorversion_footer'] = ord($footer{3}); $thisfile_id3v2['minorversion_footer'] = ord($footer{4}); } if ($thisfile_id3v2['majorversion_footer'] <= 4) { $id3_flags = ord(substr($footer{5})); $thisfile_id3v2_flags['unsynch_footer'] = (bool) ($id3_flags & 0x80); $thisfile_id3v2_flags['extfoot_footer'] = (bool) ($id3_flags & 0x40); $thisfile_id3v2_flags['experim_footer'] = (bool) ($id3_flags & 0x20); $thisfile_id3v2_flags['isfooter_footer'] = (bool) ($id3_flags & 0x10); $thisfile_id3v2['footerlength'] = getid3_lib::BigEndian2Int(substr($footer, 6, 4), 1); } } // end footer if (isset($thisfile_id3v2['comments']['genre'])) { foreach ($thisfile_id3v2['comments']['genre'] as $key => $value) { unset($thisfile_id3v2['comments']['genre'][$key]); $thisfile_id3v2['comments'] = getid3_lib::array_merge_noclobber($thisfile_id3v2['comments'], $this->ParseID3v2GenreString($value)); } } if (isset($thisfile_id3v2['comments']['track'])) { foreach ($thisfile_id3v2['comments']['track'] as $key => $value) { if (strstr($value, '/')) { list($thisfile_id3v2['comments']['tracknum'][$key], $thisfile_id3v2['comments']['totaltracks'][$key]) = explode('/', $thisfile_id3v2['comments']['track'][$key]); } } } if (!isset($thisfile_id3v2['comments']['year']) && ereg('^([0-9]{4})', trim(@$thisfile_id3v2['comments']['recording_time'][0]), $matches)) { $thisfile_id3v2['comments']['year'] = array($matches[1]); } // Set avdataoffset $ThisFileInfo['avdataoffset'] = $thisfile_id3v2['headerlength']; if (isset($thisfile_id3v2['footer'])) { $ThisFileInfo['avdataoffset'] += 10; } return true; } function ParseID3v2GenreString($genrestring) { // Parse genres into arrays of genreName and genreID // ID3v2.2.x, ID3v2.3.x: '(21)' or '(4)Eurodisco' or '(51)(39)' or '(55)((I think...)' // ID3v2.4.x: '21' $00 'Eurodisco' $00 $genrestring = trim($genrestring); $returnarray = array(); if (strpos($genrestring, "\x00") !== false) { $unprocessed = trim($genrestring); // trailing nulls will cause an infinite loop. $genrestring = ''; while (strpos($unprocessed, "\x00") !== false) { // convert null-seperated v2.4-format into v2.3 ()-seperated format $endpos = strpos($unprocessed, "\x00"); $genrestring .= '('.substr($unprocessed, 0, $endpos).')'; $unprocessed = substr($unprocessed, $endpos + 1); } unset($unprocessed); } if (getid3_id3v1::LookupGenreID($genrestring)) { $returnarray['genre'][] = $genrestring; } else { while (strpos($genrestring, '(') !== false) { $startpos = strpos($genrestring, '('); $endpos = strpos($genrestring, ')'); if (substr($genrestring, $startpos + 1, 1) == '(') { $genrestring = substr($genrestring, 0, $startpos).substr($genrestring, $startpos + 1); $endpos--; } $element = substr($genrestring, $startpos + 1, $endpos - ($startpos + 1)); $genrestring = substr($genrestring, 0, $startpos).substr($genrestring, $endpos + 1); if (getid3_id3v1::LookupGenreName($element)) { // $element is a valid genre id/abbreviation if (empty($returnarray['genre']) || !in_array(getid3_id3v1::LookupGenreName($element), $returnarray['genre'])) { // avoid duplicate entires $returnarray['genre'][] = getid3_id3v1::LookupGenreName($element); } } else { if (empty($returnarray['genre']) || !in_array($element, $returnarray['genre'])) { // avoid duplicate entires $returnarray['genre'][] = $element; } } } } if ($genrestring) { if (empty($returnarray['genre']) || !in_array($genrestring, $returnarray['genre'])) { // avoid duplicate entires $returnarray['genre'][] = $genrestring; } } return $returnarray; } function ParseID3v2Frame(&$parsedFrame, &$ThisFileInfo) { // shortcuts $id3v2_majorversion = $ThisFileInfo['id3v2']['majorversion']; $parsedFrame['framenamelong'] = $this->FrameNameLongLookup($parsedFrame['frame_name']); if (empty($parsedFrame['framenamelong'])) { unset($parsedFrame['framenamelong']); } $parsedFrame['framenameshort'] = $this->FrameNameShortLookup($parsedFrame['frame_name']); if (empty($parsedFrame['framenameshort'])) { unset($parsedFrame['framenameshort']); } if ($id3v2_majorversion >= 3) { // frame flags are not part of the ID3v2.2 standard if ($id3v2_majorversion == 3) { // Frame Header Flags // %abc00000 %ijk00000 $parsedFrame['flags']['TagAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x8000); // a - Tag alter preservation $parsedFrame['flags']['FileAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x4000); // b - File alter preservation $parsedFrame['flags']['ReadOnly'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x2000); // c - Read only $parsedFrame['flags']['compression'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0080); // i - Compression $parsedFrame['flags']['Encryption'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0040); // j - Encryption $parsedFrame['flags']['GroupingIdentity'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0020); // k - Grouping identity } elseif ($id3v2_majorversion == 4) { // Frame Header Flags // %0abc0000 %0h00kmnp $parsedFrame['flags']['TagAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x4000); // a - Tag alter preservation $parsedFrame['flags']['FileAlterPreservation'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x2000); // b - File alter preservation $parsedFrame['flags']['ReadOnly'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x1000); // c - Read only $parsedFrame['flags']['GroupingIdentity'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0040); // h - Grouping identity $parsedFrame['flags']['compression'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0008); // k - Compression $parsedFrame['flags']['Encryption'] = (bool) ($parsedFrame['frame_flags_raw'] & 0x0004); // m - Encryption
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -