Mercurial > judyates
comparison e2gallerypro/e2upload/Backend/Assets/getid3/module.audio-video.flv.php @ 3:3f6b44aa6b35 judyates
[svn r4] added ability to buy stuff, from a Prints page, but it doesn't work well with the css, and it also has not been fitted into the perl make system.
author | rlm |
---|---|
date | Mon, 22 Feb 2010 08:02:39 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:670229c4eb4b | 3:3f6b44aa6b35 |
---|---|
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.archive.gzip.php | | |
18 // | module for analyzing GZIP files | | |
19 // | dependencies: NONE | | |
20 // +----------------------------------------------------------------------+ | |
21 // | FLV module by Seth Kaufman <sethØwhirl-i.gig*com> | | |
22 // | | | |
23 // | * version 0.1 (26 June 2005) | | |
24 // | | | |
25 // | minor modifications by James Heinrich <infoØgetid3*org> | | |
26 // | * version 0.1.1 (15 July 2005) | | |
27 // | | | |
28 // | Support for On2 VP6 codec and meta information by | | |
29 // | Steve Webster <steve.websterØfeaturecreep*com> | | |
30 // | * version 0.2 (22 February 2006) | | |
31 // | | | |
32 // | Modified to not read entire file into memory | | |
33 // | by James Heinrich <infoØgetid3*org> | | |
34 // | * version 0.3 (15 June 2006) | | |
35 // | | | |
36 // | Modifications by Allan Hansen <ahØartemis*dk> | | |
37 // | Adapted module for PHP5 and getID3 2.0.0. | | |
38 // +----------------------------------------------------------------------+ | |
39 // | |
40 // $Id: module.audio-video.flv.php,v 1.7 2006/11/10 11:20:12 ah Exp $ | |
41 | |
42 | |
43 | |
44 class getid3_flv extends getid3_handler | |
45 { | |
46 | |
47 const TAG_AUDIO = 8; | |
48 const TAG_VIDEO = 9; | |
49 const TAG_META = 18; | |
50 | |
51 const VIDEO_H263 = 2; | |
52 const VIDEO_SCREEN = 3; | |
53 const VIDEO_VP6 = 4; | |
54 | |
55 | |
56 public function Analyze() | |
57 { | |
58 $info = &$this->getid3->info; | |
59 | |
60 $info['flv'] = array (); | |
61 $info_flv = &$info['flv']; | |
62 | |
63 fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); | |
64 | |
65 $flv_data_length = $info['avdataend'] - $info['avdataoffset']; | |
66 $flv_header = fread($this->getid3->fp, 5); | |
67 | |
68 $info['fileformat'] = 'flv'; | |
69 $info_flv['header']['signature'] = substr($flv_header, 0, 3); | |
70 $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1)); | |
71 $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1)); | |
72 | |
73 $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x04); | |
74 $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x01); | |
75 | |
76 $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4)); | |
77 $flv_header_frame_length = 9; | |
78 if ($frame_size_data_length > $flv_header_frame_length) { | |
79 fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR); | |
80 } | |
81 | |
82 $duration = 0; | |
83 while ((ftell($this->getid3->fp) + 1) < $info['avdataend']) { | |
84 | |
85 $this_tag_header = fread($this->getid3->fp, 16); | |
86 | |
87 $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4)); | |
88 $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1)); | |
89 $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3)); | |
90 $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3)); | |
91 $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1)); | |
92 $next_offset = ftell($this->getid3->fp) - 1 + $data_length; | |
93 | |
94 switch ($tag_type) { | |
95 | |
96 case getid3_flv::TAG_AUDIO: | |
97 if (!isset($info_flv['audio']['audioFormat'])) { | |
98 $info_flv['audio']['audioFormat'] = $last_header_byte & 0x07; | |
99 $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10; | |
100 $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40; | |
101 $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80; | |
102 } | |
103 break; | |
104 | |
105 | |
106 case getid3_flv::TAG_VIDEO: | |
107 if (!isset($info_flv['video']['videoCodec'])) { | |
108 $info_flv['video']['videoCodec'] = $last_header_byte & 0x07; | |
109 | |
110 $flv_video_header = fread($this->getid3->fp, 11); | |
111 | |
112 if ($info_flv['video']['videoCodec'] != getid3_flv::VIDEO_VP6) { | |
113 | |
114 $picture_size_type = (getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2))) >> 7; | |
115 $picture_size_type = $picture_size_type & 0x0007; | |
116 $info_flv['header']['videoSizeType'] = $picture_size_type; | |
117 | |
118 switch ($picture_size_type) { | |
119 case 0: | |
120 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2)); | |
121 $picture_size_enc <<= 1; | |
122 $info['video']['resolution_x'] = ($picture_size_enc & 0xFF00) >> 8; | |
123 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2)); | |
124 $picture_size_enc <<= 1; | |
125 $info['video']['resolution_y'] = ($picture_size_enc & 0xFF00) >> 8; | |
126 break; | |
127 | |
128 case 1: | |
129 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4)); | |
130 $picture_size_enc <<= 1; | |
131 $info['video']['resolution_x'] = ($picture_size_enc & 0xFFFF0000) >> 16; | |
132 | |
133 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4)); | |
134 $picture_size_enc <<= 1; | |
135 $info['video']['resolution_y'] = ($picture_size_enc & 0xFFFF0000) >> 16; | |
136 break; | |
137 | |
138 case 2: | |
139 $info['video']['resolution_x'] = 352; | |
140 $info['video']['resolution_y'] = 288; | |
141 break; | |
142 | |
143 case 3: | |
144 $info['video']['resolution_x'] = 176; | |
145 $info['video']['resolution_y'] = 144; | |
146 break; | |
147 | |
148 case 4: | |
149 $info['video']['resolution_x'] = 128; | |
150 $info['video']['resolution_y'] = 96; | |
151 break; | |
152 | |
153 case 5: | |
154 $info['video']['resolution_x'] = 320; | |
155 $info['video']['resolution_y'] = 240; | |
156 break; | |
157 | |
158 case 6: | |
159 $info['video']['resolution_x'] = 160; | |
160 $info['video']['resolution_y'] = 120; | |
161 break; | |
162 | |
163 default: | |
164 $info['video']['resolution_x'] = 0; | |
165 $info['video']['resolution_y'] = 0; | |
166 break; | |
167 } | |
168 } | |
169 } | |
170 break; | |
171 | |
172 | |
173 // Meta tag | |
174 case getid3_flv::TAG_META: | |
175 | |
176 fseek($this->getid3->fp, -1, SEEK_CUR); | |
177 $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length))); | |
178 $event_name = $reader->readData(); | |
179 $info['meta'][$event_name] = $reader->readData(); | |
180 unset($reader); | |
181 | |
182 $info['video']['frame_rate'] = @$info['meta']['onMetaData']['framerate']; | |
183 $info['video']['resolution_x'] = @$info['meta']['onMetaData']['width']; | |
184 $info['video']['resolution_y'] = @$info['meta']['onMetaData']['height']; | |
185 break; | |
186 | |
187 default: | |
188 // noop | |
189 break; | |
190 } | |
191 | |
192 if ($timestamp > $duration) { | |
193 $duration = $timestamp; | |
194 } | |
195 | |
196 fseek($this->getid3->fp, $next_offset, SEEK_SET); | |
197 } | |
198 | |
199 if ($info['playtime_seconds'] = $duration / 1000) { | |
200 $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']; | |
201 } | |
202 | |
203 if ($info_flv['header']['hasAudio']) { | |
204 $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']); | |
205 $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']); | |
206 $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']); | |
207 | |
208 $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1; // 0=mono,1=stereo | |
209 $info['audio']['lossless'] = ($info_flv['audio']['audioFormat'] ? false : true); // 0=uncompressed | |
210 $info['audio']['dataformat'] = 'flv'; | |
211 } | |
212 if (@$info_flv['header']['hasVideo']) { | |
213 $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']); | |
214 $info['video']['dataformat'] = 'flv'; | |
215 $info['video']['lossless'] = false; | |
216 } | |
217 | |
218 return true; | |
219 } | |
220 | |
221 | |
222 public static function FLVaudioFormat($id) { | |
223 | |
224 static $lookup = array( | |
225 0 => 'uncompressed', | |
226 1 => 'ADPCM', | |
227 2 => 'mp3', | |
228 5 => 'Nellymoser 8kHz mono', | |
229 6 => 'Nellymoser', | |
230 ); | |
231 return (@$lookup[$id] ? @$lookup[$id] : false); | |
232 } | |
233 | |
234 | |
235 public static function FLVaudioRate($id) { | |
236 | |
237 static $lookup = array( | |
238 0 => 5500, | |
239 1 => 11025, | |
240 2 => 22050, | |
241 3 => 44100, | |
242 ); | |
243 return (@$lookup[$id] ? @$lookup[$id] : false); | |
244 } | |
245 | |
246 | |
247 public static function FLVaudioBitDepth($id) { | |
248 | |
249 static $lookup = array( | |
250 0 => 8, | |
251 1 => 16, | |
252 ); | |
253 return (@$lookup[$id] ? @$lookup[$id] : false); | |
254 } | |
255 | |
256 | |
257 public static function FLVvideoCodec($id) { | |
258 | |
259 static $lookup = array( | |
260 getid3_flv::VIDEO_H263 => 'Sorenson H.263', | |
261 getid3_flv::VIDEO_SCREEN => 'Screen video', | |
262 getid3_flv::VIDEO_VP6 => 'On2 VP6', | |
263 ); | |
264 return (@$lookup[$id] ? @$lookup[$id] : false); | |
265 } | |
266 } | |
267 | |
268 | |
269 | |
270 class AMFStream | |
271 { | |
272 public $bytes; | |
273 public $pos; | |
274 | |
275 | |
276 public function AMFStream($bytes) { | |
277 | |
278 $this->bytes = $bytes; | |
279 $this->pos = 0; | |
280 } | |
281 | |
282 | |
283 public function readByte() { | |
284 | |
285 return getid3_lib::BigEndian2Int(substr($this->bytes, $this->pos++, 1)); | |
286 } | |
287 | |
288 | |
289 public function readInt() { | |
290 | |
291 return ($this->readByte() << 8) + $this->readByte(); | |
292 } | |
293 | |
294 | |
295 public function readLong() { | |
296 | |
297 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte(); | |
298 } | |
299 | |
300 | |
301 public function readDouble() { | |
302 | |
303 return getid3_lib::BigEndian2Float($this->read(8)); | |
304 } | |
305 | |
306 | |
307 public function readUTF() { | |
308 | |
309 $length = $this->readInt(); | |
310 return $this->read($length); | |
311 } | |
312 | |
313 | |
314 public function readLongUTF() { | |
315 | |
316 $length = $this->readLong(); | |
317 return $this->read($length); | |
318 } | |
319 | |
320 | |
321 public function read($length) { | |
322 | |
323 $val = substr($this->bytes, $this->pos, $length); | |
324 $this->pos += $length; | |
325 return $val; | |
326 } | |
327 | |
328 | |
329 public function peekByte() { | |
330 | |
331 $pos = $this->pos; | |
332 $val = $this->readByte(); | |
333 $this->pos = $pos; | |
334 return $val; | |
335 } | |
336 | |
337 | |
338 public function peekInt() { | |
339 | |
340 $pos = $this->pos; | |
341 $val = $this->readInt(); | |
342 $this->pos = $pos; | |
343 return $val; | |
344 } | |
345 | |
346 | |
347 public function peekLong() { | |
348 | |
349 $pos = $this->pos; | |
350 $val = $this->readLong(); | |
351 $this->pos = $pos; | |
352 return $val; | |
353 } | |
354 | |
355 | |
356 public function peekDouble() { | |
357 | |
358 $pos = $this->pos; | |
359 $val = $this->readDouble(); | |
360 $this->pos = $pos; | |
361 return $val; | |
362 } | |
363 | |
364 | |
365 public function peekUTF() { | |
366 | |
367 $pos = $this->pos; | |
368 $val = $this->readUTF(); | |
369 $this->pos = $pos; | |
370 return $val; | |
371 } | |
372 | |
373 | |
374 public function peekLongUTF() { | |
375 | |
376 $pos = $this->pos; | |
377 $val = $this->readLongUTF(); | |
378 $this->pos = $pos; | |
379 return $val; | |
380 } | |
381 } | |
382 | |
383 | |
384 | |
385 class AMFReader | |
386 { | |
387 public $stream; | |
388 | |
389 public function __construct($stream) { | |
390 | |
391 $this->stream = $stream; | |
392 } | |
393 | |
394 | |
395 public function readData() { | |
396 | |
397 $value = null; | |
398 | |
399 $type = $this->stream->readByte(); | |
400 | |
401 switch($type) { | |
402 // Double | |
403 case 0: | |
404 $value = $this->readDouble(); | |
405 break; | |
406 | |
407 // Boolean | |
408 case 1: | |
409 $value = $this->readBoolean(); | |
410 break; | |
411 | |
412 // String | |
413 case 2: | |
414 $value = $this->readString(); | |
415 break; | |
416 | |
417 // Object | |
418 case 3: | |
419 $value = $this->readObject(); | |
420 break; | |
421 | |
422 // null | |
423 case 6: | |
424 return null; | |
425 break; | |
426 | |
427 // Mixed array | |
428 case 8: | |
429 $value = $this->readMixedArray(); | |
430 break; | |
431 | |
432 // Array | |
433 case 10: | |
434 $value = $this->readArray(); | |
435 break; | |
436 | |
437 // Date | |
438 case 11: | |
439 $value = $this->readDate(); | |
440 break; | |
441 | |
442 // Long string | |
443 case 13: | |
444 $value = $this->readLongString(); | |
445 break; | |
446 | |
447 // XML (handled as string) | |
448 case 15: | |
449 $value = $this->readXML(); | |
450 break; | |
451 | |
452 // Typed object (handled as object) | |
453 case 16: | |
454 $value = $this->readTypedObject(); | |
455 break; | |
456 | |
457 // Long string | |
458 default: | |
459 $value = '(unknown or unsupported data type)'; | |
460 break; | |
461 } | |
462 | |
463 return $value; | |
464 } | |
465 | |
466 | |
467 public function readDouble() { | |
468 | |
469 return $this->stream->readDouble(); | |
470 } | |
471 | |
472 | |
473 public function readBoolean() { | |
474 | |
475 return $this->stream->readByte() == 1; | |
476 } | |
477 | |
478 | |
479 public function readString() { | |
480 | |
481 return $this->stream->readUTF(); | |
482 } | |
483 | |
484 | |
485 public function readObject() { | |
486 | |
487 // Get highest numerical index - ignored | |
488 $highestIndex = $this->stream->readLong(); | |
489 | |
490 $data = array(); | |
491 | |
492 while ($key = $this->stream->readUTF()) { | |
493 // Mixed array record ends with empty string (0x00 0x00) and 0x09 | |
494 if (($key == '') && ($this->stream->peekByte() == 0x09)) { | |
495 // Consume byte | |
496 $this->stream->readByte(); | |
497 break; | |
498 } | |
499 | |
500 $data[$key] = $this->readData(); | |
501 } | |
502 | |
503 return $data; | |
504 } | |
505 | |
506 | |
507 public function readMixedArray() { | |
508 | |
509 // Get highest numerical index - ignored | |
510 $highestIndex = $this->stream->readLong(); | |
511 | |
512 $data = array(); | |
513 | |
514 while ($key = $this->stream->readUTF()) { | |
515 // Mixed array record ends with empty string (0x00 0x00) and 0x09 | |
516 if (($key == '') && ($this->stream->peekByte() == 0x09)) { | |
517 // Consume byte | |
518 $this->stream->readByte(); | |
519 break; | |
520 } | |
521 | |
522 if (is_numeric($key)) { | |
523 $key = (float) $key; | |
524 } | |
525 | |
526 $data[$key] = $this->readData(); | |
527 } | |
528 | |
529 return $data; | |
530 } | |
531 | |
532 | |
533 public function readArray() { | |
534 | |
535 $length = $this->stream->readLong(); | |
536 | |
537 $data = array(); | |
538 | |
539 for ($i = 0; $i < count($length); $i++) { | |
540 $data[] = $this->readData(); | |
541 } | |
542 | |
543 return $data; | |
544 } | |
545 | |
546 | |
547 public function readDate() { | |
548 | |
549 $timestamp = $this->stream->readDouble(); | |
550 $timezone = $this->stream->readInt(); | |
551 return $timestamp; | |
552 } | |
553 | |
554 | |
555 public function readLongString() { | |
556 | |
557 return $this->stream->readLongUTF(); | |
558 } | |
559 | |
560 | |
561 public function readXML() { | |
562 | |
563 return $this->stream->readLongUTF(); | |
564 } | |
565 | |
566 | |
567 public function readTypedObject() { | |
568 | |
569 $className = $this->stream->readUTF(); | |
570 return $this->readObject(); | |
571 } | |
572 } | |
573 | |
574 ?> |