1 <?php |
1 <?php |
|
2 |
2 ///////////////////////////////////////////////////////////////// |
3 ///////////////////////////////////////////////////////////////// |
3 /// getID3() by James Heinrich <info@getid3.org> // |
4 /// getID3() by James Heinrich <info@getid3.org> // |
4 // available at http://getid3.sourceforge.net // |
5 // available at https://github.com/JamesHeinrich/getID3 // |
5 // or http://www.getid3.org // |
6 // or https://www.getid3.org // |
6 // also https://github.com/JamesHeinrich/getID3 // |
7 // or http://getid3.sourceforge.net // |
7 ///////////////////////////////////////////////////////////////// |
8 // see readme.txt for more details // |
8 // See readme.txt for more details // |
|
9 ///////////////////////////////////////////////////////////////// |
9 ///////////////////////////////////////////////////////////////// |
10 /// // |
10 /// // |
11 // module.tag.lyrics3.php // |
11 // module.tag.lyrics3.php // |
12 // module for analyzing Lyrics3 tags // |
12 // module for analyzing Lyrics3 tags // |
13 // dependencies: module.tag.apetag.php (optional) // |
13 // dependencies: module.tag.apetag.php (optional) // |
14 // /// |
14 // /// |
15 ///////////////////////////////////////////////////////////////// |
15 ///////////////////////////////////////////////////////////////// |
16 |
16 |
17 |
17 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers |
|
18 exit; |
|
19 } |
18 class getid3_lyrics3 extends getid3_handler |
20 class getid3_lyrics3 extends getid3_handler |
19 { |
21 { |
20 |
22 /** |
|
23 * @return bool |
|
24 */ |
21 public function Analyze() { |
25 public function Analyze() { |
22 $info = &$this->getid3->info; |
26 $info = &$this->getid3->info; |
23 |
27 |
24 // http://www.volweb.cz/str/tags.htm |
28 // http://www.volweb.cz/str/tags.htm |
25 |
29 |
28 return false; |
32 return false; |
29 } |
33 } |
30 |
34 |
31 $this->fseek((0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - "LYRICSEND" - [Lyrics3size] |
35 $this->fseek((0 - 128 - 9 - 6), SEEK_END); // end - ID3v1 - "LYRICSEND" - [Lyrics3size] |
32 $lyrics3_id3v1 = $this->fread(128 + 9 + 6); |
36 $lyrics3_id3v1 = $this->fread(128 + 9 + 6); |
33 $lyrics3lsz = substr($lyrics3_id3v1, 0, 6); // Lyrics3size |
37 $lyrics3lsz = (int) substr($lyrics3_id3v1, 0, 6); // Lyrics3size |
34 $lyrics3end = substr($lyrics3_id3v1, 6, 9); // LYRICSEND or LYRICS200 |
38 $lyrics3end = substr($lyrics3_id3v1, 6, 9); // LYRICSEND or LYRICS200 |
35 $id3v1tag = substr($lyrics3_id3v1, 15, 128); // ID3v1 |
39 $id3v1tag = substr($lyrics3_id3v1, 15, 128); // ID3v1 |
36 |
40 |
37 if ($lyrics3end == 'LYRICSEND') { |
41 if ($lyrics3end == 'LYRICSEND') { |
38 // Lyrics3v1, ID3v1, no APE |
42 // Lyrics3v1, ID3v1, no APE |
59 |
63 |
60 } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) { |
64 } elseif (substr(strrev($lyrics3_id3v1), 0, 9) == strrev('LYRICS200')) { |
61 |
65 |
62 // Lyrics3v2, no ID3v1, no APE |
66 // Lyrics3v2, no ID3v1, no APE |
63 |
67 |
64 $lyrics3size = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200' |
68 $lyrics3size = (int) strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200' |
65 $lyrics3offset = $info['filesize'] - $lyrics3size; |
69 $lyrics3offset = $info['filesize'] - $lyrics3size; |
66 $lyrics3version = 2; |
70 $lyrics3version = 2; |
67 |
71 |
68 } else { |
72 } else { |
69 |
73 |
94 |
98 |
95 } |
99 } |
96 |
100 |
97 } |
101 } |
98 |
102 |
99 if (isset($lyrics3offset)) { |
103 if (isset($lyrics3offset) && isset($lyrics3version) && isset($lyrics3size)) { |
100 $info['avdataend'] = $lyrics3offset; |
104 $info['avdataend'] = $lyrics3offset; |
101 $this->getLyrics3Data($lyrics3offset, $lyrics3version, $lyrics3size); |
105 $this->getLyrics3Data($lyrics3offset, $lyrics3version, $lyrics3size); |
102 |
106 |
103 if (!isset($info['ape'])) { |
107 if (!isset($info['ape'])) { |
104 if (isset($info['lyrics3']['tag_offset_start'])) { |
108 if (isset($info['lyrics3']['tag_offset_start'])) { |
105 $GETID3_ERRORARRAY = &$info['warning']; |
109 $GETID3_ERRORARRAY = &$info['warning']; |
106 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true); |
110 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true); |
107 $getid3_temp = new getID3(); |
111 $getid3_temp = new getID3(); |
108 $getid3_temp->openfile($this->getid3->filename); |
112 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp); |
109 $getid3_apetag = new getid3_apetag($getid3_temp); |
113 $getid3_apetag = new getid3_apetag($getid3_temp); |
110 $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start']; |
114 $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start']; |
111 $getid3_apetag->Analyze(); |
115 $getid3_apetag->Analyze(); |
112 if (!empty($getid3_temp->info['ape'])) { |
116 if (!empty($getid3_temp->info['ape'])) { |
113 $info['ape'] = $getid3_temp->info['ape']; |
117 $info['ape'] = $getid3_temp->info['ape']; |
139 $this->fseek($endoffset); |
150 $this->fseek($endoffset); |
140 if ($length <= 0) { |
151 if ($length <= 0) { |
141 return false; |
152 return false; |
142 } |
153 } |
143 $rawdata = $this->fread($length); |
154 $rawdata = $this->fread($length); |
|
155 |
|
156 $ParsedLyrics3 = array(); |
144 |
157 |
145 $ParsedLyrics3['raw']['lyrics3version'] = $version; |
158 $ParsedLyrics3['raw']['lyrics3version'] = $version; |
146 $ParsedLyrics3['raw']['lyrics3tagsize'] = $length; |
159 $ParsedLyrics3['raw']['lyrics3tagsize'] = $length; |
147 $ParsedLyrics3['tag_offset_start'] = $endoffset; |
160 $ParsedLyrics3['tag_offset_start'] = $endoffset; |
148 $ParsedLyrics3['tag_offset_end'] = $endoffset + $length - 1; |
161 $ParsedLyrics3['tag_offset_end'] = $endoffset + $length - 1; |
248 $info['lyrics3'] = $ParsedLyrics3; |
260 $info['lyrics3'] = $ParsedLyrics3; |
249 |
261 |
250 return true; |
262 return true; |
251 } |
263 } |
252 |
264 |
|
265 /** |
|
266 * @param string $rawtimestamp |
|
267 * |
|
268 * @return int|false |
|
269 */ |
253 public function Lyrics3Timestamp2Seconds($rawtimestamp) { |
270 public function Lyrics3Timestamp2Seconds($rawtimestamp) { |
254 if (preg_match('#^\\[([0-9]{2}):([0-9]{2})\\]$#', $rawtimestamp, $regs)) { |
271 if (preg_match('#^\\[([0-9]{2}):([0-9]{2})\\]$#', $rawtimestamp, $regs)) { |
255 return (int) (($regs[1] * 60) + $regs[2]); |
272 return (int) (($regs[1] * 60) + $regs[2]); |
256 } |
273 } |
257 return false; |
274 return false; |
258 } |
275 } |
259 |
276 |
|
277 /** |
|
278 * @param array $Lyrics3data |
|
279 * |
|
280 * @return bool |
|
281 */ |
260 public function Lyrics3LyricsTimestampParse(&$Lyrics3data) { |
282 public function Lyrics3LyricsTimestampParse(&$Lyrics3data) { |
261 $lyricsarray = explode("\r\n", $Lyrics3data['raw']['LYR']); |
283 $lyricsarray = explode("\r\n", $Lyrics3data['raw']['LYR']); |
|
284 $notimestamplyricsarray = array(); |
262 foreach ($lyricsarray as $key => $lyricline) { |
285 foreach ($lyricsarray as $key => $lyricline) { |
263 $regs = array(); |
286 $regs = array(); |
264 unset($thislinetimestamps); |
287 unset($thislinetimestamps); |
265 while (preg_match('#^(\\[[0-9]{2}:[0-9]{2}\\])#', $lyricline, $regs)) { |
288 while (preg_match('#^(\\[[0-9]{2}:[0-9]{2}\\])#', $lyricline, $regs)) { |
266 $thislinetimestamps[] = $this->Lyrics3Timestamp2Seconds($regs[0]); |
289 $thislinetimestamps[] = $this->Lyrics3Timestamp2Seconds($regs[0]); |