source: extensions/charlies_content/getid3/getid3/module.tag.lyrics3.php @ 3318

Last change on this file since 3318 was 3318, checked in by vdigital, 15 years ago

+ Add Charlies' content to depository

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1<?php
2// +----------------------------------------------------------------------+
3// | PHP version 5                                                        |
4// +----------------------------------------------------------------------+
5// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 |
6// +----------------------------------------------------------------------+
7// | This source file is subject to version 2 of the GPL license,         |
8// | that is bundled with this package in the file license.txt and is     |
9// | available through the world-wide-web at the following url:           |
10// | http://www.gnu.org/copyleft/gpl.html                                 |
11// +----------------------------------------------------------------------+
12// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    |
13// +----------------------------------------------------------------------+
14// | Authors: James Heinrich <infoØgetid3*org>                            |
15// |          Allan Hansen <ahØartemis*dk>                                |
16// +----------------------------------------------------------------------+
17// | module.tag.lyrics3.php                                               |
18// | module for analyzing Lyrics3 tags                                    |
19// | dependencies: module.tag.apetag.php (optional)                       |
20// +----------------------------------------------------------------------+
21//
22// $Id: module.tag.lyrics3.php 3318 2009-05-20 21:54:10Z vdigital $
23
24
25class getid3_lyrics3 extends getid3_handler
26{
27
28    public function Analyze() {
29
30        $getid3 = $this->getid3;
31
32        fseek($getid3->fp, (0 - 128 - 9 - 6), SEEK_END);  // end - ID3v1 - LYRICSEND - [Lyrics3size]
33        $lyrics3_id3v1 = fread($getid3->fp, 128 + 9 + 6);
34        $lyrics3_lsz   = substr($lyrics3_id3v1,  0,   6); // Lyrics3size
35        $lyrics3_end   = substr($lyrics3_id3v1,  6,   9); // LYRICSEND or LYRICS200
36        $id3v1_tag     = substr($lyrics3_id3v1, 15, 128); // ID3v1
37
38        // Lyrics3v1, ID3v1, no APE
39        if ($lyrics3_end == 'LYRICSEND') {
40
41            $lyrics3_size    = 5100;
42            $lyrics3_offset  = filesize($getid3->filename) - 128 - $lyrics3_size;
43            $lyrics3_version = 1;
44        } 
45
46        // Lyrics3v2, ID3v1, no APE
47        elseif ($lyrics3_end == 'LYRICS200') {
48
49            // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
50            $lyrics3_size    = $lyrics3_lsz + 6 + strlen('LYRICS200');
51            $lyrics3_offset  = filesize($getid3->filename) - 128 - $lyrics3_size;
52            $lyrics3_version = 2;
53        } 
54       
55        // Lyrics3v1, no ID3v1, no APE
56        elseif (substr(strrev($lyrics3_id3v1), 0, 9) == 'DNESCIRYL') {            // strrev('LYRICSEND') = 'DNESCIRYL'
57
58            $lyrics3_size    = 5100;
59            $lyrics3_offset  = filesize($getid3->filename) - $lyrics3_size;
60            $lyrics3_version = 1;
61            $lyrics3_offset  = filesize($getid3->filename) - $lyrics3_size;
62        } 
63   
64        // Lyrics3v2, no ID3v1, no APE
65        elseif (substr(strrev($lyrics3_id3v1), 0, 9) == '002SCIRYL') {             // strrev('LYRICS200') = '002SCIRYL'
66
67            $lyrics3_size    = strrev(substr(strrev($lyrics3_id3v1), 9, 6)) + 15;   // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'  // 15 = 6 + strlen('LYRICS200')
68            $lyrics3_offset  = filesize($getid3->filename) - $lyrics3_size;
69            $lyrics3_version = 2;
70        } 
71   
72        elseif (isset($getid3->info['ape']['tag_offset_start']) && ($getid3->info['ape']['tag_offset_start'] > 15)) {
73
74            fseek($getid3->fp, $getid3->info['ape']['tag_offset_start'] - 15, SEEK_SET);
75            $lyrics3_lsz = fread($getid3->fp, 6);
76            $lyrics3_end = fread($getid3->fp, 9);
77
78           
79            // Lyrics3v1, APE, maybe ID3v1
80            if ($lyrics3_end == 'LYRICSEND') {
81
82                $lyrics3_size    = 5100;
83                $lyrics3_offset  = $getid3->info['ape']['tag_offset_start'] - $lyrics3_size;
84                $getid3->info['avdataend'] = $lyrics3_offset;
85                $lyrics3_version = 1;
86                $getid3->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
87            } 
88       
89           
90            // Lyrics3v2, APE, maybe ID3v1
91            elseif ($lyrics3_end == 'LYRICS200') {
92
93                $lyrics3_size    = $lyrics3_lsz + 15; // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
94                $lyrics3_offset  = $getid3->info['ape']['tag_offset_start'] - $lyrics3_size;
95                $lyrics3_version = 2;
96                $getid3->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
97
98            }
99        }
100       
101       
102        //// GetLyrics3Data()
103       
104       
105        if (isset($lyrics3_offset)) {
106           
107            $getid3->info['avdataend'] = $lyrics3_offset;
108           
109            if ($lyrics3_size <= 0) {
110                return false;
111            }
112
113            fseek($getid3->fp, $lyrics3_offset, SEEK_SET);
114            $raw_data = fread($getid3->fp, $lyrics3_size);
115   
116            if (substr($raw_data, 0, 11) != 'LYRICSBEGIN') {
117                if (strpos($raw_data, 'LYRICSBEGIN') !== false) {
118   
119                    $getid3->warning('"LYRICSBEGIN" expected at '.$lyrics3_offset.' but actually found at '.($lyrics3_offset + strpos($raw_data, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$lyrics3_version);
120                    $getid3->info['avdataend'] = $lyrics3_offset + strpos($raw_data, 'LYRICSBEGIN');
121                    $parsed_lyrics3['tag_offset_start'] = $getid3->info['avdataend'];
122                    $raw_data = substr($raw_data, strpos($raw_data, 'LYRICSBEGIN'));
123                    $lyrics3_size = strlen($raw_data);
124                }
125                else {
126                    throw new getid3_exception('"LYRICSBEGIN" expected at '.$lyrics3_offset.' but found "'.substr($raw_data, 0, 11).'" instead.');
127                }
128   
129            }
130   
131            $parsed_lyrics3['raw']['lyrics3version'] = $lyrics3_version;
132            $parsed_lyrics3['raw']['lyrics3tagsize'] = $lyrics3_size;
133            $parsed_lyrics3['tag_offset_start']      = $lyrics3_offset;
134            $parsed_lyrics3['tag_offset_end']        = $lyrics3_offset + $lyrics3_size;
135   
136            switch ($lyrics3_version) {
137   
138                case 1:
139                    if (substr($raw_data, strlen($raw_data) - 9, 9) == 'LYRICSEND') {
140                        $parsed_lyrics3['raw']['LYR'] = trim(substr($raw_data, 11, strlen($raw_data) - 11 - 9));
141                        getid3_lyrics3::Lyrics3LyricsTimestampParse($parsed_lyrics3);
142                    }
143                    else {
144                        throw new getid3_exception('"LYRICSEND" expected at '.(ftell($getid3->fp) - 11 + $lyrics3_size - 9).' but found "'.substr($raw_data, strlen($raw_data) - 9, 9).'" instead.');
145                    }
146                    break;
147   
148                case 2:
149                    if (substr($raw_data, strlen($raw_data) - 9, 9) == 'LYRICS200') {
150                        $parsed_lyrics3['raw']['unparsed'] = substr($raw_data, 11, strlen($raw_data) - 11 - 9 - 6); // LYRICSBEGIN + LYRICS200 + LSZ
151                        $raw_data = $parsed_lyrics3['raw']['unparsed'];
152                        while (strlen($raw_data) > 0) {
153                            $fieldname = substr($raw_data, 0, 3);
154                            $fieldsize = (int)substr($raw_data, 3, 5);
155                            $parsed_lyrics3['raw'][$fieldname] = substr($raw_data, 8, $fieldsize);
156                            $raw_data  = substr($raw_data, 3 + 5 + $fieldsize);
157                        }
158   
159                        if (isset($parsed_lyrics3['raw']['IND'])) {
160                            $i = 0;
161                            foreach (array ('lyrics', 'timestamps', 'inhibitrandom') as $flagname) {
162                                if (strlen($parsed_lyrics3['raw']['IND']) > ++$i) {
163                                    $parsed_lyrics3['flags'][$flagname] = getid3_lyrics3::IntString2Bool(substr($parsed_lyrics3['raw']['IND'], $i, 1));
164                                }
165                            }
166                        }
167   
168                        foreach (array ('ETT'=>'title', 'EAR'=>'artist', 'EAL'=>'album', 'INF'=>'comment', 'AUT'=>'author') as $key => $value) {
169                            if (isset($parsed_lyrics3['raw'][$key])) {
170                                $parsed_lyrics3['comments'][$value][] = trim($parsed_lyrics3['raw'][$key]);
171                            }
172                        }
173   
174                        if (isset($parsed_lyrics3['raw']['IMG'])) {
175                            foreach (explode("\r\n", $parsed_lyrics3['raw']['IMG']) as $key => $image_string) {
176                                if (strpos($image_string, '||') !== false) {
177                                    $imagearray = explode('||', $image_string);
178                                    $parsed_lyrics3['images'][$key]['filename']    = @$imagearray[0];
179                                    $parsed_lyrics3['images'][$key]['description'] = @$imagearray[1];
180                                    $parsed_lyrics3['images'][$key]['timestamp']   = getid3_lyrics3::Lyrics3Timestamp2Seconds(@$imagearray[2]);
181                                }
182                            }
183                        }
184                       
185                        if (isset($parsed_lyrics3['raw']['LYR'])) {
186                            getid3_lyrics3::Lyrics3LyricsTimestampParse($parsed_lyrics3);
187                        }
188                    }
189                      else {
190                        throw new getid3_exception('"LYRICS200" expected at '.(ftell($getid3->fp) - 11 + $lyrics3_size - 9).' but found "'.substr($raw_data, strlen($raw_data) - 9, 9).'" instead.');
191                    }
192                    break;
193   
194                default:
195                    throw new getid3_exception('Cannot process Lyrics3 version '.$lyrics3_version.' (only v1 and v2)');
196            }
197   
198            if (isset($getid3->info['id3v1']['tag_offset_start']) && ($getid3->info['id3v1']['tag_offset_start'] < $parsed_lyrics3['tag_offset_end'])) {
199                $getid3->warning('ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data');
200                unset($getid3->info['id3v1']);
201            }
202   
203            $getid3->info['lyrics3'] = $parsed_lyrics3;
204   
205   
206            // Check for APE tag after lyrics3
207            if (!@$getid3->info['ape'] && $getid3->option_tag_apetag && class_exists('getid3_apetag')) {
208                $apetag = new getid3_apetag($getid3);
209                $apetag->option_override_end_offset = $getid3->info['lyrics3']['tag_offset_start'];
210                $apetag->Analyze();
211            }
212        }
213
214        return true;
215    }
216   
217
218   
219   
220    public static function Lyrics3Timestamp2Seconds($rawtimestamp) {
221        if (ereg('^\\[([0-9]{2}):([0-9]{2})\\]$', $rawtimestamp, $regs)) {
222            return (int)(($regs[1] * 60) + $regs[2]);
223        }
224        return false;
225    }
226
227   
228   
229    public static function Lyrics3LyricsTimestampParse(&$lyrics3_data) {
230
231        $lyrics_array = explode("\r\n", $lyrics3_data['raw']['LYR']);
232        foreach ($lyrics_array as $key => $lyric_line) {
233           
234            while (ereg('^(\\[[0-9]{2}:[0-9]{2}\\])', $lyric_line, $regs)) {
235                $this_line_timestamps[] = getid3_lyrics3::Lyrics3Timestamp2Seconds($regs[0]);
236                $lyric_line = str_replace($regs[0], '', $lyric_line);
237            }
238            $no_timestamp_lyrics_array[$key] = $lyric_line;
239            if (@is_array($this_line_timestamps)) {
240                sort($this_line_timestamps);
241                foreach ($this_line_timestamps as $timestampkey => $timestamp) {
242                    if (isset($lyrics3_data['synchedlyrics'][$timestamp])) {
243                        // timestamps only have a 1-second resolution, it's possible that multiple lines
244                        // could have the same timestamp, if so, append
245                        $lyrics3_data['synchedlyrics'][$timestamp] .= "\r\n".$lyric_line;
246                    } else {
247                        $lyrics3_data['synchedlyrics'][$timestamp] = $lyric_line;
248                    }
249                }
250            }
251            unset($this_line_timestamps);
252            $regs = array ();
253        }
254        $lyrics3_data['unsynchedlyrics'] = implode("\r\n", $no_timestamp_lyrics_array);
255        if (isset($lyrics3_data['synchedlyrics']) && is_array($lyrics3_data['synchedlyrics'])) {
256            ksort($lyrics3_data['synchedlyrics']);
257        }
258        return true;
259    }
260
261
262
263    public static function IntString2Bool($char) {
264       
265        return $char == '1' ? true : ($char == '0' ? false : null);
266    }
267}
268
269
270?>
Note: See TracBrowser for help on using the repository browser.