55 define(
'GETID3_FLV_TAG_AUDIO', 8);
56 define(
'GETID3_FLV_TAG_VIDEO', 9);
57 define(
'GETID3_FLV_TAG_META', 18);
59 define(
'GETID3_FLV_VIDEO_H263', 2);
60 define(
'GETID3_FLV_VIDEO_SCREEN', 3);
61 define(
'GETID3_FLV_VIDEO_VP6FLV', 4);
62 define(
'GETID3_FLV_VIDEO_VP6FLV_ALPHA', 5);
63 define(
'GETID3_FLV_VIDEO_SCREENV2', 6);
64 define(
'GETID3_FLV_VIDEO_H264', 7);
66 define(
'H264_AVC_SEQUENCE_HEADER', 0);
67 define(
'H264_PROFILE_BASELINE', 66);
68 define(
'H264_PROFILE_MAIN', 77);
69 define(
'H264_PROFILE_EXTENDED', 88);
70 define(
'H264_PROFILE_HIGH', 100);
71 define(
'H264_PROFILE_HIGH10', 110);
72 define(
'H264_PROFILE_HIGH422', 122);
73 define(
'H264_PROFILE_HIGH444', 144);
74 define(
'H264_PROFILE_HIGH444_PREDICTIVE', 244);
83 $info = &$this->getid3->info;
87 $FLVdataLength =
$info[
'avdataend'] -
$info[
'avdataoffset'];
88 $FLVheader = $this->
fread(5);
90 $info[
'fileformat'] =
'flv';
91 $info[
'flv'][
'header'][
'signature'] = substr($FLVheader, 0, 3);
95 if ($info[
'flv'][
'header'][
'signature'] != self::magic) {
97 unset($info[
'flv'], $info[
'fileformat']);
101 $info[
'flv'][
'header'][
'hasAudio'] = (bool) ($TypeFlags & 0x04);
102 $info[
'flv'][
'header'][
'hasVideo'] = (bool) ($TypeFlags & 0x01);
105 $FLVheaderFrameLength = 9;
106 if ($FrameSizeDataLength > $FLVheaderFrameLength) {
107 $this->
fseek($FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
110 $found_video =
false;
111 $found_audio =
false;
113 $found_valid_meta_playtime =
false;
115 $info[
'flv'][
'framecount'] = array(
'total'=>0,
'audio'=>0,
'video'=>0);
116 $flv_framecount = &$info[
'flv'][
'framecount'];
117 while ((($this->
ftell() + 16) < $info[
'avdataend']) && (($tagParseCount++ <= $this->max_frames) || !$found_valid_meta_playtime)) {
118 $ThisTagHeader = $this->
fread(16);
125 $NextOffset = $this->
ftell() - 1 + $DataLength;
126 if ($Timestamp > $Duration) {
127 $Duration = $Timestamp;
130 $flv_framecount[
'total']++;
133 $flv_framecount[
'audio']++;
136 $info[
'flv'][
'audio'][
'audioFormat'] = ($LastHeaderByte >> 4) & 0x0F;
137 $info[
'flv'][
'audio'][
'audioRate'] = ($LastHeaderByte >> 2) & 0x03;
138 $info[
'flv'][
'audio'][
'audioSampleSize'] = ($LastHeaderByte >> 1) & 0x01;
139 $info[
'flv'][
'audio'][
'audioType'] = $LastHeaderByte & 0x01;
144 $flv_framecount[
'video']++;
147 $info[
'flv'][
'video'][
'videoCodec'] = $LastHeaderByte & 0x07;
149 $FLVvideoHeader = $this->
fread(11);
163 if (($numOfSequenceParameterSets & 0x1F) != 0) {
169 $sps = $this->
fread($spsSize);
170 if (strlen($sps) == $spsSize) {
172 $spsReader->readData();
173 $info[
'video'][
'resolution_x'] = $spsReader->getWidth();
174 $info[
'video'][
'resolution_y'] = $spsReader->getHeight();
183 $PictureSizeType = $PictureSizeType & 0x0007;
184 $info[
'flv'][
'header'][
'videoSizeType'] = $PictureSizeType;
185 switch ($PictureSizeType) {
196 $info[
'video'][
'resolution_x'] = $PictureSizeEnc[
'x'] & 0xFF;
197 $info[
'video'][
'resolution_y'] = $PictureSizeEnc[
'y'] & 0xFF;
203 $info[
'video'][
'resolution_x'] = $PictureSizeEnc[
'x'] & 0xFFFF;
204 $info[
'video'][
'resolution_y'] = $PictureSizeEnc[
'y'] & 0xFFFF;
208 $info[
'video'][
'resolution_x'] = 352;
209 $info[
'video'][
'resolution_y'] = 288;
213 $info[
'video'][
'resolution_x'] = 176;
214 $info[
'video'][
'resolution_y'] = 144;
218 $info[
'video'][
'resolution_x'] = 128;
219 $info[
'video'][
'resolution_y'] = 96;
223 $info[
'video'][
'resolution_x'] = 320;
224 $info[
'video'][
'resolution_y'] = 240;
228 $info[
'video'][
'resolution_x'] = 160;
229 $info[
'video'][
'resolution_y'] = 120;
233 $info[
'video'][
'resolution_x'] = 0;
234 $info[
'video'][
'resolution_y'] = 0;
242 if (!isset($info[
'video'][
'resolution_x'])) {
245 $info[
'video'][
'resolution_x'] = ($PictureSizeEnc[
'x'] & 0xFF) << 3;
246 $info[
'video'][
'resolution_y'] = ($PictureSizeEnc[
'y'] & 0xFF) << 3;
251 if (!empty($info[
'video'][
'resolution_x']) && !empty($info[
'video'][
'resolution_y'])) {
252 $info[
'video'][
'pixel_aspect_ratio'] = $info[
'video'][
'resolution_x'] / $info[
'video'][
'resolution_y'];
261 $this->
fseek(-1, SEEK_CUR);
262 $datachunk = $this->
fread($DataLength);
265 $eventName =
$reader->readData();
266 $info[
'flv'][
'meta'][$eventName] =
$reader->readData();
269 $copykeys = array(
'framerate'=>
'frame_rate',
'width'=>
'resolution_x',
'height'=>
'resolution_y',
'audiodatarate'=>
'bitrate',
'videodatarate'=>
'bitrate');
270 foreach ($copykeys as $sourcekey => $destkey) {
271 if (isset($info[
'flv'][
'meta'][
'onMetaData'][$sourcekey])) {
272 switch ($sourcekey) {
275 $info[
'video'][$destkey] = intval(round($info[
'flv'][
'meta'][
'onMetaData'][$sourcekey]));
277 case 'audiodatarate':
278 $info[
'audio'][$destkey] =
getid3_lib::CastAsInt(round($info[
'flv'][
'meta'][
'onMetaData'][$sourcekey] * 1000));
280 case 'videodatarate':
283 $info[
'video'][$destkey] = $info[
'flv'][
'meta'][
'onMetaData'][$sourcekey];
288 if (!empty($info[
'flv'][
'meta'][
'onMetaData'][
'duration'])) {
289 $found_valid_meta_playtime =
true;
298 $this->
fseek($NextOffset);
301 $info[
'playtime_seconds'] = $Duration / 1000;
302 if ($info[
'playtime_seconds'] > 0) {
303 $info[
'bitrate'] = (($info[
'avdataend'] - $info[
'avdataoffset']) * 8) / $info[
'playtime_seconds'];
306 if ($info[
'flv'][
'header'][
'hasAudio']) {
307 $info[
'audio'][
'codec'] = self::audioFormatLookup($info[
'flv'][
'audio'][
'audioFormat']);
308 $info[
'audio'][
'sample_rate'] = self::audioRateLookup($info[
'flv'][
'audio'][
'audioRate']);
309 $info[
'audio'][
'bits_per_sample'] = self::audioBitDepthLookup($info[
'flv'][
'audio'][
'audioSampleSize']);
311 $info[
'audio'][
'channels'] = $info[
'flv'][
'audio'][
'audioType'] + 1;
312 $info[
'audio'][
'lossless'] = ($info[
'flv'][
'audio'][
'audioFormat'] ? false :
true);
313 $info[
'audio'][
'dataformat'] =
'flv';
315 if (!empty($info[
'flv'][
'header'][
'hasVideo'])) {
316 $info[
'video'][
'codec'] = self::videoCodecLookup($info[
'flv'][
'video'][
'videoCodec']);
317 $info[
'video'][
'dataformat'] =
'flv';
318 $info[
'video'][
'lossless'] =
false;
322 if (!empty($info[
'flv'][
'meta'][
'onMetaData'][
'duration'])) {
323 $info[
'playtime_seconds'] = $info[
'flv'][
'meta'][
'onMetaData'][
'duration'];
324 $info[
'bitrate'] = (($info[
'avdataend'] - $info[
'avdataoffset']) * 8) / $info[
'playtime_seconds'];
326 if (isset($info[
'flv'][
'meta'][
'onMetaData'][
'audiocodecid'])) {
327 $info[
'audio'][
'codec'] = self::audioFormatLookup($info[
'flv'][
'meta'][
'onMetaData'][
'audiocodecid']);
329 if (isset($info[
'flv'][
'meta'][
'onMetaData'][
'videocodecid'])) {
330 $info[
'video'][
'codec'] = self::videoCodecLookup($info[
'flv'][
'meta'][
'onMetaData'][
'videocodecid']);
337 static $lookup = array(
338 0 =>
'Linear PCM, platform endian',
341 3 =>
'Linear PCM, little endian',
342 4 =>
'Nellymoser 16kHz mono',
343 5 =>
'Nellymoser 8kHz mono',
345 7 =>
'G.711A-law logarithmic PCM',
346 8 =>
'G.711 mu-law logarithmic PCM',
353 15 =>
'Device-specific sound',
355 return (isset($lookup[
$id]) ? $lookup[$id] :
false);
359 static $lookup = array(
365 return (isset($lookup[
$id]) ? $lookup[$id] :
false);
369 static $lookup = array(
373 return (isset($lookup[
$id]) ? $lookup[$id] :
false);
377 static $lookup = array(
385 return (isset($lookup[
$id]) ? $lookup[$id] :
false);
394 $this->bytes =& $bytes;
403 return ($this->readByte() << 8) + $this->readByte();
407 return ($this->readByte() << 24) + ($this->readByte() << 16) + ($this->readByte() << 8) + $this->readByte();
415 $length = $this->readInt();
416 return $this->read($length);
420 $length = $this->readLong();
421 return $this->read($length);
424 public function read($length) {
425 $val = substr($this->bytes, $this->pos, $length);
426 $this->pos += $length;
432 $val = $this->readByte();
439 $val = $this->readInt();
446 $val = $this->readLong();
453 $val = $this->readDouble();
460 $val = $this->readUTF();
467 $val = $this->readLongUTF();
483 $type = $this->stream->readByte();
488 $value = $this->readDouble();
493 $value = $this->readBoolean();
498 $value = $this->readString();
503 $value = $this->readObject();
513 $value = $this->readMixedArray();
518 $value = $this->readArray();
523 $value = $this->readDate();
528 $value = $this->readLongString();
533 $value = $this->readXML();
538 $value = $this->readTypedObject();
543 $value =
'(unknown or unsupported data type)';
551 return $this->stream->readDouble();
555 return $this->stream->readByte() == 1;
559 return $this->stream->readUTF();
568 while (
$key = $this->stream->readUTF()) {
572 if ((
$key ==
'') && ($this->stream->peekByte() == 0x09)) {
574 $this->stream->readByte();
581 $highestIndex = $this->stream->readLong();
585 while (
$key = $this->stream->readUTF()) {
586 if (is_numeric(
$key)) {
592 if ((
$key ==
'') && ($this->stream->peekByte() == 0x09)) {
594 $this->stream->readByte();
601 $length = $this->stream->readLong();
604 for (
$i = 0;
$i < $length;
$i++) {
605 $data[] = $this->readData();
612 $timezone = $this->stream->readInt();
617 return $this->stream->readLongUTF();
621 return $this->stream->readLongUTF();
625 $className = $this->stream->readUTF();
626 return $this->readObject();
633 public $currentBytes = 0;
634 public $currentBits = 0;
645 $profile = $this->getBits(8);
648 $level_idc = $this->getBits(8);
649 $this->expGolombUe();
650 $this->expGolombUe();
651 $picOrderType = $this->expGolombUe();
652 if ($picOrderType == 0) {
653 $this->expGolombUe();
654 } elseif ($picOrderType == 1) {
656 $this->expGolombSe();
657 $this->expGolombSe();
658 $num_ref_frames_in_pic_order_cnt_cycle = $this->expGolombUe();
659 for (
$i = 0;
$i < $num_ref_frames_in_pic_order_cnt_cycle;
$i++) {
660 $this->expGolombSe();
663 $this->expGolombUe();
665 $pic_width_in_mbs_minus1 = $this->expGolombUe();
666 $pic_height_in_map_units_minus1 = $this->expGolombUe();
668 $frame_mbs_only_flag = $this->getBits(1);
669 if ($frame_mbs_only_flag == 0) {
673 $frame_cropping_flag = $this->getBits(1);
675 $frame_crop_left_offset = 0;
676 $frame_crop_right_offset = 0;
677 $frame_crop_top_offset = 0;
678 $frame_crop_bottom_offset = 0;
680 if ($frame_cropping_flag) {
681 $frame_crop_left_offset = $this->expGolombUe();
682 $frame_crop_right_offset = $this->expGolombUe();
683 $frame_crop_top_offset = $this->expGolombUe();
684 $frame_crop_bottom_offset = $this->expGolombUe();
689 $this->width = (($pic_width_in_mbs_minus1 + 1) * 16) - ($frame_crop_left_offset * 2) - ($frame_crop_right_offset * 2);
690 $this->height = ((2 - $frame_mbs_only_flag) * ($pic_height_in_map_units_minus1 + 1) * 16) - ($frame_crop_top_offset * 2) - ($frame_crop_bottom_offset * 2);
695 $newBits = $this->currentBits + $bits;
696 $this->currentBytes += (int)floor($newBits / 8);
697 $this->currentBits = $newBits % 8;
708 for (
$i = 0;
$i < $bits;
$i++) {
715 $significantBits = 0;
716 $bit = $this->getBit();
719 $bit = $this->getBit();
721 if ($significantBits > 31) {
726 return (1 << $significantBits) + $this->getBits($significantBits) - 1;
730 $result = $this->expGolombUe();
743 return $this->height;
static audioRateLookup($id)
const GETID3_FLV_TAG_VIDEO
const GETID3_FLV_TAG_META
const GETID3_FLV_TAG_AUDIO
getID3() by James Heinrich info@getid3.org //
if(!array_key_exists('StateId', $_REQUEST)) $id
static LittleEndian2Int($byteword, $signed=false)
$stream
PHP stream implementation.
static videoCodecLookup($id)
const GETID3_FLV_VIDEO_VP6FLV_ALPHA
static BigEndian2Float($byteword)
const GETID3_FLV_VIDEO_SCREEN
static audioFormatLookup($id)
const GETID3_FLV_VIDEO_H264
static CastAsInt($floatnum)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
foreach($mandatory_scripts as $file) $timestamp
static audioBitDepthLookup($id)
const H264_AVC_SEQUENCE_HEADER
fseek($bytes, $whence=SEEK_SET)
const GETID3_FLV_VIDEO_SCREENV2
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
const GETID3_FLV_VIDEO_VP6FLV
const GETID3_FLV_VIDEO_H263