wp/wp-includes/ID3/module.audio-video.matroska.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
     1 <?php
     1 <?php
     2 /////////////////////////////////////////////////////////////////
     2 /////////////////////////////////////////////////////////////////
     3 /// getID3() by James Heinrich <info@getid3.org>               //
     3 /// getID3() by James Heinrich <info@getid3.org>               //
     4 //  available at http://getid3.sourceforge.net                 //
     4 //  available at http://getid3.sourceforge.net                 //
     5 //            or http://www.getid3.org                         //
     5 //            or http://www.getid3.org                         //
       
     6 //          also https://github.com/JamesHeinrich/getID3       //
     6 /////////////////////////////////////////////////////////////////
     7 /////////////////////////////////////////////////////////////////
     7 // See readme.txt for more details                             //
     8 // See readme.txt for more details                             //
     8 /////////////////////////////////////////////////////////////////
     9 /////////////////////////////////////////////////////////////////
     9 //                                                             //
    10 //                                                             //
    10 // module.audio-video.matriska.php                             //
    11 // module.audio-video.matriska.php                             //
   279 						if (isset($trackarray['DefaultDuration'])) { $track_info['frame_rate']  = round(1000000000 / $trackarray['DefaultDuration'], 3); }
   280 						if (isset($trackarray['DefaultDuration'])) { $track_info['frame_rate']  = round(1000000000 / $trackarray['DefaultDuration'], 3); }
   280 						if (isset($trackarray['CodecName']))       { $track_info['codec']       = $trackarray['CodecName']; }
   281 						if (isset($trackarray['CodecName']))       { $track_info['codec']       = $trackarray['CodecName']; }
   281 
   282 
   282 						switch ($trackarray['CodecID']) {
   283 						switch ($trackarray['CodecID']) {
   283 							case 'V_MS/VFW/FOURCC':
   284 							case 'V_MS/VFW/FOURCC':
   284 								if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, false)) {
   285 								getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
   285 									$this->warning('Unable to parse codec private data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio-video.riff.php"');
   286 
   286 									break;
       
   287 								}
       
   288 								$parsed = getid3_riff::ParseBITMAPINFOHEADER($trackarray['CodecPrivate']);
   287 								$parsed = getid3_riff::ParseBITMAPINFOHEADER($trackarray['CodecPrivate']);
   289 								$track_info['codec'] = getid3_riff::fourccLookup($parsed['fourcc']);
   288 								$track_info['codec'] = getid3_riff::fourccLookup($parsed['fourcc']);
   290 								$info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
   289 								$info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
   291 								break;
   290 								break;
   292 
   291 
   333 							case 'A_AC3':
   332 							case 'A_AC3':
   334 							case 'A_DTS':
   333 							case 'A_DTS':
   335 							case 'A_MPEG/L3':
   334 							case 'A_MPEG/L3':
   336 							case 'A_MPEG/L2':
   335 							case 'A_MPEG/L2':
   337 							case 'A_FLAC':
   336 							case 'A_FLAC':
   338 								if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, false)) {
   337 								getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, true);
   339 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio.'.$track_info['dataformat'].'.php"');
       
   340 									break;
       
   341 								}
       
   342 
   338 
   343 								if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
   339 								if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
   344 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
   340 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
   345 									break;
   341 									break;
   346 								}
   342 								}
   383 										$this->warning($class.'() says: ['.$newerror.']');
   379 										$this->warning($class.'() says: ['.$newerror.']');
   384 									}
   380 									}
   385 								}
   381 								}
   386 								if (!empty($getid3_temp->info['warning'])) {
   382 								if (!empty($getid3_temp->info['warning'])) {
   387 									foreach ($getid3_temp->info['warning'] as $newerror) {
   383 									foreach ($getid3_temp->info['warning'] as $newerror) {
   388 										if ($track_info['dataformat'] == 'mp3' && preg_match('/^Probable truncated file: expecting \d+ bytes of audio data, only found \d+ \(short by \d+ bytes\)$/', $newerror)) {
       
   389 											// LAME/Xing header is probably set, but audio data is chunked into Matroska file and near-impossible to verify if audio stream is complete, so ignore useless warning
       
   390 											continue;
       
   391 										}
       
   392 										$this->warning($class.'() says: ['.$newerror.']');
   384 										$this->warning($class.'() says: ['.$newerror.']');
   393 									}
   385 									}
   394 								}
   386 								}
   395 								unset($getid3_temp, $getid3_audio);
   387 								unset($getid3_temp, $getid3_audio);
   396 								break;
   388 								break;
   398 							case 'A_AAC':
   390 							case 'A_AAC':
   399 							case 'A_AAC/MPEG2/LC':
   391 							case 'A_AAC/MPEG2/LC':
   400 							case 'A_AAC/MPEG2/LC/SBR':
   392 							case 'A_AAC/MPEG2/LC/SBR':
   401 							case 'A_AAC/MPEG4/LC':
   393 							case 'A_AAC/MPEG4/LC':
   402 							case 'A_AAC/MPEG4/LC/SBR':
   394 							case 'A_AAC/MPEG4/LC/SBR':
   403 							    $this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated');
   395 								$this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated');
   404 								break;
   396 								break;
   405 
   397 
   406 							case 'A_VORBIS':
   398 							case 'A_VORBIS':
   407 								if (!isset($trackarray['CodecPrivate'])) {
   399 								if (!isset($trackarray['CodecPrivate'])) {
   408 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set');
   400 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set');
   413 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword');
   405 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword');
   414 									break;
   406 									break;
   415 								}
   407 								}
   416 								$vorbis_offset -= 1;
   408 								$vorbis_offset -= 1;
   417 
   409 
   418 								if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, false)) {
   410 								getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
   419 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio.ogg.php"');
       
   420 									break;
       
   421 								}
       
   422 
   411 
   423 								// create temp instance
   412 								// create temp instance
   424 								$getid3_temp = new getID3();
   413 								$getid3_temp = new getID3();
   425 
   414 
   426 								// analyze
   415 								// analyze
   453 								}
   442 								}
   454 								unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset);
   443 								unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset);
   455 								break;
   444 								break;
   456 
   445 
   457 							case 'A_MS/ACM':
   446 							case 'A_MS/ACM':
   458 								if (!getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, false)) {
   447 								getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
   459 									$this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because cannot include "module.audio-video.riff.php"');
       
   460 									break;
       
   461 								}
       
   462 
   448 
   463 								$parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
   449 								$parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
   464 								foreach ($parsed as $key => $value) {
   450 								foreach ($parsed as $key => $value) {
   465 									if ($key != 'raw') {
   451 									if ($key != 'raw') {
   466 										$track_info[$key] = $value;
   452 										$track_info[$key] = $value;
   513 
   499 
   514 		while ($this->getEBMLelement($top_element, $info['avdataend'])) {
   500 		while ($this->getEBMLelement($top_element, $info['avdataend'])) {
   515 			switch ($top_element['id']) {
   501 			switch ($top_element['id']) {
   516 
   502 
   517 				case EBML_ID_EBML:
   503 				case EBML_ID_EBML:
   518 					$info['fileformat'] = 'matroska';
       
   519 					$info['matroska']['header']['offset'] = $top_element['offset'];
   504 					$info['matroska']['header']['offset'] = $top_element['offset'];
   520 					$info['matroska']['header']['length'] = $top_element['length'];
   505 					$info['matroska']['header']['length'] = $top_element['length'];
   521 
   506 
   522 					while ($this->getEBMLelement($element_data, $top_element['end'], true)) {
   507 					while ($this->getEBMLelement($element_data, $top_element['end'], true)) {
   523 						switch ($element_data['id']) {
   508 						switch ($element_data['id']) {
   532 								break;
   517 								break;
   533 
   518 
   534 							case EBML_ID_DOCTYPE:
   519 							case EBML_ID_DOCTYPE:
   535 								$element_data['data'] = getid3_lib::trimNullByte($element_data['data']);
   520 								$element_data['data'] = getid3_lib::trimNullByte($element_data['data']);
   536 								$info['matroska']['doctype'] = $element_data['data'];
   521 								$info['matroska']['doctype'] = $element_data['data'];
       
   522 								$info['fileformat'] = $element_data['data'];
   537 								break;
   523 								break;
   538 
   524 
   539 							default:
   525 							default:
   540 								$this->unhandledElement('header', __LINE__, $element_data);
   526 								$this->unhandledElement('header', __LINE__, $element_data);
   541 						}
   527 						}
  1524 			$CodecIDlist['V_MPEG4/ISO/AP']   = 'mpeg4';
  1510 			$CodecIDlist['V_MPEG4/ISO/AP']   = 'mpeg4';
  1525 			$CodecIDlist['V_MPEG4/ISO/ASP']  = 'mpeg4';
  1511 			$CodecIDlist['V_MPEG4/ISO/ASP']  = 'mpeg4';
  1526 			$CodecIDlist['V_MPEG4/ISO/AVC']  = 'h264';
  1512 			$CodecIDlist['V_MPEG4/ISO/AVC']  = 'h264';
  1527 			$CodecIDlist['V_MPEG4/ISO/SP']   = 'mpeg4';
  1513 			$CodecIDlist['V_MPEG4/ISO/SP']   = 'mpeg4';
  1528 			$CodecIDlist['V_VP8']            = 'vp8';
  1514 			$CodecIDlist['V_VP8']            = 'vp8';
  1529 			$CodecIDlist['V_MS/VFW/FOURCC']  = 'riff';
  1515 			$CodecIDlist['V_MS/VFW/FOURCC']  = 'vcm'; // Microsoft (TM) Video Codec Manager (VCM)
  1530 			$CodecIDlist['A_MS/ACM']         = 'riff';
  1516 			$CodecIDlist['A_MS/ACM']         = 'acm'; // Microsoft (TM) Audio Codec Manager (ACM)
  1531 		}
  1517 		}
  1532 		return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
  1518 		return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
  1533 	}
  1519 	}
  1534 
  1520 
  1535 	private static function EBMLidName($value) {
  1521 	private static function EBMLidName($value) {