29 {
30
31
32 $thisfile_audio = &$ThisFileInfo['audio'];
33 $thisfile_video = &$ThisFileInfo['video'];
34 $ThisFileInfo['asf'] = array();
35 $thisfile_asf = &$ThisFileInfo['asf'];
36 $thisfile_asf['comments'] = array();
37 $thisfile_asf_comments = &$thisfile_asf['comments'];
38 $thisfile_asf['header_object'] = array();
39 $thisfile_asf_headerobject = &$thisfile_asf['header_object'];
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 $ThisFileInfo['fileformat'] = 'asf';
63
64 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
65 $HeaderObjectData =
fread($fd, 30);
66
67 $thisfile_asf_headerobject['objectid'] = substr($HeaderObjectData, 0, 16);
68 $thisfile_asf_headerobject[
'objectid_guid'] = $this->
BytestringToGUID($thisfile_asf_headerobject[
'objectid']);
69 if ($thisfile_asf_headerobject['objectid'] != GETID3_ASF_Header_Object) {
70 $ThisFileInfo[
'warning'][] =
'ASF header GUID {'.$this->BytestringToGUID($thisfile_asf_headerobject[
'objectid']).
'} does not match expected "GETID3_ASF_Header_Object" GUID {'.$this->
BytestringToGUID(GETID3_ASF_Header_Object).
'}';
71 unset($ThisFileInfo['fileformat']);
72 unset($ThisFileInfo['asf']);
73 return false;
74 break;
75 }
80
81
82 $ASFHeaderData =
fread($fd, $thisfile_asf_headerobject[
'objectsize'] - 30);
83
84 $offset = 0;
85
86 for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
87 $NextObjectGUID = substr($ASFHeaderData, $offset, 16);
88 $offset += 16;
91 $offset += 8;
92 switch ($NextObjectGUID) {
93
94 case GETID3_ASF_File_Properties_Object:
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 $thisfile_asf['file_properties_object'] = array();
116 $thisfile_asf_filepropertiesobject = &$thisfile_asf['file_properties_object'];
117
118 $thisfile_asf_filepropertiesobject['objectid'] = $NextObjectGUID;
119 $thisfile_asf_filepropertiesobject['objectid_guid'] = $NextObjectGUIDtext;
120 $thisfile_asf_filepropertiesobject['objectsize'] = $NextObjectSize;
121 $thisfile_asf_filepropertiesobject['fileid'] = substr($ASFHeaderData, $offset, 16);
122 $offset += 16;
123 $thisfile_asf_filepropertiesobject[
'fileid_guid'] = $this->
BytestringToGUID($thisfile_asf_filepropertiesobject[
'fileid']);
125 $offset += 8;
127 $thisfile_asf_filepropertiesobject[
'creation_date_unix'] = $this->
FILETIMEtoUNIXtime($thisfile_asf_filepropertiesobject[
'creation_date']);
128 $offset += 8;
130 $offset += 8;
132 $offset += 8;
134 $offset += 8;
136 $offset += 8;
137 $ThisFileInfo['playtime_seconds'] = ($thisfile_asf_filepropertiesobject['play_duration'] / 10000000) - ($thisfile_asf_filepropertiesobject['preroll'] / 1000);
139 $offset += 4;
140 $thisfile_asf_filepropertiesobject['flags']['broadcast'] = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0001);
141 $thisfile_asf_filepropertiesobject['flags']['seekable'] = (bool) ($thisfile_asf_filepropertiesobject['flags_raw'] & 0x0002);
142
144 $offset += 4;
146 $offset += 4;
148 $offset += 4;
149
150 $ThisFileInfo['bitrate'] = ($thisfile_asf_filepropertiesobject['filesize'] * 8) / $ThisFileInfo['playtime_seconds'];
151 break;
152
153 case GETID3_ASF_Stream_Properties_Object:
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 $StreamPropertiesObjectData['objectid'] = $NextObjectGUID;
176 $StreamPropertiesObjectData['objectid_guid'] = $NextObjectGUIDtext;
177 $StreamPropertiesObjectData['objectsize'] = $NextObjectSize;
178 $StreamPropertiesObjectData['stream_type'] = substr($ASFHeaderData, $offset, 16);
179 $offset += 16;
180 $StreamPropertiesObjectData[
'stream_type_guid'] = $this->
BytestringToGUID($StreamPropertiesObjectData[
'stream_type']);
181 $StreamPropertiesObjectData['error_correct_type'] = substr($ASFHeaderData, $offset, 16);
182 $offset += 16;
183 $StreamPropertiesObjectData[
'error_correct_guid'] = $this->
BytestringToGUID($StreamPropertiesObjectData[
'error_correct_type']);
185 $offset += 8;
187 $offset += 4;
189 $offset += 4;
191 $offset += 2;
192 $StreamPropertiesObjectStreamNumber = $StreamPropertiesObjectData['flags_raw'] & 0x007F;
193 $StreamPropertiesObjectData['flags']['encrypted'] = (bool) ($StreamPropertiesObjectData['flags_raw'] & 0x8000);
194
195 $offset += 4;
196 $StreamPropertiesObjectData['type_specific_data'] = substr($ASFHeaderData, $offset, $StreamPropertiesObjectData['type_data_length']);
197 $offset += $StreamPropertiesObjectData['type_data_length'];
198 $StreamPropertiesObjectData['error_correct_data'] = substr($ASFHeaderData, $offset, $StreamPropertiesObjectData['error_data_length']);
199 $offset += $StreamPropertiesObjectData['error_data_length'];
200
201 switch ($StreamPropertiesObjectData['stream_type']) {
202
203 case GETID3_ASF_Audio_Media:
204 $thisfile_audio['dataformat'] = (!empty($thisfile_audio['dataformat']) ? $thisfile_audio['dataformat'] : 'asf');
205 $thisfile_audio['bitrate_mode'] = (!empty($thisfile_audio['bitrate_mode']) ? $thisfile_audio['bitrate_mode'] : 'cbr');
206
208 unset($audiodata['raw']);
210 break;
211
212 case GETID3_ASF_Video_Media:
213 $thisfile_video['dataformat'] = (!empty($thisfile_video['dataformat']) ? $thisfile_video['dataformat'] : 'asf');
214 $thisfile_video['bitrate_mode'] = (!empty($thisfile_video['bitrate_mode']) ? $thisfile_video['bitrate_mode'] : 'cbr');
215 break;
216
217 case GETID3_ASF_Command_Media:
218 default:
219
220 break;
221
222 }
223
224 $thisfile_asf['stream_properties_object'][$StreamPropertiesObjectStreamNumber] = $StreamPropertiesObjectData;
225 unset($StreamPropertiesObjectData);
226 break;
227
228 case GETID3_ASF_Header_Extension_Object:
229
230
231
232
233
234
235
236
237
238
239 $thisfile_asf['header_extension_object'] = array();
240 $thisfile_asf_headerextensionobject = &$thisfile_asf['header_extension_object'];
241
242 $thisfile_asf_headerextensionobject['objectid'] = $NextObjectGUID;
243 $thisfile_asf_headerextensionobject['objectid_guid'] = $NextObjectGUIDtext;
244 $thisfile_asf_headerextensionobject['objectsize'] = $NextObjectSize;
245 $thisfile_asf_headerextensionobject['reserved_1'] = substr($ASFHeaderData, $offset, 16);
246 $offset += 16;
247 $thisfile_asf_headerextensionobject[
'reserved_1_guid'] = $this->
BytestringToGUID($thisfile_asf_headerextensionobject[
'reserved_1']);
248 if ($thisfile_asf_headerextensionobject['reserved_1'] != GETID3_ASF_Reserved_1) {
249 $ThisFileInfo[
'warning'][] =
'header_extension_object.reserved_1 GUID ('.$this->BytestringToGUID($thisfile_asf_headerextensionobject[
'reserved_1']).
') does not match expected "GETID3_ASF_Reserved_1" GUID ('.$this->
BytestringToGUID(GETID3_ASF_Reserved_1).
')';
250
251 break;
252 }
254 $offset += 2;
255 if ($thisfile_asf_headerextensionobject['reserved_2'] != 6) {
256 $ThisFileInfo['warning'][] = 'header_extension_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_headerextensionobject['reserved_2']).') does not match expected value of "6"';
257
258 break;
259 }
261 $offset += 4;
262 $thisfile_asf_headerextensionobject['extension_data'] = substr($ASFHeaderData, $offset, $thisfile_asf_headerextensionobject['extension_data_size']);
263 $offset += $thisfile_asf_headerextensionobject['extension_data_size'];
264 break;
265
266 case GETID3_ASF_Codec_List_Object:
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 $thisfile_asf['codec_list_object'] = array();
284 $thisfile_asf_codeclistobject = &$thisfile_asf['codec_list_object'];
285
286 $thisfile_asf_codeclistobject['objectid'] = $NextObjectGUID;
287 $thisfile_asf_codeclistobject['objectid_guid'] = $NextObjectGUIDtext;
288 $thisfile_asf_codeclistobject['objectsize'] = $NextObjectSize;
289 $thisfile_asf_codeclistobject['reserved'] = substr($ASFHeaderData, $offset, 16);
290 $offset += 16;
291 $thisfile_asf_codeclistobject[
'reserved_guid'] = $this->
BytestringToGUID($thisfile_asf_codeclistobject[
'reserved']);
292 if ($thisfile_asf_codeclistobject[
'reserved'] != $this->
GUIDtoBytestring(
'86D15241-311D-11D0-A3A4-00A0C90348F6')) {
293 $ThisFileInfo['warning'][] = 'codec_list_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {86D15241-311D-11D0-A3A4-00A0C90348F6}';
294
295 break;
296 }
298 $offset += 4;
299 for ($CodecEntryCounter = 0; $CodecEntryCounter < $thisfile_asf_codeclistobject['codec_entries_count']; $CodecEntryCounter++) {
300
301 $thisfile_asf_codeclistobject['codec_entries'][$CodecEntryCounter] = array();
302 $thisfile_asf_codeclistobject_codecentries_current = &$thisfile_asf_codeclistobject['codec_entries'][$CodecEntryCounter];
303
305 $offset += 2;
306 $thisfile_asf_codeclistobject_codecentries_current[
'type'] = $this->
ASFCodecListObjectTypeLookup($thisfile_asf_codeclistobject_codecentries_current[
'type_raw']);
307
309 $offset += 2;
310 $thisfile_asf_codeclistobject_codecentries_current['name'] = substr($ASFHeaderData, $offset, $CodecNameLength);
311 $offset += $CodecNameLength;
312
314 $offset += 2;
315 $thisfile_asf_codeclistobject_codecentries_current['description'] = substr($ASFHeaderData, $offset, $CodecDescriptionLength);
316 $offset += $CodecDescriptionLength;
317
319 $offset += 2;
320 $thisfile_asf_codeclistobject_codecentries_current['information'] = substr($ASFHeaderData, $offset, $CodecInformationLength);
321 $offset += $CodecInformationLength;
322
323 if ($thisfile_asf_codeclistobject_codecentries_current['type_raw'] == 2) {
324
325 if (strpos($thisfile_asf_codeclistobject_codecentries_current['description'], ',') === false) {
326 $ThisFileInfo['error'][] = '[asf][codec_list_object][codec_entries]['.$CodecEntryCounter.'][description] expected to contain comma-seperated list of parameters: "'.$thisfile_asf_codeclistobject_codecentries_current['description'].'"';
327 return false;
328 }
329 list($AudioCodecBitrate, $AudioCodecFrequency, $AudioCodecChannels) = explode(
',', $this->
TrimConvert($thisfile_asf_codeclistobject_codecentries_current[
'description']));
330 $thisfile_audio[
'codec'] = $this->
TrimConvert($thisfile_asf_codeclistobject_codecentries_current[
'name']);
331
332 if (!isset($thisfile_audio['bitrate']) && strstr($AudioCodecBitrate, 'kbps')) {
333 $thisfile_audio['bitrate'] = (int) (trim(str_replace('kbps', '', $AudioCodecBitrate)) * 1000);
334 }
335
336 if (!@$thisfile_video['bitrate'] && @$thisfile_audio['bitrate'] && @$ThisFileInfo['bitrate']) {
337
338 $thisfile_video['bitrate'] = $ThisFileInfo['bitrate'] - $thisfile_audio['bitrate'];
339 }
340
341 $AudioCodecFrequency = (int) trim(str_replace('kHz', '', $AudioCodecFrequency));
342 switch ($AudioCodecFrequency) {
343 case 8:
344 case 8000:
345 $thisfile_audio['sample_rate'] = 8000;
346 break;
347
348 case 11:
349 case 11025:
350 $thisfile_audio['sample_rate'] = 11025;
351 break;
352
353 case 12:
354 case 12000:
355 $thisfile_audio['sample_rate'] = 12000;
356 break;
357
358 case 16:
359 case 16000:
360 $thisfile_audio['sample_rate'] = 16000;
361 break;
362
363 case 22:
364 case 22050:
365 $thisfile_audio['sample_rate'] = 22050;
366 break;
367
368 case 24:
369 case 24000:
370 $thisfile_audio['sample_rate'] = 24000;
371 break;
372
373 case 32:
374 case 32000:
375 $thisfile_audio['sample_rate'] = 32000;
376 break;
377
378 case 44:
379 case 441000:
380 $thisfile_audio['sample_rate'] = 44100;
381 break;
382
383 case 48:
384 case 48000:
385 $thisfile_audio['sample_rate'] = 48000;
386 break;
387
388 default:
389 $ThisFileInfo[
'warning'][] =
'unknown frequency: "'.$AudioCodecFrequency.
'" ('.$this->
TrimConvert($thisfile_asf_codeclistobject_codecentries_current[
'description']).
')';
390
391 break;
392 }
393
394 if (!isset($thisfile_audio['channels'])) {
395 if (strstr($AudioCodecChannels, 'stereo')) {
396 $thisfile_audio['channels'] = 2;
397 } elseif (strstr($AudioCodecChannels, 'mono')) {
398 $thisfile_audio['channels'] = 1;
399 }
400 }
401 }
402 }
403 break;
404
405 case GETID3_ASF_Script_Command_Object:
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423 $thisfile_asf['script_command_object'] = array();
424 $thisfile_asf_scriptcommandobject = &$thisfile_asf['script_command_object'];
425
426 $thisfile_asf_scriptcommandobject['objectid'] = $NextObjectGUID;
427 $thisfile_asf_scriptcommandobject['objectid_guid'] = $NextObjectGUIDtext;
428 $thisfile_asf_scriptcommandobject['objectsize'] = $NextObjectSize;
429 $thisfile_asf_scriptcommandobject['reserved'] = substr($ASFHeaderData, $offset, 16);
430 $offset += 16;
431 $thisfile_asf_scriptcommandobject[
'reserved_guid'] = $this->
BytestringToGUID($thisfile_asf_scriptcommandobject[
'reserved']);
432 if ($thisfile_asf_scriptcommandobject[
'reserved'] != $this->
GUIDtoBytestring(
'4B1ACBE3-100B-11D0-A39B-00A0C90348F6')) {
433 $ThisFileInfo['warning'][] = 'script_command_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4B1ACBE3-100B-11D0-A39B-00A0C90348F6}';
434
435 break;
436 }
438 $offset += 2;
440 $offset += 2;
441 for ($CommandTypesCounter = 0; $CommandTypesCounter < $thisfile_asf_scriptcommandobject['command_types_count']; $CommandTypesCounter++) {
443 $offset += 2;
444 $thisfile_asf_scriptcommandobject['command_types'][$CommandTypesCounter]['name'] = substr($ASFHeaderData, $offset, $CommandTypeNameLength);
445 $offset += $CommandTypeNameLength;
446 }
447 for ($CommandsCounter = 0; $CommandsCounter < $thisfile_asf_scriptcommandobject['commands_count']; $CommandsCounter++) {
448 $thisfile_asf_scriptcommandobject[
'commands'][$CommandsCounter][
'presentation_time'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
449 $offset += 4;
450 $thisfile_asf_scriptcommandobject[
'commands'][$CommandsCounter][
'type_index'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
451 $offset += 2;
452
454 $offset += 2;
455 $thisfile_asf_scriptcommandobject['commands'][$CommandsCounter]['name'] = substr($ASFHeaderData, $offset, $CommandTypeNameLength);
456 $offset += $CommandTypeNameLength;
457 }
458 break;
459
460 case GETID3_ASF_Marker_Object:
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481 $thisfile_asf['marker_object'] = array();
482 $thisfile_asf_markerobject = &$thisfile_asf['marker_object'];
483
484 $thisfile_asf_markerobject['objectid'] = $NextObjectGUID;
485 $thisfile_asf_markerobject['objectid_guid'] = $NextObjectGUIDtext;
486 $thisfile_asf_markerobject['objectsize'] = $NextObjectSize;
487 $thisfile_asf_markerobject['reserved'] = substr($ASFHeaderData, $offset, 16);
488 $offset += 16;
489 $thisfile_asf_markerobject[
'reserved_guid'] = $this->
BytestringToGUID($thisfile_asf_markerobject[
'reserved']);
490 if ($thisfile_asf_markerobject[
'reserved'] != $this->
GUIDtoBytestring(
'4CFEDB20-75F6-11CF-9C0F-00A0C90349CB')) {
491 $ThisFileInfo['warning'][] = 'marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved_1']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}';
492 break;
493 }
495 $offset += 4;
497 $offset += 2;
498 if ($thisfile_asf_markerobject['reserved_2'] != 0) {
499 $ThisFileInfo['warning'][] = 'marker_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_markerobject['reserved_2']).') does not match expected value of "0"';
500 break;
501 }
503 $offset += 2;
504 $thisfile_asf_markerobject['name'] = substr($ASFHeaderData, $offset, $thisfile_asf_markerobject['name_length']);
505 $offset += $thisfile_asf_markerobject['name_length'];
506 for ($MarkersCounter = 0; $MarkersCounter < $thisfile_asf_markerobject['markers_count']; $MarkersCounter++) {
508 $offset += 8;
509 $thisfile_asf_markerobject[
'markers'][$MarkersCounter][
'presentation_time'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 8));
510 $offset += 8;
511 $thisfile_asf_markerobject[
'markers'][$MarkersCounter][
'entry_length'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
512 $offset += 2;
514 $offset += 4;
516 $offset += 4;
517 $thisfile_asf_markerobject[
'markers'][$MarkersCounter][
'marker_description_length'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
518 $offset += 4;
519 $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description'] = substr($ASFHeaderData, $offset, $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length']);
520 $offset += $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length'];
521 $PaddingLength = $thisfile_asf_markerobject['markers'][$MarkersCounter]['entry_length'] - 4 - 4 - 4 - $thisfile_asf_markerobject['markers'][$MarkersCounter]['marker_description_length'];
522 if ($PaddingLength > 0) {
523 $thisfile_asf_markerobject['markers'][$MarkersCounter]['padding'] = substr($ASFHeaderData, $offset, $PaddingLength);
524 $offset += $PaddingLength;
525 }
526 }
527 break;
528
529 case GETID3_ASF_Bitrate_Mutual_Exclusion_Object:
530
531
532
533
534
535
536
537
538
539 $thisfile_asf['bitrate_mutual_exclusion_object'] = array();
540 $thisfile_asf_bitratemutualexclusionobject = &$thisfile_asf['bitrate_mutual_exclusion_object'];
541
542 $thisfile_asf_bitratemutualexclusionobject['objectid'] = $NextObjectGUID;
543 $thisfile_asf_bitratemutualexclusionobject['objectid_guid'] = $NextObjectGUIDtext;
544 $thisfile_asf_bitratemutualexclusionobject['objectsize'] = $NextObjectSize;
545 $thisfile_asf_bitratemutualexclusionobject['reserved'] = substr($ASFHeaderData, $offset, 16);
546 $thisfile_asf_bitratemutualexclusionobject[
'reserved_guid'] = $this->
BytestringToGUID($thisfile_asf_bitratemutualexclusionobject[
'reserved']);
547 $offset += 16;
548 if (($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Bitrate) && ($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Unknown)) {
549 $ThisFileInfo[
'warning'][] =
'bitrate_mutual_exclusion_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject[
'reserved']).
'} does not match expected "GETID3_ASF_Mutex_Bitrate" GUID {'.$this->
BytestringToGUID(GETID3_ASF_Mutex_Bitrate).
'} or "GETID3_ASF_Mutex_Unknown" GUID {'.$this->
BytestringToGUID(GETID3_ASF_Mutex_Unknown).
'}';
550
551 break;
552 }
554 $offset += 2;
555 for ($StreamNumberCounter = 0; $StreamNumberCounter < $thisfile_asf_bitratemutualexclusionobject['stream_numbers_count']; $StreamNumberCounter++) {
556 $thisfile_asf_bitratemutualexclusionobject[
'stream_numbers'][$StreamNumberCounter] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
557 $offset += 2;
558 }
559 break;
560
561 case GETID3_ASF_Error_Correction_Object:
562
563
564
565
566
567
568
569
570
571 $thisfile_asf['error_correction_object'] = array();
572 $thisfile_asf_errorcorrectionobject = &$thisfile_asf['error_correction_object'];
573
574 $thisfile_asf_errorcorrectionobject['objectid'] = $NextObjectGUID;
575 $thisfile_asf_errorcorrectionobject['objectid_guid'] = $NextObjectGUIDtext;
576 $thisfile_asf_errorcorrectionobject['objectsize'] = $NextObjectSize;
577 $thisfile_asf_errorcorrectionobject['error_correction_type'] = substr($ASFHeaderData, $offset, 16);
578 $offset += 16;
579 $thisfile_asf_errorcorrectionobject[
'error_correction_guid'] = $this->
BytestringToGUID($thisfile_asf_errorcorrectionobject[
'error_correction_type']);
581 $offset += 4;
582 switch ($thisfile_asf_errorcorrectionobject['error_correction_type']) {
583 case GETID3_ASF_No_Error_Correction:
584
585 $offset += $thisfile_asf_errorcorrectionobject['error_correction_data_length'];
586 break;
587
588 case GETID3_ASF_Audio_Spread:
589
590
591
592
593
594
595
597 $offset += 1;
599 $offset += 2;
601 $offset += 2;
603 $offset += 2;
604 $thisfile_asf_errorcorrectionobject['silence_data'] = substr($ASFHeaderData, $offset, $thisfile_asf_errorcorrectionobject['silence_data_length']);
605 $offset += $thisfile_asf_errorcorrectionobject['silence_data_length'];
606 break;
607
608 default:
609 $ThisFileInfo[
'warning'][] =
'error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject[
'reserved']).
'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->
BytestringToGUID(GETID3_ASF_No_Error_Correction).
'} or "GETID3_ASF_Audio_Spread" GUID {'.$this->
BytestringToGUID(GETID3_ASF_Audio_Spread).
'}';
610
611 break;
612 }
613
614 break;
615
616 case GETID3_ASF_Content_Description_Object:
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633 $thisfile_asf['content_description_object'] = array();
634 $thisfile_asf_contentdescriptionobject = &$thisfile_asf['content_description_object'];
635
636 $thisfile_asf_contentdescriptionobject['objectid'] = $NextObjectGUID;
637 $thisfile_asf_contentdescriptionobject['objectid_guid'] = $NextObjectGUIDtext;
638 $thisfile_asf_contentdescriptionobject['objectsize'] = $NextObjectSize;
640 $offset += 2;
642 $offset += 2;
644 $offset += 2;
646 $offset += 2;
648 $offset += 2;
649 $thisfile_asf_contentdescriptionobject['title'] = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['title_length']);
650 $offset += $thisfile_asf_contentdescriptionobject['title_length'];
651 $thisfile_asf_contentdescriptionobject['author'] = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['author_length']);
652 $offset += $thisfile_asf_contentdescriptionobject['author_length'];
653 $thisfile_asf_contentdescriptionobject['copyright'] = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['copyright_length']);
654 $offset += $thisfile_asf_contentdescriptionobject['copyright_length'];
655 $thisfile_asf_contentdescriptionobject['description'] = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['description_length']);
656 $offset += $thisfile_asf_contentdescriptionobject['description_length'];
657 $thisfile_asf_contentdescriptionobject['rating'] = substr($ASFHeaderData, $offset, $thisfile_asf_contentdescriptionobject['rating_length']);
658 $offset += $thisfile_asf_contentdescriptionobject['rating_length'];
659
660 $ASFcommentKeysToCopy = array('title'=>'title', 'author'=>'artist', 'copyright'=>'copyright', 'description'=>'comment', 'rating'=>'rating');
661 foreach ($ASFcommentKeysToCopy as $keytocopyfrom => $keytocopyto) {
662 if (!empty($thisfile_asf_contentdescriptionobject[$keytocopyfrom])) {
663 $thisfile_asf_comments[$keytocopyto][] = $this->
TrimTerm($thisfile_asf_contentdescriptionobject[$keytocopyfrom]);
664 }
665 }
666 break;
667
668 case GETID3_ASF_Extended_Content_Description_Object:
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688 $thisfile_asf['extended_content_description_object'] = array();
689 $thisfile_asf_extendedcontentdescriptionobject = &$thisfile_asf['extended_content_description_object'];
690
691 $thisfile_asf_extendedcontentdescriptionobject['objectid'] = $NextObjectGUID;
692 $thisfile_asf_extendedcontentdescriptionobject['objectid_guid'] = $NextObjectGUIDtext;
693 $thisfile_asf_extendedcontentdescriptionobject['objectsize'] = $NextObjectSize;
694 $thisfile_asf_extendedcontentdescriptionobject[
'content_descriptors_count'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
695 $offset += 2;
696 for ($ExtendedContentDescriptorsCounter = 0; $ExtendedContentDescriptorsCounter < $thisfile_asf_extendedcontentdescriptionobject['content_descriptors_count']; $ExtendedContentDescriptorsCounter++) {
697
698 $thisfile_asf_extendedcontentdescriptionobject['content_descriptors'][$ExtendedContentDescriptorsCounter] = array();
699 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current = &$thisfile_asf_extendedcontentdescriptionobject['content_descriptors'][$ExtendedContentDescriptorsCounter];
700
701 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['base_offset'] = $offset + 30;
702 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'name_length'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
703 $offset += 2;
704 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name'] = substr($ASFHeaderData, $offset, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name_length']);
705 $offset += $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['name_length'];
706 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value_type'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
707 $offset += 2;
708 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value_length'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
709 $offset += 2;
710 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'] = substr($ASFHeaderData, $offset, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_length']);
711 $offset += $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_length'];
712 switch ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type']) {
713 case 0x0000:
714 break;
715
716 case 0x0001:
717
718 break;
719
720 case 0x0002:
721 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value'] = (bool)
getid3_lib::LittleEndian2Int($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']);
722 break;
723
724 case 0x0003:
725 case 0x0004:
726 case 0x0005:
727 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value'] =
getid3_lib::LittleEndian2Int($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']);
728 break;
729
730 default:
731 $ThisFileInfo['warning'][] = 'extended_content_description.content_descriptors.'.$ExtendedContentDescriptorsCounter.'.value_type is invalid ('.$thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type'].')';
732
733 break;
734 }
735 switch ($this->
TrimConvert(strtolower($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'name']))) {
736
737 case 'wm/albumartist':
738 case 'artist':
739 $thisfile_asf_comments[
'artist'] = array($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
740 break;
741
742 case 'wm/albumtitle':
743 case 'album':
744 $thisfile_asf_comments[
'album'] = array($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
745 break;
746
747 case 'wm/genre':
748 case 'genre':
749 $thisfile_asf_comments[
'genre'] = array($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
750 break;
751
752 case 'wm/tracknumber':
753 case 'tracknumber':
754 $thisfile_asf_comments[
'track'] = array(intval($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value'])));
755 break;
756
757 case 'wm/track':
758 if (empty($thisfile_asf_comments['track'])) {
759 $thisfile_asf_comments[
'track'] = array(1 + $this->
TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
760 }
761 break;
762
763 case 'wm/year':
764 case 'year':
765 case 'date':
766 $thisfile_asf_comments[
'year'] = array( $this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
767 break;
768
769 case 'wm/lyrics':
770 case 'lyrics':
771 $thisfile_asf_comments[
'lyrics'] = array($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
772 break;
773
774 case 'isvbr':
775 if ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']) {
776 $thisfile_audio['bitrate_mode'] = 'vbr';
777 $thisfile_video['bitrate_mode'] = 'vbr';
778 }
779 break;
780
781 case 'id3':
782
783 if (class_exists('getid3_id3v2')) {
784 $tempfile = tempnam('*', 'getID3');
785 $tempfilehandle = fopen($tempfile, "wb");
786 $tempThisfileInfo = array('encoding'=>$ThisFileInfo['encoding']);
787 fwrite($tempfilehandle, $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
788 fclose($tempfilehandle);
789
790 $tempfilehandle = fopen($tempfile, "rb");
791 $id3 =
new getid3_id3v2($tempfilehandle, $tempThisfileInfo);
792 fclose($tempfilehandle);
793 unlink($tempfile);
794
795 $ThisFileInfo['id3v2'] = $tempThisfileInfo['id3v2'];
796 }
797 break;
798
799 case 'wm/encodingtime':
800 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'encoding_time_unix'] = $this->
FILETIMEtoUNIXtime($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']);
801 $thisfile_asf_comments['encoding_time_unix'] = array($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['encoding_time_unix']);
802 break;
803
804 case 'wm/picture':
805
806
807
808
809
810
811
812
813 $wm_picture_offset = 0;
814 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'image_type_id'] =
getid3_lib::LittleEndian2Int(substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value'], $wm_picture_offset, 1));
815 $wm_picture_offset += 1;
816 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'image_type'] = $this->
WMpictureTypeLookup($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'image_type_id']);
817 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'image_size'] =
getid3_lib::LittleEndian2Int(substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value'], $wm_picture_offset, 4));
818 $wm_picture_offset += 4;
819
820 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_mime'] = '';
821 do {
822 $next_byte_pair = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 2);
823 $wm_picture_offset += 2;
824 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_mime'] .= $next_byte_pair;
825 } while ($next_byte_pair !== "\x00\x00");
826
827 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_description'] = '';
828 do {
829 $next_byte_pair = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset, 2);
830 $wm_picture_offset += 2;
831 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['image_description'] .= $next_byte_pair;
832 } while ($next_byte_pair !== "\x00\x00");
833
834 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['dataoffset'] = $wm_picture_offset;
835 $thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['data'] = substr($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value'], $wm_picture_offset);
836 unset($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']);
837
838 break;
839
840 default:
841 switch ($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type']) {
842 case 0:
843 if (substr($this->
TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'name']), 0, 3) ==
'WM/') {
844 $thisfile_asf_comments[str_replace(
'wm/',
'', strtolower($this->
TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'name'])))] = array($this->
TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current[
'value']));
845 }
846 break;
847
848 case 1:
849 break;
850 }
851 break;
852 }
853
854 }
855 break;
856
857 case GETID3_ASF_Stream_Bitrate_Properties_Object:
858
859
860
861
862
863
864
865
866
867
868
869
870 $thisfile_asf['stream_bitrate_properties_object'] = array();
871 $thisfile_asf_streambitratepropertiesobject = &$thisfile_asf['stream_bitrate_properties_object'];
872
873 $thisfile_asf_streambitratepropertiesobject['objectid'] = $NextObjectGUID;
874 $thisfile_asf_streambitratepropertiesobject['objectid_guid'] = $NextObjectGUIDtext;
875 $thisfile_asf_streambitratepropertiesobject['objectsize'] = $NextObjectSize;
876 $thisfile_asf_streambitratepropertiesobject[
'bitrate_records_count'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
877 $offset += 2;
878 for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitratepropertiesobject['bitrate_records_count']; $BitrateRecordsCounter++) {
879 $thisfile_asf_streambitratepropertiesobject[
'bitrate_records'][$BitrateRecordsCounter][
'flags_raw'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
880 $offset += 2;
881 $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['flags']['stream_number'] = $thisfile_asf_streambitratepropertiesobject['bitrate_records'][$BitrateRecordsCounter]['flags_raw'] & 0x007F;
882 $thisfile_asf_streambitratepropertiesobject[
'bitrate_records'][$BitrateRecordsCounter][
'bitrate'] =
getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
883 $offset += 4;
884 }
885 break;
886
887 case GETID3_ASF_Padding_Object:
888
889
890
891
892
893
894
895 $thisfile_asf['padding_object'] = array();
896 $thisfile_asf_paddingobject = &$thisfile_asf['padding_object'];
897
898 $thisfile_asf_paddingobject['objectid'] = $NextObjectGUID;
899 $thisfile_asf_paddingobject['objectid_guid'] = $NextObjectGUIDtext;
900 $thisfile_asf_paddingobject['objectsize'] = $NextObjectSize;
901 $thisfile_asf_paddingobject['padding_length'] = $thisfile_asf_paddingobject['objectsize'] - 16 - 8;
902 $thisfile_asf_paddingobject['padding'] = substr($ASFHeaderData, $offset, $thisfile_asf_paddingobject['padding_length']);
903 break;
904
905 case GETID3_ASF_Extended_Content_Encryption_Object:
906 case GETID3_ASF_Content_Encryption_Object:
907
908 $offset += ($NextObjectSize - 16 - 8);
909 break;
910
911 default:
912
913 if ($this->
GUIDname($NextObjectGUIDtext)) {
914 $ThisFileInfo['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
915 } else {
916 $ThisFileInfo['warning'][] = 'unknown GUID {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
917 }
918 $offset += ($NextObjectSize - 16 - 8);
919 break;
920 }
921 }
922 if (isset($thisfile_asf_streambitrateproperties['bitrate_records_count'])) {
923 $ASFbitrateAudio = 0;
924 $ASFbitrateVideo = 0;
925 for ($BitrateRecordsCounter = 0; $BitrateRecordsCounter < $thisfile_asf_streambitrateproperties['bitrate_records_count']; $BitrateRecordsCounter++) {
926 if (isset($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter])) {
927 switch ($thisfile_asf_codeclistobject['codec_entries'][$BitrateRecordsCounter]['type_raw']) {
928 case 1:
929 $ASFbitrateVideo += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
930 break;
931
932 case 2:
933 $ASFbitrateAudio += $thisfile_asf_streambitrateproperties['bitrate_records'][$BitrateRecordsCounter]['bitrate'];
934 break;
935
936 default:
937
938 break;
939 }
940 }
941 }
942 if ($ASFbitrateAudio > 0) {
943 $thisfile_audio['bitrate'] = $ASFbitrateAudio;
944 }
945 if ($ASFbitrateVideo > 0) {
946 $thisfile_video['bitrate'] = $ASFbitrateVideo;
947 }
948 }
949 if (isset($thisfile_asf['stream_properties_object']) && is_array($thisfile_asf['stream_properties_object'])) {
950
951 $thisfile_audio['bitrate'] = 0;
952 $thisfile_video['bitrate'] = 0;
953
954 foreach ($thisfile_asf['stream_properties_object'] as $streamnumber => $streamdata) {
955
956 switch ($streamdata['stream_type']) {
957 case GETID3_ASF_Audio_Media:
958
959
960
961
962
963
964
965
966
967
968
969 $thisfile_asf['audio_media'][$streamnumber] = array();
970 $thisfile_asf_audiomedia_currentstream = &$thisfile_asf['audio_media'][$streamnumber];
971
972 $audiomediaoffset = 0;
973
975 $audiomediaoffset += 16;
976
977 $thisfile_audio['lossless'] = false;
978 switch ($thisfile_asf_audiomedia_currentstream['raw']['wFormatTag']) {
979 case 0x0001:
980 case 0x0163:
981 $thisfile_audio['lossless'] = true;
982 break;
983 }
984
985 if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
986 foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
987 if (@$dataarray['flags']['stream_number'] == $streamnumber) {
988 $thisfile_asf_audiomedia_currentstream['bitrate'] = $dataarray['bitrate'];
989 $thisfile_audio['bitrate'] += $dataarray['bitrate'];
990 break;
991 }
992 }
993 } else {
994 if (@$thisfile_asf_audiomedia_currentstream['bytes_sec']) {
995 $thisfile_audio['bitrate'] += $thisfile_asf_audiomedia_currentstream['bytes_sec'] * 8;
996 } elseif (@$thisfile_asf_audiomedia_currentstream['bitrate']) {
997 $thisfile_audio['bitrate'] += $thisfile_asf_audiomedia_currentstream['bitrate'];
998 }
999 }
1000 $thisfile_audio['streams'][$streamnumber] = $thisfile_asf_audiomedia_currentstream;
1001 $thisfile_audio['streams'][$streamnumber]['wformattag'] = $thisfile_asf_audiomedia_currentstream['raw']['wFormatTag'];
1002 $thisfile_audio['streams'][$streamnumber]['lossless'] = $thisfile_audio['lossless'];
1003 $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
1004 unset($thisfile_audio['streams'][$streamnumber]['raw']);
1005
1006 $thisfile_asf_audiomedia_currentstream[
'codec_data_size'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $audiomediaoffset, 2));
1007 $audiomediaoffset += 2;
1008 $thisfile_asf_audiomedia_currentstream['codec_data'] = substr($streamdata['type_specific_data'], $audiomediaoffset, $thisfile_asf_audiomedia_currentstream['codec_data_size']);
1009 $audiomediaoffset += $thisfile_asf_audiomedia_currentstream['codec_data_size'];
1010
1011 break;
1012
1013 case GETID3_ASF_Video_Media:
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034 $thisfile_asf['video_media'][$streamnumber] = array();
1035 $thisfile_asf_videomedia_currentstream = &$thisfile_asf['video_media'][$streamnumber];
1036
1037 $videomediaoffset = 0;
1038 $thisfile_asf_videomedia_currentstream[
'image_width'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1039 $videomediaoffset += 4;
1040 $thisfile_asf_videomedia_currentstream[
'image_height'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1041 $videomediaoffset += 4;
1042 $thisfile_asf_videomedia_currentstream[
'flags'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 1));
1043 $videomediaoffset += 1;
1044 $thisfile_asf_videomedia_currentstream[
'format_data_size'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 2));
1045 $videomediaoffset += 2;
1046 $thisfile_asf_videomedia_currentstream[
'format_data'][
'format_data_size'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1047 $videomediaoffset += 4;
1048 $thisfile_asf_videomedia_currentstream[
'format_data'][
'image_width'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1049 $videomediaoffset += 4;
1050 $thisfile_asf_videomedia_currentstream[
'format_data'][
'image_height'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1051 $videomediaoffset += 4;
1052 $thisfile_asf_videomedia_currentstream[
'format_data'][
'reserved'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 2));
1053 $videomediaoffset += 2;
1054 $thisfile_asf_videomedia_currentstream[
'format_data'][
'bits_per_pixel'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 2));
1055 $videomediaoffset += 2;
1056 $thisfile_asf_videomedia_currentstream['format_data']['codec_fourcc'] = substr($streamdata['type_specific_data'], $videomediaoffset, 4);
1057 $videomediaoffset += 4;
1058 $thisfile_asf_videomedia_currentstream[
'format_data'][
'image_size'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1059 $videomediaoffset += 4;
1060 $thisfile_asf_videomedia_currentstream[
'format_data'][
'horizontal_pels'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1061 $videomediaoffset += 4;
1062 $thisfile_asf_videomedia_currentstream[
'format_data'][
'vertical_pels'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1063 $videomediaoffset += 4;
1064 $thisfile_asf_videomedia_currentstream[
'format_data'][
'colors_used'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1065 $videomediaoffset += 4;
1066 $thisfile_asf_videomedia_currentstream[
'format_data'][
'colors_important'] =
getid3_lib::LittleEndian2Int(substr($streamdata[
'type_specific_data'], $videomediaoffset, 4));
1067 $videomediaoffset += 4;
1068 $thisfile_asf_videomedia_currentstream['format_data']['codec_data'] = substr($streamdata['type_specific_data'], $videomediaoffset);
1069
1070 if (!empty($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'])) {
1071 foreach ($thisfile_asf['stream_bitrate_properties_object']['bitrate_records'] as $dummy => $dataarray) {
1072 if (@$dataarray['flags']['stream_number'] == $streamnumber) {
1073 $thisfile_asf_videomedia_currentstream['bitrate'] = $dataarray['bitrate'];
1074 $thisfile_video['streams'][$streamnumber]['bitrate'] = $dataarray['bitrate'];
1075 $thisfile_video['bitrate'] += $dataarray['bitrate'];
1076 break;
1077 }
1078 }
1079 }
1080
1081 $thisfile_asf_videomedia_currentstream[
'format_data'][
'codec'] =
getid3_riff::RIFFfourccLookup($thisfile_asf_videomedia_currentstream[
'format_data'][
'codec_fourcc']);
1082
1083 $thisfile_video['streams'][$streamnumber]['fourcc'] = $thisfile_asf_videomedia_currentstream['format_data']['codec_fourcc'];
1084 $thisfile_video['streams'][$streamnumber]['codec'] = $thisfile_asf_videomedia_currentstream['format_data']['codec'];
1085 $thisfile_video['streams'][$streamnumber]['resolution_x'] = $thisfile_asf_videomedia_currentstream['image_width'];
1086 $thisfile_video['streams'][$streamnumber]['resolution_y'] = $thisfile_asf_videomedia_currentstream['image_height'];
1087 $thisfile_video['streams'][$streamnumber]['bits_per_sample'] = $thisfile_asf_videomedia_currentstream['format_data']['bits_per_pixel'];
1088 break;
1089
1090 default:
1091 break;
1092 }
1093 }
1094 }
1095
1096 while (
ftell($fd) < $ThisFileInfo[
'avdataend']) {
1097 $NextObjectDataHeader =
fread($fd, 24);
1098 $offset = 0;
1099 $NextObjectGUID = substr($NextObjectDataHeader, 0, 16);
1100 $offset += 16;
1103 $offset += 8;
1104
1105 switch ($NextObjectGUID) {
1106 case GETID3_ASF_Data_Object:
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116 $thisfile_asf['data_object'] = array();
1117 $thisfile_asf_dataobject = &$thisfile_asf['data_object'];
1118
1119 $DataObjectData = $NextObjectDataHeader.fread($fd, 50 - 24);
1120 $offset = 24;
1121
1122 $thisfile_asf_dataobject['objectid'] = $NextObjectGUID;
1123 $thisfile_asf_dataobject['objectid_guid'] = $NextObjectGUIDtext;
1124 $thisfile_asf_dataobject['objectsize'] = $NextObjectSize;
1125
1126 $thisfile_asf_dataobject['fileid'] = substr($DataObjectData, $offset, 16);
1127 $offset += 16;
1128 $thisfile_asf_dataobject[
'fileid_guid'] = $this->
BytestringToGUID($thisfile_asf_dataobject[
'fileid']);
1130 $offset += 8;
1132 $offset += 2;
1133 if ($thisfile_asf_dataobject['reserved'] != 0x0101) {
1134 $ThisFileInfo['warning'][] = 'data_object.reserved ('.getid3_lib::PrintHexBytes($thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"';
1135
1136 break;
1137 }
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147 $ThisFileInfo[
'avdataoffset'] =
ftell($fd);
1148 fseek($fd, ($thisfile_asf_dataobject[
'objectsize'] - 50), SEEK_CUR);
1149 $ThisFileInfo[
'avdataend'] =
ftell($fd);
1150 break;
1151
1152 case GETID3_ASF_Simple_Index_Object:
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166 $thisfile_asf['simple_index_object'] = array();
1167 $thisfile_asf_simpleindexobject = &$thisfile_asf['simple_index_object'];
1168
1169 $SimpleIndexObjectData = $NextObjectDataHeader.fread($fd, 56 - 24);
1170 $offset = 24;
1171
1172 $thisfile_asf_simpleindexobject['objectid'] = $NextObjectGUID;
1173 $thisfile_asf_simpleindexobject['objectid_guid'] = $NextObjectGUIDtext;
1174 $thisfile_asf_simpleindexobject['objectsize'] = $NextObjectSize;
1175
1176 $thisfile_asf_simpleindexobject['fileid'] = substr($SimpleIndexObjectData, $offset, 16);
1177 $offset += 16;
1178 $thisfile_asf_simpleindexobject[
'fileid_guid'] = $this->
BytestringToGUID($thisfile_asf_simpleindexobject[
'fileid']);
1179 $thisfile_asf_simpleindexobject[
'index_entry_time_interval'] =
getid3_lib::LittleEndian2Int(substr($SimpleIndexObjectData, $offset, 8));
1180 $offset += 8;
1182 $offset += 4;
1184 $offset += 4;
1185
1186 $IndexEntriesData = $SimpleIndexObjectData.fread($fd, 6 * $thisfile_asf_simpleindexobject['index_entries_count']);
1187 for ($IndexEntriesCounter = 0; $IndexEntriesCounter < $thisfile_asf_simpleindexobject['index_entries_count']; $IndexEntriesCounter++) {
1188 $thisfile_asf_simpleindexobject[
'index_entries'][$IndexEntriesCounter][
'packet_number'] =
getid3_lib::LittleEndian2Int(substr($IndexEntriesData, $offset, 4));
1189 $offset += 4;
1190 $thisfile_asf_simpleindexobject[
'index_entries'][$IndexEntriesCounter][
'packet_count'] =
getid3_lib::LittleEndian2Int(substr($IndexEntriesData, $offset, 4));
1191 $offset += 2;
1192 }
1193
1194 break;
1195
1196 case GETID3_ASF_Index_Object:
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 $thisfile_asf['asf_index_object'] = array();
1221 $thisfile_asf_asfindexobject = &$thisfile_asf['asf_index_object'];
1222
1223 $ASFIndexObjectData = $NextObjectDataHeader.fread($fd, 34 - 24);
1224 $offset = 24;
1225
1226 $thisfile_asf_asfindexobject['objectid'] = $NextObjectGUID;
1227 $thisfile_asf_asfindexobject['objectid_guid'] = $NextObjectGUIDtext;
1228 $thisfile_asf_asfindexobject['objectsize'] = $NextObjectSize;
1229
1231 $offset += 4;
1233 $offset += 2;
1235 $offset += 4;
1236
1237 $ASFIndexObjectData .=
fread($fd, 4 * $thisfile_asf_asfindexobject[
'index_specifiers_count']);
1238 for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1240 $offset += 2;
1241 $thisfile_asf_asfindexobject['index_specifiers'][$IndexSpecifiersCounter]['stream_number'] = $IndexSpecifierStreamNumber;
1242 $thisfile_asf_asfindexobject[
'index_specifiers'][$IndexSpecifiersCounter][
'index_type'] =
getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 2));
1243 $offset += 2;
1244 $thisfile_asf_asfindexobject[
'index_specifiers'][$IndexSpecifiersCounter][
'index_type_text'] = $this->
ASFIndexObjectIndexTypeLookup($thisfile_asf_asfindexobject[
'index_specifiers'][$IndexSpecifiersCounter][
'index_type']);
1245 }
1246
1247 $ASFIndexObjectData .=
fread($fd, 4);
1249 $offset += 4;
1250
1251 $ASFIndexObjectData .=
fread($fd, 8 * $thisfile_asf_asfindexobject[
'index_specifiers_count']);
1252 for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1253 $thisfile_asf_asfindexobject[
'block_positions'][$IndexSpecifiersCounter] =
getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 8));
1254 $offset += 8;
1255 }
1256
1257 $ASFIndexObjectData .=
fread($fd, 4 * $thisfile_asf_asfindexobject[
'index_specifiers_count'] * $thisfile_asf_asfindexobject[
'index_entry_count']);
1258 for ($IndexEntryCounter = 0; $IndexEntryCounter < $thisfile_asf_asfindexobject['index_entry_count']; $IndexEntryCounter++) {
1259 for ($IndexSpecifiersCounter = 0; $IndexSpecifiersCounter < $thisfile_asf_asfindexobject['index_specifiers_count']; $IndexSpecifiersCounter++) {
1260 $thisfile_asf_asfindexobject[
'offsets'][$IndexSpecifiersCounter][$IndexEntryCounter] =
getid3_lib::LittleEndian2Int(substr($ASFIndexObjectData, $offset, 4));
1261 $offset += 4;
1262 }
1263 }
1264 break;
1265
1266
1267 default:
1268
1269 if ($this->
GUIDname($NextObjectGUIDtext)) {
1270 $ThisFileInfo['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF body at offset '.($offset - 16 - 8);
1271 } else {
1272 $ThisFileInfo[
'warning'][] =
'unknown GUID {'.$NextObjectGUIDtext.
'} in ASF body at offset '.(
ftell($fd) - 16 - 8);
1273 }
1274 fseek($fd, ($NextObjectSize - 16 - 8), SEEK_CUR);
1275 break;
1276 }
1277 }
1278
1279 if (isset($thisfile_asf_codeclistobject['codec_entries']) && is_array($thisfile_asf_codeclistobject['codec_entries'])) {
1280 foreach ($thisfile_asf_codeclistobject['codec_entries'] as $streamnumber => $streamdata) {
1281 switch ($streamdata['information']) {
1282 case 'WMV1':
1283 case 'WMV2':
1284 case 'WMV3':
1285 $thisfile_video['dataformat'] = 'wmv';
1286 $ThisFileInfo['mime_type'] = 'video/x-ms-wmv';
1287 break;
1288
1289 case 'MP42':
1290 case 'MP43':
1291 case 'MP4S':
1292 case 'mp4s':
1293 $thisfile_video['dataformat'] = 'asf';
1294 $ThisFileInfo['mime_type'] = 'video/x-ms-asf';
1295 break;
1296
1297 default:
1298 switch ($streamdata['type_raw']) {
1299 case 1:
1300 if (strstr($this->
TrimConvert($streamdata[
'name']),
'Windows Media')) {
1301 $thisfile_video['dataformat'] = 'wmv';
1302 if ($ThisFileInfo['mime_type'] == 'video/x-ms-asf') {
1303 $ThisFileInfo['mime_type'] = 'video/x-ms-wmv';
1304 }
1305 }
1306 break;
1307
1308 case 2:
1309 if (strstr($this->
TrimConvert($streamdata[
'name']),
'Windows Media')) {
1310 $thisfile_audio['dataformat'] = 'wma';
1311 if ($ThisFileInfo['mime_type'] == 'video/x-ms-asf') {
1312 $ThisFileInfo['mime_type'] = 'audio/x-ms-wma';
1313 }
1314 }
1315 break;
1316
1317 }
1318 break;
1319 }
1320 }
1321 }
1322
1323 switch (@$thisfile_audio['codec']) {
1324 case 'MPEG Layer-3':
1325 $thisfile_audio['dataformat'] = 'mp3';
1326 break;
1327
1328 default:
1329 break;
1330 }
1331
1332 if (isset($thisfile_asf_codeclistobject['codec_entries'])) {
1333 foreach ($thisfile_asf_codeclistobject['codec_entries'] as $streamnumber => $streamdata) {
1334 switch ($streamdata['type_raw']) {
1335
1336 case 1:
1337 $thisfile_video[
'encoder'] = $this->
TrimConvert($thisfile_asf_codeclistobject[
'codec_entries'][$streamnumber][
'name']);
1338 break;
1339
1340 case 2:
1341 $thisfile_audio[
'encoder'] = $this->
TrimConvert($thisfile_asf_codeclistobject[
'codec_entries'][$streamnumber][
'name']);
1342
1343
1344 $thisfile_audio[
'encoder_options'] = $this->
TrimConvert($thisfile_asf_codeclistobject[
'codec_entries'][0][
'description']);
1345
1346 $thisfile_audio['codec'] = $thisfile_audio['encoder'];
1347 break;
1348
1349 default:
1350 $ThisFileInfo['warning'][] = 'Unknown streamtype: [codec_list_object][codec_entries]['.$streamnumber.'][type_raw] == '.$streamdata['type_raw'];
1351 break;
1352
1353 }
1354 }
1355 }
1356
1357 if (isset($ThisFileInfo['audio'])) {
1358 $thisfile_audio['lossless'] = (isset($thisfile_audio['lossless']) ? $thisfile_audio['lossless'] : false);
1359 $thisfile_audio['dataformat'] = (!empty($thisfile_audio['dataformat']) ? $thisfile_audio['dataformat'] : 'asf');
1360 }
1361 if (!empty($thisfile_video['dataformat'])) {
1362 $thisfile_video['lossless'] = (isset($thisfile_audio['lossless']) ? $thisfile_audio['lossless'] : false);
1363 $thisfile_video['pixel_aspect_ratio'] = (isset($thisfile_audio['pixel_aspect_ratio']) ? $thisfile_audio['pixel_aspect_ratio'] : (float) 1);
1364 $thisfile_video['dataformat'] = (!empty($thisfile_video['dataformat']) ? $thisfile_video['dataformat'] : 'asf');
1365 }
1366 $ThisFileInfo['bitrate'] = @$thisfile_audio['bitrate'] + @$thisfile_video['bitrate'];
1367 return true;
1368 }
ASFCodecListObjectTypeLookup($CodecListType)
RIFFparseWAVEFORMATex($WaveFormatExData)
RIFFfourccLookup($fourcc)