1 <?php |
1 <?php |
2 ///////////////////////////////////////////////////////////////// |
2 ///////////////////////////////////////////////////////////////// |
3 /// getID3() by James Heinrich <info@getid3.org> // |
3 /// getID3() by James Heinrich <info@getid3.org> // |
4 // available at http://getid3.sourceforge.net // |
4 // available at http://getid3.sourceforge.net // |
5 // or http://www.getid3.org // |
5 // or http://www.getid3.org // |
|
6 // also https://github.com/JamesHeinrich/getID3 // |
6 ///////////////////////////////////////////////////////////////// |
7 ///////////////////////////////////////////////////////////////// |
7 // See readme.txt for more details // |
8 // See readme.txt for more details // |
8 ///////////////////////////////////////////////////////////////// |
9 ///////////////////////////////////////////////////////////////// |
9 /// // |
10 /// // |
10 // module.tag.id3v2.php // |
11 // module.tag.id3v2.php // |
49 $thisfile_id3v2 = &$info['id3v2']; |
50 $thisfile_id3v2 = &$info['id3v2']; |
50 $thisfile_id3v2['flags'] = array(); |
51 $thisfile_id3v2['flags'] = array(); |
51 $thisfile_id3v2_flags = &$thisfile_id3v2['flags']; |
52 $thisfile_id3v2_flags = &$thisfile_id3v2['flags']; |
52 |
53 |
53 |
54 |
54 fseek($this->getid3->fp, $this->StartingOffset, SEEK_SET); |
55 $this->fseek($this->StartingOffset); |
55 $header = fread($this->getid3->fp, 10); |
56 $header = $this->fread(10); |
56 if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) { |
57 if (substr($header, 0, 3) == 'ID3' && strlen($header) == 10) { |
57 |
58 |
58 $thisfile_id3v2['majorversion'] = ord($header{3}); |
59 $thisfile_id3v2['majorversion'] = ord($header{3}); |
59 $thisfile_id3v2['minorversion'] = ord($header{4}); |
60 $thisfile_id3v2['minorversion'] = ord($header{4}); |
60 |
61 |
129 if (!empty($thisfile_id3v2_flags['isfooter'])) { |
130 if (!empty($thisfile_id3v2_flags['isfooter'])) { |
130 $sizeofframes -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio |
131 $sizeofframes -= 10; // footer takes last 10 bytes of ID3v2 header, after frame data, before audio |
131 } |
132 } |
132 if ($sizeofframes > 0) { |
133 if ($sizeofframes > 0) { |
133 |
134 |
134 $framedata = fread($this->getid3->fp, $sizeofframes); // read all frames from file into $framedata variable |
135 $framedata = $this->fread($sizeofframes); // read all frames from file into $framedata variable |
135 |
136 |
136 // if entire frame data is unsynched, de-unsynch it now (ID3v2.3.x) |
137 // if entire frame data is unsynched, de-unsynch it now (ID3v2.3.x) |
137 if (!empty($thisfile_id3v2_flags['unsynch']) && ($id3v2_majorversion <= 3)) { |
138 if (!empty($thisfile_id3v2_flags['unsynch']) && ($id3v2_majorversion <= 3)) { |
138 $framedata = $this->DeUnsynchronise($framedata); |
139 $framedata = $this->DeUnsynchronise($framedata); |
139 } |
140 } |
421 // ID3v2 version $04 00 |
422 // ID3v2 version $04 00 |
422 // ID3v2 flags %abcd0000 |
423 // ID3v2 flags %abcd0000 |
423 // ID3v2 size 4 * %0xxxxxxx |
424 // ID3v2 size 4 * %0xxxxxxx |
424 |
425 |
425 if (isset($thisfile_id3v2_flags['isfooter']) && $thisfile_id3v2_flags['isfooter']) { |
426 if (isset($thisfile_id3v2_flags['isfooter']) && $thisfile_id3v2_flags['isfooter']) { |
426 $footer = fread($this->getid3->fp, 10); |
427 $footer = $this->fread(10); |
427 if (substr($footer, 0, 3) == '3DI') { |
428 if (substr($footer, 0, 3) == '3DI') { |
428 $thisfile_id3v2['footer'] = true; |
429 $thisfile_id3v2['footer'] = true; |
429 $thisfile_id3v2['majorversion_footer'] = ord($footer{3}); |
430 $thisfile_id3v2['majorversion_footer'] = ord($footer{3}); |
430 $thisfile_id3v2['minorversion_footer'] = ord($footer{4}); |
431 $thisfile_id3v2['minorversion_footer'] = ord($footer{4}); |
431 } |
432 } |
640 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); |
641 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); |
641 |
642 |
642 $parsedFrame['description'] = $frame_description; |
643 $parsedFrame['description'] = $frame_description; |
643 $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); |
644 $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding))); |
644 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
645 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
645 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = trim(getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data'])); |
646 $commentkey = ($parsedFrame['description'] ? $parsedFrame['description'] : (isset($info['id3v2']['comments'][$parsedFrame['framenameshort']]) ? count($info['id3v2']['comments'][$parsedFrame['framenameshort']]) : 0)); |
|
647 if (!isset($info['id3v2']['comments'][$parsedFrame['framenameshort']]) || !array_key_exists($commentkey, $info['id3v2']['comments'][$parsedFrame['framenameshort']])) { |
|
648 $info['id3v2']['comments'][$parsedFrame['framenameshort']][$commentkey] = trim(getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data'])); |
|
649 } else { |
|
650 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = trim(getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data'])); |
|
651 } |
646 } |
652 } |
647 //unset($parsedFrame['data']); do not unset, may be needed elsewhere, e.g. for replaygain |
653 //unset($parsedFrame['data']); do not unset, may be needed elsewhere, e.g. for replaygain |
648 |
654 |
649 |
655 |
650 } elseif ($parsedFrame['frame_name']{0} == 'T') { // 4.2. T??[?] Text information frame |
656 } elseif ($parsedFrame['frame_name']{0} == 'T') { // 4.2. T??[?] Text information frame |
1075 $parsedFrame['language'] = $frame_language; |
1081 $parsedFrame['language'] = $frame_language; |
1076 $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); |
1082 $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false); |
1077 $parsedFrame['description'] = $frame_description; |
1083 $parsedFrame['description'] = $frame_description; |
1078 $parsedFrame['data'] = $frame_text; |
1084 $parsedFrame['data'] = $frame_text; |
1079 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
1085 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { |
1080 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); |
1086 $commentkey = ($parsedFrame['description'] ? $parsedFrame['description'] : (!empty($info['id3v2']['comments'][$parsedFrame['framenameshort']]) ? count($info['id3v2']['comments'][$parsedFrame['framenameshort']]) : 0)); |
|
1087 if (!isset($info['id3v2']['comments'][$parsedFrame['framenameshort']]) || !array_key_exists($commentkey, $info['id3v2']['comments'][$parsedFrame['framenameshort']])) { |
|
1088 $info['id3v2']['comments'][$parsedFrame['framenameshort']][$commentkey] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); |
|
1089 } else { |
|
1090 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']); |
|
1091 } |
1081 } |
1092 } |
1082 |
1093 |
1083 } |
1094 } |
1084 |
1095 |
1085 } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'RVA2')) { // 4.11 RVA2 Relative volume adjustment (2) (ID3v2.4+ only) |
1096 } elseif (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'RVA2')) { // 4.11 RVA2 Relative volume adjustment (2) (ID3v2.4+ only) |
1883 $frame_offset += 4; |
1894 $frame_offset += 4; |
1884 $parsedFrame['indexpoints'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); |
1895 $parsedFrame['indexpoints'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2)); |
1885 $frame_offset += 2; |
1896 $frame_offset += 2; |
1886 $parsedFrame['bitsperpoint'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); |
1897 $parsedFrame['bitsperpoint'] = ord(substr($parsedFrame['data'], $frame_offset++, 1)); |
1887 $frame_bytesperpoint = ceil($parsedFrame['bitsperpoint'] / 8); |
1898 $frame_bytesperpoint = ceil($parsedFrame['bitsperpoint'] / 8); |
1888 for ($i = 0; $i < $frame_indexpoints; $i++) { |
1899 for ($i = 0; $i < $parsedFrame['indexpoints']; $i++) { |
1889 $parsedFrame['indexes'][$i] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesperpoint)); |
1900 $parsedFrame['indexes'][$i] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, $frame_bytesperpoint)); |
1890 $frame_offset += $frame_bytesperpoint; |
1901 $frame_offset += $frame_bytesperpoint; |
1891 } |
1902 } |
1892 unset($parsedFrame['data']); |
1903 unset($parsedFrame['data']); |
1893 |
1904 |