Mercurial > judyates
view e2gallerypro/e2upload/Backend/Assets/getid3/module.audio-video.flv.php @ 20:1038db2374ec judyates
change address
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 08 Sep 2013 00:47:09 -0400 |
parents | 3f6b44aa6b35 |
children |
line wrap: on
line source
1 <?php2 // +----------------------------------------------------------------------+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 $44 class getid3_flv extends getid3_handler45 {47 const TAG_AUDIO = 8;48 const TAG_VIDEO = 9;49 const TAG_META = 18;51 const VIDEO_H263 = 2;52 const VIDEO_SCREEN = 3;53 const VIDEO_VP6 = 4;56 public function Analyze()57 {58 $info = &$this->getid3->info;60 $info['flv'] = array ();61 $info_flv = &$info['flv'];63 fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);65 $flv_data_length = $info['avdataend'] - $info['avdataoffset'];66 $flv_header = fread($this->getid3->fp, 5);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));73 $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x04);74 $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x01);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 }82 $duration = 0;83 while ((ftell($this->getid3->fp) + 1) < $info['avdataend']) {85 $this_tag_header = fread($this->getid3->fp, 16);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;94 switch ($tag_type) {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;106 case getid3_flv::TAG_VIDEO:107 if (!isset($info_flv['video']['videoCodec'])) {108 $info_flv['video']['videoCodec'] = $last_header_byte & 0x07;110 $flv_video_header = fread($this->getid3->fp, 11);112 if ($info_flv['video']['videoCodec'] != getid3_flv::VIDEO_VP6) {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;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;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;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;138 case 2:139 $info['video']['resolution_x'] = 352;140 $info['video']['resolution_y'] = 288;141 break;143 case 3:144 $info['video']['resolution_x'] = 176;145 $info['video']['resolution_y'] = 144;146 break;148 case 4:149 $info['video']['resolution_x'] = 128;150 $info['video']['resolution_y'] = 96;151 break;153 case 5:154 $info['video']['resolution_x'] = 320;155 $info['video']['resolution_y'] = 240;156 break;158 case 6:159 $info['video']['resolution_x'] = 160;160 $info['video']['resolution_y'] = 120;161 break;163 default:164 $info['video']['resolution_x'] = 0;165 $info['video']['resolution_y'] = 0;166 break;167 }168 }169 }170 break;173 // Meta tag174 case getid3_flv::TAG_META: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);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;187 default:188 // noop189 break;190 }192 if ($timestamp > $duration) {193 $duration = $timestamp;194 }196 fseek($this->getid3->fp, $next_offset, SEEK_SET);197 }199 if ($info['playtime_seconds'] = $duration / 1000) {200 $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'];201 }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']);208 $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1; // 0=mono,1=stereo209 $info['audio']['lossless'] = ($info_flv['audio']['audioFormat'] ? false : true); // 0=uncompressed210 $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 }218 return true;219 }222 public static function FLVaudioFormat($id) {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 }235 public static function FLVaudioRate($id) {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 }247 public static function FLVaudioBitDepth($id) {249 static $lookup = array(250 0 => 8,251 1 => 16,252 );253 return (@$lookup[$id] ? @$lookup[$id] : false);254 }257 public static function FLVvideoCodec($id) {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 }270 class AMFStream271 {272 public $bytes;273 public $pos;276 public function AMFStream($bytes) {278 $this->bytes = $bytes;279 $this->pos = 0;280 }283 public function readByte() {285 return getid3_lib::BigEndian2Int(substr($this->bytes, $this->pos++, 1));286 }289 public function readInt() {291 return ($this->readByte() << 8) + $this->readByte();292 }295 public function readLong() {297 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();298 }301 public function readDouble() {303 return getid3_lib::BigEndian2Float($this->read(8));304 }307 public function readUTF() {309 $length = $this->readInt();310 return $this->read($length);311 }314 public function readLongUTF() {316 $length = $this->readLong();317 return $this->read($length);318 }321 public function read($length) {323 $val = substr($this->bytes, $this->pos, $length);324 $this->pos += $length;325 return $val;326 }329 public function peekByte() {331 $pos = $this->pos;332 $val = $this->readByte();333 $this->pos = $pos;334 return $val;335 }338 public function peekInt() {340 $pos = $this->pos;341 $val = $this->readInt();342 $this->pos = $pos;343 return $val;344 }347 public function peekLong() {349 $pos = $this->pos;350 $val = $this->readLong();351 $this->pos = $pos;352 return $val;353 }356 public function peekDouble() {358 $pos = $this->pos;359 $val = $this->readDouble();360 $this->pos = $pos;361 return $val;362 }365 public function peekUTF() {367 $pos = $this->pos;368 $val = $this->readUTF();369 $this->pos = $pos;370 return $val;371 }374 public function peekLongUTF() {376 $pos = $this->pos;377 $val = $this->readLongUTF();378 $this->pos = $pos;379 return $val;380 }381 }385 class AMFReader386 {387 public $stream;389 public function __construct($stream) {391 $this->stream = $stream;392 }395 public function readData() {397 $value = null;399 $type = $this->stream->readByte();401 switch($type) {402 // Double403 case 0:404 $value = $this->readDouble();405 break;407 // Boolean408 case 1:409 $value = $this->readBoolean();410 break;412 // String413 case 2:414 $value = $this->readString();415 break;417 // Object418 case 3:419 $value = $this->readObject();420 break;422 // null423 case 6:424 return null;425 break;427 // Mixed array428 case 8:429 $value = $this->readMixedArray();430 break;432 // Array433 case 10:434 $value = $this->readArray();435 break;437 // Date438 case 11:439 $value = $this->readDate();440 break;442 // Long string443 case 13:444 $value = $this->readLongString();445 break;447 // XML (handled as string)448 case 15:449 $value = $this->readXML();450 break;452 // Typed object (handled as object)453 case 16:454 $value = $this->readTypedObject();455 break;457 // Long string458 default:459 $value = '(unknown or unsupported data type)';460 break;461 }463 return $value;464 }467 public function readDouble() {469 return $this->stream->readDouble();470 }473 public function readBoolean() {475 return $this->stream->readByte() == 1;476 }479 public function readString() {481 return $this->stream->readUTF();482 }485 public function readObject() {487 // Get highest numerical index - ignored488 $highestIndex = $this->stream->readLong();490 $data = array();492 while ($key = $this->stream->readUTF()) {493 // Mixed array record ends with empty string (0x00 0x00) and 0x09494 if (($key == '') && ($this->stream->peekByte() == 0x09)) {495 // Consume byte496 $this->stream->readByte();497 break;498 }500 $data[$key] = $this->readData();501 }503 return $data;504 }507 public function readMixedArray() {509 // Get highest numerical index - ignored510 $highestIndex = $this->stream->readLong();512 $data = array();514 while ($key = $this->stream->readUTF()) {515 // Mixed array record ends with empty string (0x00 0x00) and 0x09516 if (($key == '') && ($this->stream->peekByte() == 0x09)) {517 // Consume byte518 $this->stream->readByte();519 break;520 }522 if (is_numeric($key)) {523 $key = (float) $key;524 }526 $data[$key] = $this->readData();527 }529 return $data;530 }533 public function readArray() {535 $length = $this->stream->readLong();537 $data = array();539 for ($i = 0; $i < count($length); $i++) {540 $data[] = $this->readData();541 }543 return $data;544 }547 public function readDate() {549 $timestamp = $this->stream->readDouble();550 $timezone = $this->stream->readInt();551 return $timestamp;552 }555 public function readLongString() {557 return $this->stream->readLongUTF();558 }561 public function readXML() {563 return $this->stream->readLongUTF();564 }567 public function readTypedObject() {569 $className = $this->stream->readUTF();570 return $this->readObject();571 }572 }574 ?>