91 {
92 $info = &$this->getid3->info;
93
94 fseek($this->getid3->fp,
$info[
'avdataoffset'], SEEK_SET);
95
96 $FLVdataLength =
$info[
'avdataend'] -
$info[
'avdataoffset'];
97 $FLVheader =
fread($this->getid3->fp, 5);
98
99 $info[
'fileformat'] =
'flv';
100 $info[
'flv'][
'header'][
'signature'] = substr($FLVheader, 0, 3);
102 3,
103 1));
105
106 $magic = 'FLV';
107 if (
$info[
'flv'][
'header'][
'signature'] != $magic) {
110 unset(
$info[
'fileformat']);
111
112 return false;
113 }
114
115 $info[
'flv'][
'header'][
'hasAudio'] = (bool) ($TypeFlags & 0x04);
116 $info[
'flv'][
'header'][
'hasVideo'] = (bool) ($TypeFlags & 0x01);
117
119 4));
120 $FLVheaderFrameLength = 9;
121 if ($FrameSizeDataLength > $FLVheaderFrameLength) {
122 fseek($this->getid3->fp,
123 $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
124 }
125 $Duration = 0;
126 $found_video = false;
127 $found_audio = false;
128 $found_meta = false;
129 $found_valid_meta_playtime = false;
130 $tagParseCount = 0;
131 $info[
'flv'][
'framecount'] = array(
'total' => 0,
'audio' => 0,
'video' => 0);
132 $flv_framecount = &
$info[
'flv'][
'framecount'];
133 while (((
ftell($this->getid3->fp) + 16) <
$info[
'avdataend']) && (($tagParseCount++ <= $this->max_frames) || !$found_valid_meta_playtime)) {
134 $ThisTagHeader =
fread($this->getid3->fp, 16);
135
137 0, 4));
139 4, 1));
141 5, 3));
143 8, 3));
145 15, 1));
146 $NextOffset =
ftell($this->getid3->fp) - 1 + $DataLength;
147 if ($Timestamp > $Duration) {
148 $Duration = $Timestamp;
149 }
150
151 $flv_framecount['total']++;
152 switch ($TagType) {
154 $flv_framecount['audio']++;
155 if (!$found_audio) {
156 $found_audio = true;
157 $info[
'flv'][
'audio'][
'audioFormat'] = ($LastHeaderByte >> 4) & 0x0F;
158 $info[
'flv'][
'audio'][
'audioRate'] = ($LastHeaderByte >> 2) & 0x03;
159 $info[
'flv'][
'audio'][
'audioSampleSize'] = ($LastHeaderByte >> 1) & 0x01;
160 $info[
'flv'][
'audio'][
'audioType'] = $LastHeaderByte & 0x01;
161 }
162 break;
163
165 $flv_framecount['video']++;
166 if (!$found_video) {
167 $found_video = true;
168 $info[
'flv'][
'video'][
'videoCodec'] = $LastHeaderByte & 0x07;
169
170 $FLVvideoHeader =
fread($this->getid3->fp, 11);
171
172 if (
$info[
'flv'][
'video'][
'videoCodec'] == self::GETID3_FLV_VIDEO_H264) {
173
174
176 0,
177 1));
179
181 4,
182 1));
184 5,
185 1));
187 6,
188 1));
190 7,
191 1));
193 8,
194 1));
195
196 if (($numOfSequenceParameterSets & 0x1F) != 0) {
197
198
199
201 9,
202 2));
203
204 $sps =
fread($this->getid3->fp, $spsSize);
205 if (strlen($sps) == $spsSize) {
206 $spsReader = new AVCSequenceParameterSetReader($sps);
207 $spsReader->readData();
208 $info[
'video'][
'resolution_x'] = $spsReader->getWidth();
209 $info[
'video'][
'resolution_y'] = $spsReader->getHeight();
210 }
211 }
212 }
213
214 } elseif (
$info[
'flv'][
'video'][
'videoCodec'] == self::GETID3_FLV_VIDEO_H263) {
215
217 3,
218 2))) >> 7;
219 $PictureSizeType = $PictureSizeType & 0x0007;
220 $info[
'flv'][
'header'][
'videoSizeType'] = $PictureSizeType;
221 switch ($PictureSizeType) {
222 case 0:
223
224
225
226
227
228
229
231 4,
232 2));
234 5,
235 2));
236 $PictureSizeEnc['x'] >>= 7;
237 $PictureSizeEnc['y'] >>= 7;
238 $info[
'video'][
'resolution_x'] = $PictureSizeEnc[
'x'] & 0xFF;
239 $info[
'video'][
'resolution_y'] = $PictureSizeEnc[
'y'] & 0xFF;
240 break;
241
242 case 1:
244 4,
245 3));
247 6,
248 3));
249 $PictureSizeEnc['x'] >>= 7;
250 $PictureSizeEnc['y'] >>= 7;
251 $info[
'video'][
'resolution_x'] = $PictureSizeEnc[
'x'] & 0xFFFF;
252 $info[
'video'][
'resolution_y'] = $PictureSizeEnc[
'y'] & 0xFFFF;
253 break;
254
255 case 2:
256 $info[
'video'][
'resolution_x'] = 352;
257 $info[
'video'][
'resolution_y'] = 288;
258 break;
259
260 case 3:
261 $info[
'video'][
'resolution_x'] = 176;
262 $info[
'video'][
'resolution_y'] = 144;
263 break;
264
265 case 4:
266 $info[
'video'][
'resolution_x'] = 128;
267 $info[
'video'][
'resolution_y'] = 96;
268 break;
269
270 case 5:
271 $info[
'video'][
'resolution_x'] = 320;
272 $info[
'video'][
'resolution_y'] = 240;
273 break;
274
275 case 6:
276 $info[
'video'][
'resolution_x'] = 160;
277 $info[
'video'][
'resolution_y'] = 120;
278 break;
279
280 default:
281 $info[
'video'][
'resolution_x'] = 0;
282 $info[
'video'][
'resolution_y'] = 0;
283 break;
284 }
285 }
286 $info[
'video'][
'pixel_aspect_ratio'] =
$info[
'video'][
'resolution_x'] /
$info[
'video'][
'resolution_y'];
287 }
288 break;
289
290
292 if (!$found_meta) {
293 $found_meta = true;
294 fseek($this->getid3->fp, -1, SEEK_CUR);
295 $datachunk =
fread($this->getid3->fp, $DataLength);
296 $AMFstream = new AMFStream($datachunk);
297 $reader =
new AMFReader($AMFstream);
298 $eventName =
$reader->readData();
301
302 $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate');
303 foreach ($copykeys as $sourcekey => $destkey) {
304 if (isset(
$info[
'flv'][
'meta'][
'onMetaData'][$sourcekey])) {
305 switch ($sourcekey) {
306 case 'width':
307 case 'height':
308 $info[
'video'][$destkey] = intval(round(
$info[
'flv'][
'meta'][
'onMetaData'][$sourcekey]));
309 break;
310 case 'audiodatarate':
312 break;
313 case 'videodatarate':
314 case 'frame_rate':
315 default:
316 $info[
'video'][$destkey] =
$info[
'flv'][
'meta'][
'onMetaData'][$sourcekey];
317 break;
318 }
319 }
320 }
321 if (!empty(
$info[
'flv'][
'meta'][
'onMetaData'][
'duration'])) {
322 $found_valid_meta_playtime = true;
323 }
324 }
325 break;
326
327 default:
328
329 break;
330 }
331 fseek($this->getid3->fp, $NextOffset, SEEK_SET);
332 }
333
334 $info[
'playtime_seconds'] = $Duration / 1000;
335 if (
$info[
'playtime_seconds'] > 0) {
336 $info[
'bitrate'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) * 8) /
$info[
'playtime_seconds'];
337 }
338
339 if (
$info[
'flv'][
'header'][
'hasAudio']) {
341 $info[
'audio'][
'sample_rate'] = $this->
FLVaudioRate($info[
'flv'][
'audio'][
'audioRate']);
342 $info[
'audio'][
'bits_per_sample'] = $this->
FLVaudioBitDepth($info[
'flv'][
'audio'][
'audioSampleSize']);
343
344 $info[
'audio'][
'channels'] =
$info[
'flv'][
'audio'][
'audioType'] + 1;
345 $info[
'audio'][
'lossless'] = (
$info[
'flv'][
'audio'][
'audioFormat'] ? false :
true);
346 $info[
'audio'][
'dataformat'] =
'flv';
347 }
348 if (!empty(
$info[
'flv'][
'header'][
'hasVideo'])) {
350 $info[
'video'][
'dataformat'] =
'flv';
351 $info[
'video'][
'lossless'] =
false;
352 }
353
354
355 if (!empty(
$info[
'flv'][
'meta'][
'onMetaData'][
'duration'])) {
356 $info[
'playtime_seconds'] =
$info[
'flv'][
'meta'][
'onMetaData'][
'duration'];
357 $info[
'bitrate'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) * 8) /
$info[
'playtime_seconds'];
358 }
359 if (isset(
$info[
'flv'][
'meta'][
'onMetaData'][
'audiocodecid'])) {
360 $info[
'audio'][
'codec'] = $this->
FLVaudioFormat($info[
'flv'][
'meta'][
'onMetaData'][
'audiocodecid']);
361 }
362 if (isset(
$info[
'flv'][
'meta'][
'onMetaData'][
'videocodecid'])) {
363 $info[
'video'][
'codec'] = $this->
FLVvideoCodec($info[
'flv'][
'meta'][
'onMetaData'][
'videocodecid']);
364 }
365
366 return true;
367 }
fseek($bytes, $whence=SEEK_SET)
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
static LittleEndian2Int($byteword, $signed=false)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
static CastAsInt($floatnum)
const H264_AVC_SEQUENCE_HEADER
const GETID3_FLV_TAG_AUDIO
const GETID3_FLV_TAG_META
const GETID3_FLV_TAG_VIDEO