[SPIP] ~maj v3.2.9-->v3.2.11
[lhc/web/www.git] / www / plugins-dist / medias / lib / getid3 / module.misc.cue.php
1 <?php
2
3 /////////////////////////////////////////////////////////////////
4 /// getID3() by James Heinrich <info@getid3.org> //
5 // available at https://github.com/JamesHeinrich/getID3 //
6 // or https://www.getid3.org //
7 // or http://getid3.sourceforge.net //
8 // see readme.txt for more details //
9 /////////////////////////////////////////////////////////////////
10 // //
11 // module.misc.cue.php //
12 // module for analyzing CUEsheet files //
13 // dependencies: NONE //
14 // //
15 /////////////////////////////////////////////////////////////////
16 // //
17 // Module originally written [2009-Mar-25] by //
18 // Nigel Barnes <ngbarnesØhotmail*com> //
19 // Minor reformatting and similar small changes to integrate //
20 // into getID3 by James Heinrich <info@getid3.org> //
21 // ///
22 /////////////////////////////////////////////////////////////////
23
24 /*
25 * CueSheet parser by Nigel Barnes.
26 *
27 * This is a PHP conversion of CueSharp 0.5 by Wyatt O'Day (wyday.com/cuesharp)
28 */
29
30 /**
31 * A CueSheet class used to open and parse cuesheets.
32 *
33 */
34
35 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
36 exit;
37 }
38
39 class getid3_cue extends getid3_handler
40 {
41 public $cuesheet = array();
42
43 /**
44 * @return bool
45 */
46 public function Analyze() {
47 $info = &$this->getid3->info;
48
49 $info['fileformat'] = 'cue';
50 $this->readCueSheetFilename($info['filenamepath']);
51 $info['cue'] = $this->cuesheet;
52 return true;
53 }
54
55 /**
56 * @param string $filename
57 *
58 * @return array
59 */
60 public function readCueSheetFilename($filename)
61 {
62 $filedata = file_get_contents($filename);
63 return $this->readCueSheet($filedata);
64 }
65
66 /**
67 * Parses a cue sheet file.
68 *
69 * @param string $filedata
70 *
71 * @return array
72 */
73 public function readCueSheet(&$filedata)
74 {
75 $cue_lines = array();
76 foreach (explode("\n", str_replace("\r", null, $filedata)) as $line)
77 {
78 if ( (strlen($line) > 0) && ($line[0] != '#'))
79 {
80 $cue_lines[] = trim($line);
81 }
82 }
83 $this->parseCueSheet($cue_lines);
84
85 return $this->cuesheet;
86 }
87
88 /**
89 * Parses the cue sheet array.
90 *
91 * @param array $file - The cuesheet as an array of each line.
92 */
93 public function parseCueSheet($file)
94 {
95 //-1 means still global, all others are track specific
96 $track_on = -1;
97
98 for ($i=0; $i < count($file); $i++)
99 {
100 list($key) = explode(' ', strtolower($file[$i]), 2);
101 switch ($key)
102 {
103 case 'catalog':
104 case 'cdtextfile':
105 case 'isrc':
106 case 'performer':
107 case 'songwriter':
108 case 'title':
109 $this->parseString($file[$i], $track_on);
110 break;
111 case 'file':
112 $currentFile = $this->parseFile($file[$i]);
113 break;
114 case 'flags':
115 $this->parseFlags($file[$i], $track_on);
116 break;
117 case 'index':
118 case 'postgap':
119 case 'pregap':
120 $this->parseIndex($file[$i], $track_on);
121 break;
122 case 'rem':
123 $this->parseComment($file[$i], $track_on);
124 break;
125 case 'track':
126 $track_on++;
127 $this->parseTrack($file[$i], $track_on);
128 if (isset($currentFile)) // if there's a file
129 {
130 $this->cuesheet['tracks'][$track_on]['datafile'] = $currentFile;
131 }
132 break;
133 default:
134 //save discarded junk and place string[] with track it was found in
135 $this->parseGarbage($file[$i], $track_on);
136 break;
137 }
138 }
139 }
140
141 /**
142 * Parses the REM command.
143 *
144 * @param string $line - The line in the cue file that contains the TRACK command.
145 * @param integer $track_on - The track currently processing.
146 */
147 public function parseComment($line, $track_on)
148 {
149 $explodedline = explode(' ', $line, 3);
150 $comment_REM = (isset($explodedline[0]) ? $explodedline[0] : '');
151 $comment_type = (isset($explodedline[1]) ? $explodedline[1] : '');
152 $comment_data = (isset($explodedline[2]) ? $explodedline[2] : '');
153 if (($comment_REM == 'REM') && $comment_type) {
154 $comment_type = strtolower($comment_type);
155 $commment_data = trim($comment_data, ' "');
156 if ($track_on != -1) {
157 $this->cuesheet['tracks'][$track_on]['comments'][$comment_type][] = $comment_data;
158 } else {
159 $this->cuesheet['comments'][$comment_type][] = $comment_data;
160 }
161 }
162 }
163
164 /**
165 * Parses the FILE command.
166 *
167 * @param string $line - The line in the cue file that contains the FILE command.
168 *
169 * @return array - Array of FILENAME and TYPE of file..
170 */
171 public function parseFile($line)
172 {
173 $line = substr($line, strpos($line, ' ') + 1);
174 $type = strtolower(substr($line, strrpos($line, ' ')));
175
176 //remove type
177 $line = substr($line, 0, strrpos($line, ' ') - 1);
178
179 //if quotes around it, remove them.
180 $line = trim($line, '"');
181
182 return array('filename'=>$line, 'type'=>$type);
183 }
184
185 /**
186 * Parses the FLAG command.
187 *
188 * @param string $line - The line in the cue file that contains the TRACK command.
189 * @param integer $track_on - The track currently processing.
190 */
191 public function parseFlags($line, $track_on)
192 {
193 if ($track_on != -1)
194 {
195 foreach (explode(' ', strtolower($line)) as $type)
196 {
197 switch ($type)
198 {
199 case 'flags':
200 // first entry in this line
201 $this->cuesheet['tracks'][$track_on]['flags'] = array(
202 '4ch' => false,
203 'data' => false,
204 'dcp' => false,
205 'pre' => false,
206 'scms' => false,
207 );
208 break;
209 case 'data':
210 case 'dcp':
211 case '4ch':
212 case 'pre':
213 case 'scms':
214 $this->cuesheet['tracks'][$track_on]['flags'][$type] = true;
215 break;
216 default:
217 break;
218 }
219 }
220 }
221 }
222
223 /**
224 * Collect any unidentified data.
225 *
226 * @param string $line - The line in the cue file that contains the TRACK command.
227 * @param integer $track_on - The track currently processing.
228 */
229 public function parseGarbage($line, $track_on)
230 {
231 if ( strlen($line) > 0 )
232 {
233 if ($track_on == -1)
234 {
235 $this->cuesheet['garbage'][] = $line;
236 }
237 else
238 {
239 $this->cuesheet['tracks'][$track_on]['garbage'][] = $line;
240 }
241 }
242 }
243
244 /**
245 * Parses the INDEX command of a TRACK.
246 *
247 * @param string $line - The line in the cue file that contains the TRACK command.
248 * @param integer $track_on - The track currently processing.
249 */
250 public function parseIndex($line, $track_on)
251 {
252 $type = strtolower(substr($line, 0, strpos($line, ' ')));
253 $line = substr($line, strpos($line, ' ') + 1);
254 $number = 0;
255
256 if ($type == 'index')
257 {
258 //read the index number
259 $number = intval(substr($line, 0, strpos($line, ' ')));
260 $line = substr($line, strpos($line, ' ') + 1);
261 }
262
263 //extract the minutes, seconds, and frames
264 $explodedline = explode(':', $line);
265 $minutes = (isset($explodedline[0]) ? $explodedline[0] : '');
266 $seconds = (isset($explodedline[1]) ? $explodedline[1] : '');
267 $frames = (isset($explodedline[2]) ? $explodedline[2] : '');
268
269 switch ($type) {
270 case 'index':
271 $this->cuesheet['tracks'][$track_on][$type][$number] = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames));
272 break;
273 case 'pregap':
274 case 'postgap':
275 $this->cuesheet['tracks'][$track_on][$type] = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames));
276 break;
277 }
278 }
279
280 /**
281 * @param string $line
282 * @param int $track_on
283 */
284 public function parseString($line, $track_on)
285 {
286 $category = strtolower(substr($line, 0, strpos($line, ' ')));
287 $line = substr($line, strpos($line, ' ') + 1);
288
289 //get rid of the quotes
290 $line = trim($line, '"');
291
292 switch ($category)
293 {
294 case 'catalog':
295 case 'cdtextfile':
296 case 'isrc':
297 case 'performer':
298 case 'songwriter':
299 case 'title':
300 if ($track_on == -1)
301 {
302 $this->cuesheet[$category] = $line;
303 }
304 else
305 {
306 $this->cuesheet['tracks'][$track_on][$category] = $line;
307 }
308 break;
309 default:
310 break;
311 }
312 }
313
314 /**
315 * Parses the TRACK command.
316 *
317 * @param string $line - The line in the cue file that contains the TRACK command.
318 * @param integer $track_on - The track currently processing.
319 */
320 public function parseTrack($line, $track_on)
321 {
322 $line = substr($line, strpos($line, ' ') + 1);
323 $track = ltrim(substr($line, 0, strpos($line, ' ')), '0');
324
325 //find the data type.
326 $datatype = strtolower(substr($line, strpos($line, ' ') + 1));
327
328 $this->cuesheet['tracks'][$track_on] = array('track_number'=>$track, 'datatype'=>$datatype);
329 }
330
331 }
332