function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData = false) { //$start_time = microtime(true); fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); $FLVdataLength = $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']; $FLVheader = fread($fd, 5); $ThisFileInfo['fileformat'] = 'flv'; $ThisFileInfo['flv']['header']['signature'] = substr($FLVheader, 0, 3); $ThisFileInfo['flv']['header']['version'] = getid3_lib::BigEndian2Int(substr($FLVheader, 3, 1)); $TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1)); if ($ThisFileInfo['flv']['header']['signature'] != 'FLV') { $ThisFileInfo['error'][] = 'Expecting "FLV" at offset ' . $ThisFileInfo['avdataoffset'] . ', found "' . $ThisFileInfo['flv']['header']['signature'] . '"'; unset($ThisFileInfo['flv']); unset($ThisFileInfo['fileformat']); return false; } $ThisFileInfo['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x4); $ThisFileInfo['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x1); $FrameSizeDataLength = getid3_lib::BigEndian2Int(fread($fd, 4)); $FLVheaderFrameLength = 9; if ($FrameSizeDataLength > $FLVheaderFrameLength) { fseek($fd, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR); } //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>'; $Duration = 0; $found_video = false; $found_audio = false; $found_meta = false; while (ftell($fd) + 16 < $ThisFileInfo['avdataend']) { $ThisTagHeader = fread($fd, 16); $PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4)); $TagType = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 4, 1)); $DataLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 5, 3)); $Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3)); $LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1)); $NextOffset = ftell($fd) - 1 + $DataLength; if ($Timestamp > $Duration) { $Duration = $Timestamp; } //echo __LINE__.'['.ftell($fd).']=('.$TagType.')='.number_format(microtime(true) - $start_time, 3).'<br>'; switch ($TagType) { case GETID3_FLV_TAG_AUDIO: if (!$found_audio) { $found_audio = true; $ThisFileInfo['flv']['audio']['audioFormat'] = $LastHeaderByte & 0x7; $ThisFileInfo['flv']['audio']['audioRate'] = ($LastHeaderByte & 0x30) / 0x10; $ThisFileInfo['flv']['audio']['audioSampleSize'] = ($LastHeaderByte & 0x40) / 0x40; $ThisFileInfo['flv']['audio']['audioType'] = ($LastHeaderByte & 0x80) / 0x80; } break; case GETID3_FLV_TAG_VIDEO: if (!$found_video) { $found_video = true; $ThisFileInfo['flv']['video']['videoCodec'] = $LastHeaderByte & 0x7; $FLVvideoHeader = fread($fd, 11); if ($ThisFileInfo['flv']['video']['videoCodec'] != GETID3_FLV_VIDEO_VP6) { $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 3, 2)) >> 7; $PictureSizeType = $PictureSizeType & 0x7; $ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType; switch ($PictureSizeType) { case 0: //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)); //$PictureSizeEnc <<= 1; //$ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8; //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2)); //$PictureSizeEnc <<= 1; //$ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8; $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2)); $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)); $PictureSizeEnc['x'] >>= 7; $PictureSizeEnc['y'] >>= 7; $ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xff; $ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xff; break; case 1: $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3)); $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3)); $PictureSizeEnc['x'] >>= 7; $PictureSizeEnc['y'] >>= 7; $ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xffff; $ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xffff; break; case 2: $ThisFileInfo['video']['resolution_x'] = 352; $ThisFileInfo['video']['resolution_y'] = 288; break; case 3: $ThisFileInfo['video']['resolution_x'] = 176; $ThisFileInfo['video']['resolution_y'] = 144; break; case 4: $ThisFileInfo['video']['resolution_x'] = 128; $ThisFileInfo['video']['resolution_y'] = 96; break; case 5: $ThisFileInfo['video']['resolution_x'] = 320; $ThisFileInfo['video']['resolution_y'] = 240; break; case 6: $ThisFileInfo['video']['resolution_x'] = 160; $ThisFileInfo['video']['resolution_y'] = 120; break; default: $ThisFileInfo['video']['resolution_x'] = 0; $ThisFileInfo['video']['resolution_y'] = 0; break; } } } break; // Meta tag // Meta tag case GETID3_FLV_TAG_META: if (!$found_meta) { $found_meta = true; fseek($fd, -1, SEEK_CUR); $bData = fread($fd, $DataLength); $b = new AMFStream($bData); // $reader = new AMFReader(new AMFStream(fread($fd, $DataLength))); $reader = new AMFReader($b); $eventName = $reader->readData(); $ThisFileInfo['meta'][$eventName] = $reader->readData(); unset($reader); $ThisFileInfo['video']['frame_rate'] = @$ThisFileInfo['meta']['onMetaData']['framerate']; $ThisFileInfo['video']['resolution_x'] = @$ThisFileInfo['meta']['onMetaData']['width']; $ThisFileInfo['video']['resolution_y'] = @$ThisFileInfo['meta']['onMetaData']['height']; } break; default: // noop break; } fseek($fd, $NextOffset, SEEK_SET); } if ($ThisFileInfo['playtime_seconds'] = $Duration / 1000) { $ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']; } if ($ThisFileInfo['flv']['header']['hasAudio']) { $ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']); $ThisFileInfo['audio']['sample_rate'] = $this->FLVaudioRate($ThisFileInfo['flv']['audio']['audioRate']); $ThisFileInfo['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($ThisFileInfo['flv']['audio']['audioSampleSize']); $ThisFileInfo['audio']['channels'] = $ThisFileInfo['flv']['audio']['audioType'] + 1; // 0=mono,1=stereo $ThisFileInfo['audio']['lossless'] = $ThisFileInfo['flv']['audio']['audioFormat'] ? false : true; // 0=uncompressed $ThisFileInfo['audio']['dataformat'] = 'flv'; } if (@$ThisFileInfo['flv']['header']['hasVideo']) { $ThisFileInfo['video']['codec'] = $this->FLVvideoCodec($ThisFileInfo['flv']['video']['videoCodec']); $ThisFileInfo['video']['dataformat'] = 'flv'; $ThisFileInfo['video']['lossless'] = false; } return true; }
public function Analyze() { $info =& $this->getid3->info; fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); $FLVdataLength = $info['avdataend'] - $info['avdataoffset']; $FLVheader = fread($this->getid3->fp, 5); $info['fileformat'] = 'flv'; $info['flv']['header']['signature'] = substr($FLVheader, 0, 3); $info['flv']['header']['version'] = getid3_lib::BigEndian2Int(substr($FLVheader, 3, 1)); $TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1)); $magic = 'FLV'; if ($info['flv']['header']['signature'] != $magic) { $info['error'][] = 'Expecting "' . getid3_lib::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . getid3_lib::PrintHexBytes($info['flv']['header']['signature']) . '"'; unset($info['flv']); unset($info['fileformat']); return false; } $info['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x4); $info['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x1); $FrameSizeDataLength = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4)); $FLVheaderFrameLength = 9; if ($FrameSizeDataLength > $FLVheaderFrameLength) { fseek($this->getid3->fp, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR); } $Duration = 0; $found_video = false; $found_audio = false; $found_meta = false; $found_valid_meta_playtime = false; $tagParseCount = 0; $info['flv']['framecount'] = array('total' => 0, 'audio' => 0, 'video' => 0); $flv_framecount =& $info['flv']['framecount']; while (ftell($this->getid3->fp) + 16 < $info['avdataend'] && ($tagParseCount++ <= $this->max_frames || !$found_valid_meta_playtime)) { $ThisTagHeader = fread($this->getid3->fp, 16); $PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4)); $TagType = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 4, 1)); $DataLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 5, 3)); $Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3)); $LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1)); $NextOffset = ftell($this->getid3->fp) - 1 + $DataLength; if ($Timestamp > $Duration) { $Duration = $Timestamp; } $flv_framecount['total']++; switch ($TagType) { case GETID3_FLV_TAG_AUDIO: $flv_framecount['audio']++; if (!$found_audio) { $found_audio = true; $info['flv']['audio']['audioFormat'] = $LastHeaderByte >> 4 & 0xf; $info['flv']['audio']['audioRate'] = $LastHeaderByte >> 2 & 0x3; $info['flv']['audio']['audioSampleSize'] = $LastHeaderByte >> 1 & 0x1; $info['flv']['audio']['audioType'] = $LastHeaderByte & 0x1; } break; case GETID3_FLV_TAG_VIDEO: $flv_framecount['video']++; if (!$found_video) { $found_video = true; $info['flv']['video']['videoCodec'] = $LastHeaderByte & 0x7; $FLVvideoHeader = fread($this->getid3->fp, 11); if ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H264) { // this code block contributed by: moysevichØgmail*com $AVCPacketType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 0, 1)); if ($AVCPacketType == H264_AVC_SEQUENCE_HEADER) { // read AVCDecoderConfigurationRecord $configurationVersion = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 1)); $AVCProfileIndication = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 1)); $profile_compatibility = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 1)); $lengthSizeMinusOne = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 7, 1)); $numOfSequenceParameterSets = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 8, 1)); if (($numOfSequenceParameterSets & 0x1f) != 0) { // there is at least one SequenceParameterSet // read size of the first SequenceParameterSet //$spsSize = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 9, 2)); $spsSize = getid3_lib::LittleEndian2Int(substr($FLVvideoHeader, 9, 2)); // read the first SequenceParameterSet $sps = fread($this->getid3->fp, $spsSize); if (strlen($sps) == $spsSize) { // make sure that whole SequenceParameterSet was red $spsReader = new AVCSequenceParameterSetReader($sps); $spsReader->readData(); $info['video']['resolution_x'] = $spsReader->getWidth(); $info['video']['resolution_y'] = $spsReader->getHeight(); } } } // end: moysevichØgmail*com } elseif ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H263) { $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 3, 2)) >> 7; $PictureSizeType = $PictureSizeType & 0x7; $info['flv']['header']['videoSizeType'] = $PictureSizeType; switch ($PictureSizeType) { case 0: //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)); //$PictureSizeEnc <<= 1; //$info['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8; //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2)); //$PictureSizeEnc <<= 1; //$info['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8; $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2)); $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2)); $PictureSizeEnc['x'] >>= 7; $PictureSizeEnc['y'] >>= 7; $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xff; $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xff; break; case 1: $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3)); $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3)); $PictureSizeEnc['x'] >>= 7; $PictureSizeEnc['y'] >>= 7; $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xffff; $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xffff; break; case 2: $info['video']['resolution_x'] = 352; $info['video']['resolution_y'] = 288; break; case 3: $info['video']['resolution_x'] = 176; $info['video']['resolution_y'] = 144; break; case 4: $info['video']['resolution_x'] = 128; $info['video']['resolution_y'] = 96; break; case 5: $info['video']['resolution_x'] = 320; $info['video']['resolution_y'] = 240; break; case 6: $info['video']['resolution_x'] = 160; $info['video']['resolution_y'] = 120; break; default: $info['video']['resolution_x'] = 0; $info['video']['resolution_y'] = 0; break; } } $info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y']; } break; // Meta tag // Meta tag case GETID3_FLV_TAG_META: if (!$found_meta) { $found_meta = true; fseek($this->getid3->fp, -1, SEEK_CUR); $datachunk = fread($this->getid3->fp, $DataLength); $AMFstream = new AMFStream($datachunk); $reader = new AMFReader($AMFstream); $eventName = $reader->readData(); $info['flv']['meta'][$eventName] = $reader->readData(); unset($reader); $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate'); foreach ($copykeys as $sourcekey => $destkey) { if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) { switch ($sourcekey) { case 'width': case 'height': $info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey])); break; case 'audiodatarate': $info['audio'][$destkey] = getid3_lib::CastAsInt(round($info['flv']['meta']['onMetaData'][$sourcekey] * 1000)); break; case 'videodatarate': case 'frame_rate': default: $info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey]; break; } } } if (!empty($info['flv']['meta']['onMetaData']['duration'])) { $found_valid_meta_playtime = true; } } break; default: // noop break; } fseek($this->getid3->fp, $NextOffset, SEEK_SET); } $info['playtime_seconds'] = $Duration / 1000; if ($info['playtime_seconds'] > 0) { $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds']; } if ($info['flv']['header']['hasAudio']) { $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['audio']['audioFormat']); $info['audio']['sample_rate'] = $this->FLVaudioRate($info['flv']['audio']['audioRate']); $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info['flv']['audio']['audioSampleSize']); $info['audio']['channels'] = $info['flv']['audio']['audioType'] + 1; // 0=mono,1=stereo $info['audio']['lossless'] = $info['flv']['audio']['audioFormat'] ? false : true; // 0=uncompressed $info['audio']['dataformat'] = 'flv'; } if (!empty($info['flv']['header']['hasVideo'])) { $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['video']['videoCodec']); $info['video']['dataformat'] = 'flv'; $info['video']['lossless'] = false; } // Set information from meta if (!empty($info['flv']['meta']['onMetaData']['duration'])) { $info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration']; $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds']; } if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) { $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['meta']['onMetaData']['audiocodecid']); } if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) { $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['meta']['onMetaData']['videocodecid']); } return true; }
public function Analyze() { $info =& $this->getid3->info; $info['flv'] = array(); $info_flv =& $info['flv']; fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); $flv_data_length = $info['avdataend'] - $info['avdataoffset']; $flv_header = fread($this->getid3->fp, 5); $info['fileformat'] = 'flv'; $info_flv['header']['signature'] = substr($flv_header, 0, 3); $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1)); $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1)); $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x4); $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x1); $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4)); $flv_header_frame_length = 9; if ($frame_size_data_length > $flv_header_frame_length) { fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR); } $duration = 0; while (ftell($this->getid3->fp) + 1 < $info['avdataend']) { $this_tag_header = fread($this->getid3->fp, 16); $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4)); $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1)); $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3)); $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3)); $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1)); $next_offset = ftell($this->getid3->fp) - 1 + $data_length; switch ($tag_type) { case getid3_flv::TAG_AUDIO: if (!isset($info_flv['audio']['audioFormat'])) { $info_flv['audio']['audioFormat'] = $last_header_byte & 0x7; $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10; $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40; $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80; } break; case getid3_flv::TAG_VIDEO: if (!isset($info_flv['video']['videoCodec'])) { $info_flv['video']['videoCodec'] = $last_header_byte & 0x7; $flv_video_header = fread($this->getid3->fp, 11); if ($info['flv']['video']['videoCodec'] == getid3_flv::VIDEO_H264) { // this code block contributed by: moysevichØgmail*com $AVCPacketType = getid3_lib::BigEndian2Int(substr($flv_video_header, 0, 1)); if ($AVCPacketType == AVCSequenceParameterSetReader::H264_AVC_SEQUENCE_HEADER) { // read AVCDecoderConfigurationRecord $configurationVersion = getid3_lib::BigEndian2Int(substr($flv_video_header, 4, 1)); $AVCProfileIndication = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 1)); $profile_compatibility = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 1)); $lengthSizeMinusOne = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 1)); $numOfSequenceParameterSets = getid3_lib::BigEndian2Int(substr($flv_video_header, 8, 1)); if (($numOfSequenceParameterSets & 0x1f) != 0) { // there is at least one SequenceParameterSet // read size of the first SequenceParameterSet //$spsSize = getid3_lib::BigEndian2Int(substr($flv_video_header, 9, 2)); $spsSize = getid3_lib::LittleEndian2Int(substr($flv_video_header, 9, 2)); // read the first SequenceParameterSet $sps = fread($this->getid3->fp, $spsSize); if (strlen($sps) == $spsSize) { // make sure that whole SequenceParameterSet was red $spsReader = new AVCSequenceParameterSetReader($sps); $spsReader->readData(); $info['video']['resolution_x'] = $spsReader->getWidth(); $info['video']['resolution_y'] = $spsReader->getHeight(); } } } // end: moysevichØgmail*com } elseif ($info_flv['video']['videoCodec'] == getid3_flv::VIDEO_H263) { $picture_size_type = getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2)) >> 7; $picture_size_type = $picture_size_type & 0x7; $info_flv['header']['videoSizeType'] = $picture_size_type; switch ($picture_size_type) { case 0: $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2)); $picture_size_enc <<= 1; $info['video']['resolution_x'] = ($picture_size_enc & 0xff00) >> 8; $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2)); $picture_size_enc <<= 1; $info['video']['resolution_y'] = ($picture_size_enc & 0xff00) >> 8; break; case 1: $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4)); $picture_size_enc <<= 1; $info['video']['resolution_x'] = ($picture_size_enc & 0xffff0000) >> 16; $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4)); $picture_size_enc <<= 1; $info['video']['resolution_y'] = ($picture_size_enc & 0xffff0000) >> 16; break; case 2: $info['video']['resolution_x'] = 352; $info['video']['resolution_y'] = 288; break; case 3: $info['video']['resolution_x'] = 176; $info['video']['resolution_y'] = 144; break; case 4: $info['video']['resolution_x'] = 128; $info['video']['resolution_y'] = 96; break; case 5: $info['video']['resolution_x'] = 320; $info['video']['resolution_y'] = 240; break; case 6: $info['video']['resolution_x'] = 160; $info['video']['resolution_y'] = 120; break; default: $info['video']['resolution_x'] = 0; $info['video']['resolution_y'] = 0; break; } } $info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y']; } break; // Meta tag // Meta tag case getid3_flv::TAG_META: fseek($this->getid3->fp, -1, SEEK_CUR); $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length))); $event_name = $reader->readData(); $info['flv']['meta'][$event_name] = $reader->readData(); unset($reader); $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate'); foreach ($copykeys as $sourcekey => $destkey) { if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) { switch ($sourcekey) { case 'width': case 'height': $info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey])); break; case 'audiodatarate': $info['audio'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey]; break; case 'videodatarate': case 'frame_rate': default: $info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey]; break; } } } break; default: // noop break; } if ($timestamp > $duration) { $duration = $timestamp; } fseek($this->getid3->fp, $next_offset, SEEK_SET); } if ($info['playtime_seconds'] = $duration / 1000) { $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']; } if ($info_flv['header']['hasAudio']) { $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']); $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']); $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']); $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1; // 0=mono,1=stereo $info['audio']['lossless'] = $info_flv['audio']['audioFormat'] ? false : true; // 0=uncompressed $info['audio']['dataformat'] = 'flv'; } if (@$info_flv['header']['hasVideo']) { $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']); $info['video']['dataformat'] = 'flv'; $info['video']['lossless'] = false; } // Set information from meta if (isset($info['flv']['meta']['onMetaData']['duration'])) { $info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration']; } if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) { $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['meta']['onMetaData']['audiocodecid']); } if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) { $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['meta']['onMetaData']['videocodecid']); } return true; }
public function Analyze() { $info =& $this->getid3->info; $info['flv'] = array(); $info_flv =& $info['flv']; fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); $flv_data_length = $info['avdataend'] - $info['avdataoffset']; $flv_header = fread($this->getid3->fp, 5); $info['fileformat'] = 'flv'; $info_flv['header']['signature'] = substr($flv_header, 0, 3); $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1)); $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1)); $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x4); $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x1); $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4)); $flv_header_frame_length = 9; if ($frame_size_data_length > $flv_header_frame_length) { fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR); } $duration = 0; while (ftell($this->getid3->fp) + 1 < $info['avdataend']) { $this_tag_header = fread($this->getid3->fp, 16); $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4)); $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1)); $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3)); $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3)); $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1)); $next_offset = ftell($this->getid3->fp) - 1 + $data_length; switch ($tag_type) { case getid3_flv::TAG_AUDIO: if (!isset($info_flv['audio']['audioFormat'])) { $info_flv['audio']['audioFormat'] = $last_header_byte & 0x7; $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10; $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40; $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80; } break; case getid3_flv::TAG_VIDEO: if (!isset($info_flv['video']['videoCodec'])) { $info_flv['video']['videoCodec'] = $last_header_byte & 0x7; $flv_video_header = fread($this->getid3->fp, 11); if ($info_flv['video']['videoCodec'] != getid3_flv::VIDEO_VP6) { $picture_size_type = getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2)) >> 7; $picture_size_type = $picture_size_type & 0x7; $info_flv['header']['videoSizeType'] = $picture_size_type; switch ($picture_size_type) { case 0: $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2)); $picture_size_enc <<= 1; $info['video']['resolution_x'] = ($picture_size_enc & 0xff00) >> 8; $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2)); $picture_size_enc <<= 1; $info['video']['resolution_y'] = ($picture_size_enc & 0xff00) >> 8; break; case 1: $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4)); $picture_size_enc <<= 1; $info['video']['resolution_x'] = ($picture_size_enc & 0xffff0000) >> 16; $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4)); $picture_size_enc <<= 1; $info['video']['resolution_y'] = ($picture_size_enc & 0xffff0000) >> 16; break; case 2: $info['video']['resolution_x'] = 352; $info['video']['resolution_y'] = 288; break; case 3: $info['video']['resolution_x'] = 176; $info['video']['resolution_y'] = 144; break; case 4: $info['video']['resolution_x'] = 128; $info['video']['resolution_y'] = 96; break; case 5: $info['video']['resolution_x'] = 320; $info['video']['resolution_y'] = 240; break; case 6: $info['video']['resolution_x'] = 160; $info['video']['resolution_y'] = 120; break; default: $info['video']['resolution_x'] = 0; $info['video']['resolution_y'] = 0; break; } } } break; // Meta tag // Meta tag case getid3_flv::TAG_META: fseek($this->getid3->fp, -1, SEEK_CUR); $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length))); $event_name = $reader->readData(); $info['meta'][$event_name] = $reader->readData(); unset($reader); $info['video']['frame_rate'] = @$info['meta']['onMetaData']['framerate']; $info['video']['resolution_x'] = @$info['meta']['onMetaData']['width']; $info['video']['resolution_y'] = @$info['meta']['onMetaData']['height']; break; default: // noop break; } if ($timestamp > $duration) { $duration = $timestamp; } fseek($this->getid3->fp, $next_offset, SEEK_SET); } if ($info['playtime_seconds'] = $duration / 1000) { $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds']; } if ($info_flv['header']['hasAudio']) { $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']); $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']); $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']); $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1; // 0=mono,1=stereo $info['audio']['lossless'] = $info_flv['audio']['audioFormat'] ? false : true; // 0=uncompressed $info['audio']['dataformat'] = 'flv'; } if (@$info_flv['header']['hasVideo']) { $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']); $info['video']['dataformat'] = 'flv'; $info['video']['lossless'] = false; } return true; }
function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData = false) { fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET); $FLVfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']); $FLVmagic = substr($FLVfileData, 0, 3); if ($FLVmagic != 'FLV') { $ThisFileInfo['error'][] = 'Expecting "FLV" at offset ' . $ThisFileInfo['avdataoffset'] . ', found "' . $ThisFileInfo['flv']['header']['signature'] . '"'; unset($ThisFileInfo['flv']); unset($ThisFileInfo['fileformat']); return false; } $ThisFileInfo['flv']['header']['signature'] = $FLVmagic; $ThisFileInfo['flv']['header']['version'] = ord($FLVfileData[3]); $ThisFileInfo['fileformat'] = 'flv'; $TypeFlags = ord($FLVfileData[4]); $ThisFileInfo['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 4); $ThisFileInfo['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 1); $FrameSizeDataLength = getid3_lib::BigEndian2Int(substr($FLVfileData, 5, 4)); // FLV tags $CurrentOffset = $FrameSizeDataLength; $FLVdataLength = strlen($FLVfileData); $Duration = 0; $SoundFormat = null; $VideoFormat = null; while ($CurrentOffset < $FLVdataLength) { // previous tag size $PreviousTagLength = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset, 4)); $CurrentOffset += 4; $TagType = ord(substr($FLVfileData, $CurrentOffset, 1)); $DataLength = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 1, 3)); $Timestamp = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 4, 3)); switch ($TagType) { case GETID3_FLV_TAG_AUDIO: if (is_null($SoundFormat)) { $SoundInfo = ord(substr($FLVfileData, $CurrentOffset + 11, 1)); $SoundFormat = $SoundInfo & 0x7; $ThisFileInfo['flv']['audio']['audioFormat'] = $SoundFormat; $ThisFileInfo['flv']['audio']['audioRate'] = ($SoundInfo & 0x30) / 0x10; $ThisFileInfo['flv']['audio']['audioSampleSize'] = ($SoundInfo & 0x40) / 0x40; $ThisFileInfo['flv']['audio']['audioType'] = ($SoundInfo & 0x80) / 0x80; } break; case GETID3_FLV_TAG_VIDEO: if (is_null($VideoFormat)) { $VideoInfo = ord(substr($FLVfileData, $CurrentOffset + 11, 1)); $VideoFormat = $VideoInfo & 0x7; $ThisFileInfo['flv']['video']['videoCodec'] = $VideoFormat; if ($VideoFormat != GETID3_FLV_VIDEO_VP6) { $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 15, 2)) >> 7; $PictureSizeType = $PictureSizeType & 0x7; $ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType; switch ($PictureSizeType) { case 0: $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 16, 2)); $PictureSizeEnc <<= 1; $ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xff00) >> 8; $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 17, 2)); $PictureSizeEnc <<= 1; $ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xff00) >> 8; break; case 1: $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 16, 4)); $PictureSizeEnc <<= 1; $ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xffff0000) >> 16; $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 18, 4)); $PictureSizeEnc <<= 1; $ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xffff0000) >> 16; break; case 2: $ThisFileInfo['video']['resolution_x'] = 352; $ThisFileInfo['video']['resolution_y'] = 288; break; case 3: $ThisFileInfo['video']['resolution_x'] = 176; $ThisFileInfo['video']['resolution_y'] = 144; break; case 4: $ThisFileInfo['video']['resolution_x'] = 128; $ThisFileInfo['video']['resolution_y'] = 96; break; case 5: $ThisFileInfo['video']['resolution_x'] = 320; $ThisFileInfo['video']['resolution_y'] = 240; break; case 6: $ThisFileInfo['video']['resolution_x'] = 160; $ThisFileInfo['video']['resolution_y'] = 120; break; default: $ThisFileInfo['video']['resolution_x'] = 0; $ThisFileInfo['video']['resolution_y'] = 0; break; } } } break; // Meta tag // Meta tag case GETID3_FLV_TAG_META: $reader = new AMFReader(new AMFStream(substr($FLVfileData, $CurrentOffset + 11, $DataLength))); $eventName = $reader->readData(); $ThisFileInfo['meta'][$eventName] = $reader->readData(); unset($reader); $ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['meta']['onMetaData']['framerate']; $ThisFileInfo['video']['resolution_x'] = $ThisFileInfo['meta']['onMetaData']['width']; $ThisFileInfo['video']['resolution_y'] = $ThisFileInfo['meta']['onMetaData']['height']; break; default: // noop break; } if ($Timestamp > $Duration) { $Duration = $Timestamp; } $CurrentOffset += $DataLength + 11; } $ThisFileInfo['playtime_seconds'] = $Duration / 1000; $ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds']; if ($ThisFileInfo['flv']['header']['hasAudio']) { $ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']); $ThisFileInfo['audio']['sample_rate'] = $this->FLVaudioRate($ThisFileInfo['flv']['audio']['audioRate']); $ThisFileInfo['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($ThisFileInfo['flv']['audio']['audioSampleSize']); $ThisFileInfo['audio']['channels'] = $ThisFileInfo['flv']['audio']['audioType'] + 1; // 0=mono,1=stereo $ThisFileInfo['audio']['lossless'] = $ThisFileInfo['flv']['audio']['audioFormat'] ? false : true; // 0=uncompressed $ThisFileInfo['audio']['dataformat'] = 'flv'; } if (@$ThisFileInfo['flv']['header']['hasVideo']) { $ThisFileInfo['video']['codec'] = $this->FLVvideoCodec($ThisFileInfo['flv']['video']['videoCodec']); $ThisFileInfo['video']['dataformat'] = 'flv'; $ThisFileInfo['video']['lossless'] = false; } return true; }