232 |
232 |
233 // parse container |
233 // parse container |
234 try { |
234 try { |
235 $this->parseEBML($info); |
235 $this->parseEBML($info); |
236 } catch (Exception $e) { |
236 } catch (Exception $e) { |
237 $info['error'][] = 'EBML parser: '.$e->getMessage(); |
237 $this->error('EBML parser: '.$e->getMessage()); |
238 } |
238 } |
239 |
239 |
240 // calculate playtime |
240 // calculate playtime |
241 if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) { |
241 if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) { |
242 foreach ($info['matroska']['info'] as $key => $infoarray) { |
242 foreach ($info['matroska']['info'] as $key => $infoarray) { |
328 case 'A_PCM/INT/BIG': |
328 case 'A_PCM/INT/BIG': |
329 $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth']; |
329 $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth']; |
330 break; |
330 break; |
331 |
331 |
332 case 'A_AC3': |
332 case 'A_AC3': |
|
333 case 'A_EAC3': |
333 case 'A_DTS': |
334 case 'A_DTS': |
334 case 'A_MPEG/L3': |
335 case 'A_MPEG/L3': |
335 case 'A_MPEG/L2': |
336 case 'A_MPEG/L2': |
336 case 'A_FLAC': |
337 case 'A_FLAC': |
337 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, true); |
338 $module_dataformat = ($track_info['dataformat'] == 'mp2' ? 'mp3' : ($track_info['dataformat'] == 'eac3' ? 'ac3' : $track_info['dataformat'])); |
|
339 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.$module_dataformat.'.php', __FILE__, true); |
338 |
340 |
339 if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) { |
341 if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) { |
340 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set'); |
342 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set'); |
341 break; |
343 break; |
342 } |
344 } |
350 if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') { |
352 if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') { |
351 $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length']; |
353 $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length']; |
352 } |
354 } |
353 |
355 |
354 // analyze |
356 // analyze |
355 $class = 'getid3_'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']); |
357 $class = 'getid3_'.$module_dataformat; |
356 $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat']; |
358 $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat']; |
357 $getid3_audio = new $class($getid3_temp, __CLASS__); |
359 $getid3_audio = new $class($getid3_temp, __CLASS__); |
358 if ($track_info['dataformat'] == 'flac') { |
360 if ($track_info['dataformat'] == 'flac') { |
359 $getid3_audio->AnalyzeString($trackarray['CodecPrivate']); |
361 $getid3_audio->AnalyzeString($trackarray['CodecPrivate']); |
360 } |
362 } |
522 $info['fileformat'] = $element_data['data']; |
525 $info['fileformat'] = $element_data['data']; |
523 break; |
526 break; |
524 |
527 |
525 default: |
528 default: |
526 $this->unhandledElement('header', __LINE__, $element_data); |
529 $this->unhandledElement('header', __LINE__, $element_data); |
|
530 break; |
527 } |
531 } |
528 |
532 |
529 unset($element_data['offset'], $element_data['end']); |
533 unset($element_data['offset'], $element_data['end']); |
530 $info['matroska']['header']['elements'][] = $element_data; |
534 $info['matroska']['header']['elements'][] = $element_data; |
531 } |
535 } |
560 $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']); |
564 $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']); |
561 break; |
565 break; |
562 |
566 |
563 default: |
567 default: |
564 $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); } |
568 $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); } |
|
569 break; |
565 } |
570 } |
566 |
571 if (!isset($seek_entry['target_id'])) { |
567 if ($seek_entry['target_id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required |
572 $this->warning('seek_entry[target_id] unexpectedly not set at '.$seek_entry['offset']); |
|
573 break; |
|
574 } |
|
575 if (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !self::$hide_clusters) { // collect clusters only if required |
568 $info['matroska']['seek'][] = $seek_entry; |
576 $info['matroska']['seek'][] = $seek_entry; |
569 } |
577 } |
570 break; |
578 break; |
571 |
579 |
572 default: |
580 default: |
573 $this->unhandledElement('seekhead', __LINE__, $seek_entry); |
581 $this->unhandledElement('seekhead', __LINE__, $seek_entry); |
|
582 break; |
574 } |
583 } |
575 } |
584 } |
576 break; |
585 break; |
577 |
586 |
578 case EBML_ID_TRACKS: // A top-level block of information with many tracks described. |
587 case EBML_ID_TRACKS: // A top-level block of information with many tracks described. |
711 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
722 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
712 break; |
723 break; |
713 |
724 |
714 default: |
725 default: |
715 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); |
726 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); |
|
727 break; |
716 } |
728 } |
717 } |
729 } |
718 break; |
730 break; |
719 |
731 |
720 case EBML_ID_CONTENTENCRYPTION: |
732 case EBML_ID_CONTENTENCRYPTION: |
734 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
746 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
735 break; |
747 break; |
736 |
748 |
737 default: |
749 default: |
738 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); |
750 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement); |
|
751 break; |
739 } |
752 } |
740 } |
753 } |
741 break; |
754 break; |
742 |
755 |
743 default: |
756 default: |
744 $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement); |
757 $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement); |
|
758 break; |
745 } |
759 } |
746 } |
760 } |
747 break; |
761 break; |
748 |
762 |
749 default: |
763 default: |
750 $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement); |
764 $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement); |
|
765 break; |
751 } |
766 } |
752 } |
767 } |
753 break; |
768 break; |
754 |
769 |
755 default: |
770 default: |
756 $this->unhandledElement('track', __LINE__, $subelement); |
771 $this->unhandledElement('track', __LINE__, $subelement); |
|
772 break; |
757 } |
773 } |
758 } |
774 } |
759 |
775 |
760 $info['matroska']['tracks']['tracks'][] = $track_entry; |
776 $info['matroska']['tracks']['tracks'][] = $track_entry; |
761 break; |
777 break; |
762 |
778 |
763 default: |
779 default: |
764 $this->unhandledElement('tracks', __LINE__, $track_entry); |
780 $this->unhandledElement('tracks', __LINE__, $track_entry); |
|
781 break; |
765 } |
782 } |
766 } |
783 } |
767 break; |
784 break; |
768 |
785 |
769 case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file. |
786 case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file. |
823 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); |
840 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']); |
824 break; |
841 break; |
825 |
842 |
826 default: |
843 default: |
827 $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement); |
844 $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement); |
|
845 break; |
828 } |
846 } |
829 } |
847 } |
830 $info_entry[$subelement['id_name']] = $chaptertranslate_entry; |
848 $info_entry[$subelement['id_name']] = $chaptertranslate_entry; |
831 break; |
849 break; |
832 |
850 |
833 default: |
851 default: |
834 $this->unhandledElement('info', __LINE__, $subelement); |
852 $this->unhandledElement('info', __LINE__, $subelement); |
|
853 break; |
835 } |
854 } |
836 } |
855 } |
837 $info['matroska']['info'][] = $info_entry; |
856 $info['matroska']['info'][] = $info_entry; |
838 break; |
857 break; |
839 |
858 |
877 $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); |
897 $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); |
878 break; |
898 break; |
879 |
899 |
880 default: |
900 default: |
881 $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement); |
901 $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement); |
|
902 break; |
882 } |
903 } |
883 } |
904 } |
884 $cues_entry[] = $cuepoint_entry; |
905 $cues_entry[] = $cuepoint_entry; |
885 break; |
906 break; |
886 |
907 |
887 default: |
908 default: |
888 $this->unhandledElement('cues', __LINE__, $subelement); |
909 $this->unhandledElement('cues', __LINE__, $subelement); |
|
910 break; |
889 } |
911 } |
890 } |
912 } |
891 $info['matroska']['cues'] = $cues_entry; |
913 $info['matroska']['cues'] = $cues_entry; |
892 break; |
914 break; |
893 |
915 |
936 $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']); |
959 $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']); |
937 break; |
960 break; |
938 |
961 |
939 default: |
962 default: |
940 $this->unhandledElement('tags.tag', __LINE__, $sub_subelement); |
963 $this->unhandledElement('tags.tag', __LINE__, $sub_subelement); |
|
964 break; |
941 } |
965 } |
942 } |
966 } |
943 $tags_entry[] = $tag_entry; |
967 $tags_entry[] = $tag_entry; |
944 break; |
968 break; |
945 |
969 |
946 default: |
970 default: |
947 $this->unhandledElement('tags', __LINE__, $subelement); |
971 $this->unhandledElement('tags', __LINE__, $subelement); |
|
972 break; |
948 } |
973 } |
949 } |
974 } |
950 $info['matroska']['tags'] = $tags_entry; |
975 $info['matroska']['tags'] = $tags_entry; |
951 break; |
976 break; |
952 |
977 |
983 $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); |
1008 $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']); |
984 break; |
1009 break; |
985 |
1010 |
986 default: |
1011 default: |
987 $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement); |
1012 $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement); |
|
1013 break; |
988 } |
1014 } |
989 } |
1015 } |
990 $info['matroska']['attachments'][] = $attachedfile_entry; |
1016 $info['matroska']['attachments'][] = $attachedfile_entry; |
991 break; |
1017 break; |
992 |
1018 |
993 default: |
1019 default: |
994 $this->unhandledElement('attachments', __LINE__, $subelement); |
1020 $this->unhandledElement('attachments', __LINE__, $subelement); |
|
1021 break; |
995 } |
1022 } |
996 } |
1023 } |
997 break; |
1024 break; |
998 |
1025 |
999 case EBML_ID_CHAPTERS: |
1026 case EBML_ID_CHAPTERS: |
1068 $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
1096 $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data']; |
1069 break; |
1097 break; |
1070 |
1098 |
1071 default: |
1099 default: |
1072 $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement); |
1100 $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement); |
|
1101 break; |
1073 } |
1102 } |
1074 } |
1103 } |
1075 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry; |
1104 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry; |
1076 break; |
1105 break; |
1077 |
1106 |
1078 default: |
1107 default: |
1079 $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement); |
1108 $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement); |
|
1109 break; |
1080 } |
1110 } |
1081 } |
1111 } |
1082 $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry; |
1112 $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry; |
1083 break; |
1113 break; |
1084 |
1114 |
1085 default: |
1115 default: |
1086 $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement); |
1116 $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement); |
|
1117 break; |
1087 } |
1118 } |
1088 } |
1119 } |
1089 $info['matroska']['chapters'][] = $editionentry_entry; |
1120 $info['matroska']['chapters'][] = $editionentry_entry; |
1090 break; |
1121 break; |
1091 |
1122 |
1092 default: |
1123 default: |
1093 $this->unhandledElement('chapters', __LINE__, $subelement); |
1124 $this->unhandledElement('chapters', __LINE__, $subelement); |
|
1125 break; |
1094 } |
1126 } |
1095 } |
1127 } |
1096 break; |
1128 break; |
1097 |
1129 |
1098 case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure. |
1130 case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure. |
1158 $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info); |
1192 $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info); |
1159 break; |
1193 break; |
1160 |
1194 |
1161 default: |
1195 default: |
1162 $this->unhandledElement('cluster', __LINE__, $subelement); |
1196 $this->unhandledElement('cluster', __LINE__, $subelement); |
|
1197 break; |
1163 } |
1198 } |
1164 $this->current_offset = $subelement['end']; |
1199 $this->current_offset = $subelement['end']; |
1165 } |
1200 } |
1166 if (!self::$hide_clusters) { |
1201 if (!self::$hide_clusters) { |
1167 $info['matroska']['cluster'][] = $cluster_entry; |
1202 $info['matroska']['cluster'][] = $cluster_entry; |
1488 static $CodecIDlist = array(); |
1526 static $CodecIDlist = array(); |
1489 if (empty($CodecIDlist)) { |
1527 if (empty($CodecIDlist)) { |
1490 $CodecIDlist['A_AAC'] = 'aac'; |
1528 $CodecIDlist['A_AAC'] = 'aac'; |
1491 $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac'; |
1529 $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac'; |
1492 $CodecIDlist['A_AC3'] = 'ac3'; |
1530 $CodecIDlist['A_AC3'] = 'ac3'; |
|
1531 $CodecIDlist['A_EAC3'] = 'eac3'; |
1493 $CodecIDlist['A_DTS'] = 'dts'; |
1532 $CodecIDlist['A_DTS'] = 'dts'; |
1494 $CodecIDlist['A_FLAC'] = 'flac'; |
1533 $CodecIDlist['A_FLAC'] = 'flac'; |
1495 $CodecIDlist['A_MPEG/L1'] = 'mp1'; |
1534 $CodecIDlist['A_MPEG/L1'] = 'mp1'; |
1496 $CodecIDlist['A_MPEG/L2'] = 'mp2'; |
1535 $CodecIDlist['A_MPEG/L2'] = 'mp2'; |
1497 $CodecIDlist['A_MPEG/L3'] = 'mp3'; |
1536 $CodecIDlist['A_MPEG/L3'] = 'mp3'; |