ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
getid3_matroska Class Reference

@tutorial http://www.matroska.org/technical/specs/index.html More...

+ Inheritance diagram for getid3_matroska:
+ Collaboration diagram for getid3_matroska:

Public Member Functions

 Analyze ()
 
- Public Member Functions inherited from getid3_handler
 __construct (getID3 $getid3, $call_module=null)
 
 Analyze ()
 
 AnalyzeString ($string)
 
 setStringMode ($string)
 
 saveAttachment ($name, $offset, $length, $image_mime=null)
 

Static Public Member Functions

static TargetTypeValue ($target_type)
 
static BlockLacingType ($lacingtype)
 
static CodecIDtoCommonName ($codecid)
 
static displayUnit ($value)
 

Static Public Attributes

static $hide_clusters = true
 
static $parse_whole_file = false
 

Private Member Functions

 parseEBML (&$info)
 
 EnsureBufferHasEnoughData ($min_data=1024)
 
 readEBMLint ()
 
 readEBMLelementData ($length, $check_buffer=false)
 
 getEBMLelement (&$element, $parent_end, $get_data=false)
 
 unhandledElement ($type, $line, $element)
 
 ExtractCommentsSimpleTag ($SimpleTagArray)
 
 HandleEMBLSimpleTag ($parent_end)
 
 HandleEMBLClusterBlock ($element, $block_type, &$info)
 

Static Private Member Functions

static EBML2Int ($EBMLstring)
 
static EBMLdate2unix ($EBMLdatestamp)
 
static EBMLidName ($value)
 
static getDefaultStreamInfo ($streams)
 

Private Attributes

 $EBMLbuffer = ''
 
 $EBMLbuffer_offset = 0
 
 $EBMLbuffer_length = 0
 
 $current_offset = 0
 
 $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID)
 

Additional Inherited Members

- Protected Member Functions inherited from getid3_handler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
 notice ($text)
 
- Protected Attributes inherited from getid3_handler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

Detailed Description

@tutorial http://www.matroska.org/technical/specs/index.html

Todo:

Rewrite EBML parser to reduce it's size and honor default element values

After rewrite implement stream size calculation, that will provide additional useful info and enable AAC/FLAC audio bitrate detection

Definition at line 216 of file module.audio-video.matroska.php.

Member Function Documentation

◆ Analyze()

getid3_matroska::Analyze ( )

Reimplemented from getid3_handler.

Definition at line 229 of file module.audio-video.matroska.php.

230 {
231 $info = &$this->getid3->info;
232
233 // parse container
234 try {
235 $this->parseEBML($info);
236 } catch (Exception $e) {
237 $this->error('EBML parser: '.$e->getMessage());
238 }
239
240 // calculate playtime
241 if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
242 foreach ($info['matroska']['info'] as $key => $infoarray) {
243 if (isset($infoarray['Duration'])) {
244 // TimecodeScale is how many nanoseconds each Duration unit is
245 $info['playtime_seconds'] = $infoarray['Duration'] * ((isset($infoarray['TimecodeScale']) ? $infoarray['TimecodeScale'] : 1000000) / 1000000000);
246 break;
247 }
248 }
249 }
250
251 // extract tags
252 if (isset($info['matroska']['tags']) && is_array($info['matroska']['tags'])) {
253 foreach ($info['matroska']['tags'] as $key => $infoarray) {
254 $this->ExtractCommentsSimpleTag($infoarray);
255 }
256 }
257
258 // process tracks
259 if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
260 foreach ($info['matroska']['tracks']['tracks'] as $key => $trackarray) {
261
262 $track_info = array();
263 $track_info['dataformat'] = self::CodecIDtoCommonName($trackarray['CodecID']);
264 $track_info['default'] = (isset($trackarray['FlagDefault']) ? $trackarray['FlagDefault'] : true);
265 if (isset($trackarray['Name'])) { $track_info['name'] = $trackarray['Name']; }
266
267 switch ($trackarray['TrackType']) {
268
269 case 1: // Video
270 $track_info['resolution_x'] = $trackarray['PixelWidth'];
271 $track_info['resolution_y'] = $trackarray['PixelHeight'];
272 $track_info['display_unit'] = self::displayUnit(isset($trackarray['DisplayUnit']) ? $trackarray['DisplayUnit'] : 0);
273 $track_info['display_x'] = (isset($trackarray['DisplayWidth']) ? $trackarray['DisplayWidth'] : $trackarray['PixelWidth']);
274 $track_info['display_y'] = (isset($trackarray['DisplayHeight']) ? $trackarray['DisplayHeight'] : $trackarray['PixelHeight']);
275
276 if (isset($trackarray['PixelCropBottom'])) { $track_info['crop_bottom'] = $trackarray['PixelCropBottom']; }
277 if (isset($trackarray['PixelCropTop'])) { $track_info['crop_top'] = $trackarray['PixelCropTop']; }
278 if (isset($trackarray['PixelCropLeft'])) { $track_info['crop_left'] = $trackarray['PixelCropLeft']; }
279 if (isset($trackarray['PixelCropRight'])) { $track_info['crop_right'] = $trackarray['PixelCropRight']; }
280 if (isset($trackarray['DefaultDuration'])) { $track_info['frame_rate'] = round(1000000000 / $trackarray['DefaultDuration'], 3); }
281 if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; }
282
283 switch ($trackarray['CodecID']) {
284 case 'V_MS/VFW/FOURCC':
285 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
286
287 $parsed = getid3_riff::ParseBITMAPINFOHEADER($trackarray['CodecPrivate']);
288 $track_info['codec'] = getid3_riff::fourccLookup($parsed['fourcc']);
289 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
290 break;
291
292 /*case 'V_MPEG4/ISO/AVC':
293 $h264['profile'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 1, 1));
294 $h264['level'] = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 3, 1));
295 $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 4, 1));
296 $h264['NALUlength'] = ($rn & 3) + 1;
297 $rn = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], 5, 1));
298 $nsps = ($rn & 31);
299 $offset = 6;
300 for ($i = 0; $i < $nsps; $i ++) {
301 $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2));
302 $h264['SPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length);
303 $offset += 2 + $length;
304 }
305 $npps = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 1));
306 $offset += 1;
307 for ($i = 0; $i < $npps; $i ++) {
308 $length = getid3_lib::BigEndian2Int(substr($trackarray['CodecPrivate'], $offset, 2));
309 $h264['PPS'][] = substr($trackarray['CodecPrivate'], $offset + 2, $length);
310 $offset += 2 + $length;
311 }
312 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $h264;
313 break;*/
314 }
315
316 $info['video']['streams'][] = $track_info;
317 break;
318
319 case 2: // Audio
320 $track_info['sample_rate'] = (isset($trackarray['SamplingFrequency']) ? $trackarray['SamplingFrequency'] : 8000.0);
321 $track_info['channels'] = (isset($trackarray['Channels']) ? $trackarray['Channels'] : 1);
322 $track_info['language'] = (isset($trackarray['Language']) ? $trackarray['Language'] : 'eng');
323 if (isset($trackarray['BitDepth'])) { $track_info['bits_per_sample'] = $trackarray['BitDepth']; }
324 if (isset($trackarray['CodecName'])) { $track_info['codec'] = $trackarray['CodecName']; }
325
326 switch ($trackarray['CodecID']) {
327 case 'A_PCM/INT/LIT':
328 case 'A_PCM/INT/BIG':
329 $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth'];
330 break;
331
332 case 'A_AC3':
333 case 'A_EAC3':
334 case 'A_DTS':
335 case 'A_MPEG/L3':
336 case 'A_MPEG/L2':
337 case 'A_FLAC':
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);
340
341 if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
342 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
343 break;
344 }
345
346 // create temp instance
347 $getid3_temp = new getID3();
348 if ($track_info['dataformat'] != 'flac') {
349 $getid3_temp->openfile($this->getid3->filename);
350 }
351 $getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'];
352 if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') {
353 $getid3_temp->info['avdataend'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'] + $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['length'];
354 }
355
356 // analyze
357 $class = 'getid3_'.$module_dataformat;
358 $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat'];
359 $getid3_audio = new $class($getid3_temp, __CLASS__);
360 if ($track_info['dataformat'] == 'flac') {
361 $getid3_audio->AnalyzeString($trackarray['CodecPrivate']);
362 }
363 else {
364 $getid3_audio->Analyze();
365 }
366 if (!empty($getid3_temp->info[$header_data_key])) {
367 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key];
368 if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
369 foreach ($getid3_temp->info['audio'] as $key => $value) {
370 $track_info[$key] = $value;
371 }
372 }
373 }
374 else {
375 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because '.$class.'::Analyze() failed at offset '.$getid3_temp->info['avdataoffset']);
376 }
377
378 // copy errors and warnings
379 if (!empty($getid3_temp->info['error'])) {
380 foreach ($getid3_temp->info['error'] as $newerror) {
381 $this->warning($class.'() says: ['.$newerror.']');
382 }
383 }
384 if (!empty($getid3_temp->info['warning'])) {
385 foreach ($getid3_temp->info['warning'] as $newerror) {
386 $this->warning($class.'() says: ['.$newerror.']');
387 }
388 }
389 unset($getid3_temp, $getid3_audio);
390 break;
391
392 case 'A_AAC':
393 case 'A_AAC/MPEG2/LC':
394 case 'A_AAC/MPEG2/LC/SBR':
395 case 'A_AAC/MPEG4/LC':
396 case 'A_AAC/MPEG4/LC/SBR':
397 $this->warning($trackarray['CodecID'].' audio data contains no header, audio/video bitrates can\'t be calculated');
398 break;
399
400 case 'A_VORBIS':
401 if (!isset($trackarray['CodecPrivate'])) {
402 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data not set');
403 break;
404 }
405 $vorbis_offset = strpos($trackarray['CodecPrivate'], 'vorbis', 1);
406 if ($vorbis_offset === false) {
407 $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because CodecPrivate data does not contain "vorbis" keyword');
408 break;
409 }
410 $vorbis_offset -= 1;
411
412 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
413
414 // create temp instance
415 $getid3_temp = new getID3();
416
417 // analyze
418 $getid3_ogg = new getid3_ogg($getid3_temp);
419 $oggpageinfo['page_seqno'] = 0;
420 $getid3_ogg->ParseVorbisPageHeader($trackarray['CodecPrivate'], $vorbis_offset, $oggpageinfo);
421 if (!empty($getid3_temp->info['ogg'])) {
422 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg'];
423 if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
424 foreach ($getid3_temp->info['audio'] as $key => $value) {
425 $track_info[$key] = $value;
426 }
427 }
428 }
429
430 // copy errors and warnings
431 if (!empty($getid3_temp->info['error'])) {
432 foreach ($getid3_temp->info['error'] as $newerror) {
433 $this->warning('getid3_ogg() says: ['.$newerror.']');
434 }
435 }
436 if (!empty($getid3_temp->info['warning'])) {
437 foreach ($getid3_temp->info['warning'] as $newerror) {
438 $this->warning('getid3_ogg() says: ['.$newerror.']');
439 }
440 }
441
442 if (!empty($getid3_temp->info['ogg']['bitrate_nominal'])) {
443 $track_info['bitrate'] = $getid3_temp->info['ogg']['bitrate_nominal'];
444 }
445 unset($getid3_temp, $getid3_ogg, $oggpageinfo, $vorbis_offset);
446 break;
447
448 case 'A_MS/ACM':
449 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
450
451 $parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
452 foreach ($parsed as $key => $value) {
453 if ($key != 'raw') {
454 $track_info[$key] = $value;
455 }
456 }
457 $info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
458 break;
459
460 default:
461 $this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"');
462 break;
463 }
464
465 $info['audio']['streams'][] = $track_info;
466 break;
467 }
468 }
469
470 if (!empty($info['video']['streams'])) {
471 $info['video'] = self::getDefaultStreamInfo($info['video']['streams']);
472 }
473 if (!empty($info['audio']['streams'])) {
474 $info['audio'] = self::getDefaultStreamInfo($info['audio']['streams']);
475 }
476 }
477
478 // process attachments
479 if (isset($info['matroska']['attachments']) && $this->getid3->option_save_attachments !== getID3::ATTACHMENTS_NONE) {
480 foreach ($info['matroska']['attachments'] as $i => $entry) {
481 if (strpos($entry['FileMimeType'], 'image/') === 0 && !empty($entry['FileData'])) {
482 $info['matroska']['comments']['picture'][] = array('data' => $entry['FileData'], 'image_mime' => $entry['FileMimeType'], 'filename' => $entry['FileName']);
483 }
484 }
485 }
486
487 // determine mime type
488 if (!empty($info['video']['streams'])) {
489 $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'video/webm' : 'video/x-matroska');
490 } elseif (!empty($info['audio']['streams'])) {
491 $info['mime_type'] = ($info['matroska']['doctype'] == 'webm' ? 'audio/webm' : 'audio/x-matroska');
492 } elseif (isset($info['mime_type'])) {
493 unset($info['mime_type']);
494 }
495
496 return true;
497 }
const ATTACHMENTS_NONE
Definition: getid3.php:118
warning($text)
Definition: getid3.php:1758
error($text)
Definition: getid3.php:1752
static IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
static CodecIDtoCommonName($codecid)
static getDefaultStreamInfo($streams)
ExtractCommentsSimpleTag($SimpleTagArray)
static parseWAVEFORMATex($WaveFormatExData)
static ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true)
static fourccLookup($fourcc)
$key
Definition: croninfo.php:18
$i
Definition: disco.tpl.php:19
$info
Definition: index.php:5

References $i, $info, $key, getID3\ATTACHMENTS_NONE, CodecIDtoCommonName(), displayUnit(), getid3_handler\error(), ExtractCommentsSimpleTag(), getid3_riff\fourccLookup(), getDefaultStreamInfo(), getid3_lib\IncludeDependency(), getid3_riff\ParseBITMAPINFOHEADER(), parseEBML(), getid3_riff\parseWAVEFORMATex(), and getid3_handler\warning().

+ Here is the call graph for this function:

◆ BlockLacingType()

static getid3_matroska::BlockLacingType (   $lacingtype)
static

Definition at line 1512 of file module.audio-video.matroska.php.

1512 {
1513 // http://matroska.org/technical/specs/index.html#block_structure
1514 static $BlockLacingType = array();
1515 if (empty($BlockLacingType)) {
1516 $BlockLacingType[0x00] = 'no lacing';
1517 $BlockLacingType[0x01] = 'Xiph lacing';
1518 $BlockLacingType[0x02] = 'fixed-size lacing';
1519 $BlockLacingType[0x03] = 'EBML lacing';
1520 }
1521 return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype);
1522 }

Referenced by HandleEMBLClusterBlock().

+ Here is the caller graph for this function:

◆ CodecIDtoCommonName()

static getid3_matroska::CodecIDtoCommonName (   $codecid)
static

Definition at line 1524 of file module.audio-video.matroska.php.

1524 {
1525 // http://www.matroska.org/technical/specs/codecid/index.html
1526 static $CodecIDlist = array();
1527 if (empty($CodecIDlist)) {
1528 $CodecIDlist['A_AAC'] = 'aac';
1529 $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac';
1530 $CodecIDlist['A_AC3'] = 'ac3';
1531 $CodecIDlist['A_EAC3'] = 'eac3';
1532 $CodecIDlist['A_DTS'] = 'dts';
1533 $CodecIDlist['A_FLAC'] = 'flac';
1534 $CodecIDlist['A_MPEG/L1'] = 'mp1';
1535 $CodecIDlist['A_MPEG/L2'] = 'mp2';
1536 $CodecIDlist['A_MPEG/L3'] = 'mp3';
1537 $CodecIDlist['A_PCM/INT/LIT'] = 'pcm'; // PCM Integer Little Endian
1538 $CodecIDlist['A_PCM/INT/BIG'] = 'pcm'; // PCM Integer Big Endian
1539 $CodecIDlist['A_QUICKTIME/QDMC'] = 'quicktime'; // Quicktime: QDesign Music
1540 $CodecIDlist['A_QUICKTIME/QDM2'] = 'quicktime'; // Quicktime: QDesign Music v2
1541 $CodecIDlist['A_VORBIS'] = 'vorbis';
1542 $CodecIDlist['V_MPEG1'] = 'mpeg';
1543 $CodecIDlist['V_THEORA'] = 'theora';
1544 $CodecIDlist['V_REAL/RV40'] = 'real';
1545 $CodecIDlist['V_REAL/RV10'] = 'real';
1546 $CodecIDlist['V_REAL/RV20'] = 'real';
1547 $CodecIDlist['V_REAL/RV30'] = 'real';
1548 $CodecIDlist['V_QUICKTIME'] = 'quicktime'; // Quicktime
1549 $CodecIDlist['V_MPEG4/ISO/AP'] = 'mpeg4';
1550 $CodecIDlist['V_MPEG4/ISO/ASP'] = 'mpeg4';
1551 $CodecIDlist['V_MPEG4/ISO/AVC'] = 'h264';
1552 $CodecIDlist['V_MPEG4/ISO/SP'] = 'mpeg4';
1553 $CodecIDlist['V_VP8'] = 'vp8';
1554 $CodecIDlist['V_MS/VFW/FOURCC'] = 'vcm'; // Microsoft (TM) Video Codec Manager (VCM)
1555 $CodecIDlist['A_MS/ACM'] = 'acm'; // Microsoft (TM) Audio Codec Manager (ACM)
1556 }
1557 return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
1558 }

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ displayUnit()

static getid3_matroska::displayUnit (   $value)
static

Definition at line 1758 of file module.audio-video.matroska.php.

1758 {
1759 // http://www.matroska.org/technical/specs/index.html#DisplayUnit
1760 static $units = array(
1761 0 => 'pixels',
1762 1 => 'centimeters',
1763 2 => 'inches',
1764 3 => 'Display Aspect Ratio');
1765
1766 return (isset($units[$value]) ? $units[$value] : 'unknown');
1767 }

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ EBML2Int()

static getid3_matroska::EBML2Int (   $EBMLstring)
staticprivate

Definition at line 1449 of file module.audio-video.matroska.php.

1449 {
1450 // http://matroska.org/specs/
1451
1452 // Element ID coded with an UTF-8 like system:
1453 // 1xxx xxxx - Class A IDs (2^7 -2 possible values) (base 0x8X)
1454 // 01xx xxxx xxxx xxxx - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX)
1455 // 001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX)
1456 // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX)
1457 // Values with all x at 0 and 1 are reserved (hence the -2).
1458
1459 // Data size, in octets, is also coded with an UTF-8 like system :
1460 // 1xxx xxxx - value 0 to 2^7-2
1461 // 01xx xxxx xxxx xxxx - value 0 to 2^14-2
1462 // 001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2
1463 // 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2
1464 // 0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2
1465 // 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2
1466 // 0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2
1467 // 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2
1468
1469 $first_byte_int = ord($EBMLstring[0]);
1470 if (0x80 & $first_byte_int) {
1471 $EBMLstring[0] = chr($first_byte_int & 0x7F);
1472 } elseif (0x40 & $first_byte_int) {
1473 $EBMLstring[0] = chr($first_byte_int & 0x3F);
1474 } elseif (0x20 & $first_byte_int) {
1475 $EBMLstring[0] = chr($first_byte_int & 0x1F);
1476 } elseif (0x10 & $first_byte_int) {
1477 $EBMLstring[0] = chr($first_byte_int & 0x0F);
1478 } elseif (0x08 & $first_byte_int) {
1479 $EBMLstring[0] = chr($first_byte_int & 0x07);
1480 } elseif (0x04 & $first_byte_int) {
1481 $EBMLstring[0] = chr($first_byte_int & 0x03);
1482 } elseif (0x02 & $first_byte_int) {
1483 $EBMLstring[0] = chr($first_byte_int & 0x01);
1484 } elseif (0x01 & $first_byte_int) {
1485 $EBMLstring[0] = chr($first_byte_int & 0x00);
1486 }
1487
1488 return getid3_lib::BigEndian2Int($EBMLstring);
1489 }
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:263

References getid3_lib\BigEndian2Int().

Referenced by parseEBML(), and readEBMLint().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EBMLdate2unix()

static getid3_matroska::EBMLdate2unix (   $EBMLdatestamp)
staticprivate

Definition at line 1491 of file module.audio-video.matroska.php.

1491 {
1492 // Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC)
1493 // 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC
1494 return round(($EBMLdatestamp / 1000000000) + 978307200);
1495 }

Referenced by parseEBML().

+ Here is the caller graph for this function:

◆ EBMLidName()

static getid3_matroska::EBMLidName (   $value)
staticprivate

Definition at line 1560 of file module.audio-video.matroska.php.

1560 {
1561 static $EBMLidList = array();
1562 if (empty($EBMLidList)) {
1563 $EBMLidList[EBML_ID_ASPECTRATIOTYPE] = 'AspectRatioType';
1564 $EBMLidList[EBML_ID_ATTACHEDFILE] = 'AttachedFile';
1565 $EBMLidList[EBML_ID_ATTACHMENTLINK] = 'AttachmentLink';
1566 $EBMLidList[EBML_ID_ATTACHMENTS] = 'Attachments';
1567 $EBMLidList[EBML_ID_AUDIO] = 'Audio';
1568 $EBMLidList[EBML_ID_BITDEPTH] = 'BitDepth';
1569 $EBMLidList[EBML_ID_CHANNELPOSITIONS] = 'ChannelPositions';
1570 $EBMLidList[EBML_ID_CHANNELS] = 'Channels';
1571 $EBMLidList[EBML_ID_CHAPCOUNTRY] = 'ChapCountry';
1572 $EBMLidList[EBML_ID_CHAPLANGUAGE] = 'ChapLanguage';
1573 $EBMLidList[EBML_ID_CHAPPROCESS] = 'ChapProcess';
1574 $EBMLidList[EBML_ID_CHAPPROCESSCODECID] = 'ChapProcessCodecID';
1575 $EBMLidList[EBML_ID_CHAPPROCESSCOMMAND] = 'ChapProcessCommand';
1576 $EBMLidList[EBML_ID_CHAPPROCESSDATA] = 'ChapProcessData';
1577 $EBMLidList[EBML_ID_CHAPPROCESSPRIVATE] = 'ChapProcessPrivate';
1578 $EBMLidList[EBML_ID_CHAPPROCESSTIME] = 'ChapProcessTime';
1579 $EBMLidList[EBML_ID_CHAPSTRING] = 'ChapString';
1580 $EBMLidList[EBML_ID_CHAPTERATOM] = 'ChapterAtom';
1581 $EBMLidList[EBML_ID_CHAPTERDISPLAY] = 'ChapterDisplay';
1582 $EBMLidList[EBML_ID_CHAPTERFLAGENABLED] = 'ChapterFlagEnabled';
1583 $EBMLidList[EBML_ID_CHAPTERFLAGHIDDEN] = 'ChapterFlagHidden';
1584 $EBMLidList[EBML_ID_CHAPTERPHYSICALEQUIV] = 'ChapterPhysicalEquiv';
1585 $EBMLidList[EBML_ID_CHAPTERS] = 'Chapters';
1586 $EBMLidList[EBML_ID_CHAPTERSEGMENTEDITIONUID] = 'ChapterSegmentEditionUID';
1587 $EBMLidList[EBML_ID_CHAPTERSEGMENTUID] = 'ChapterSegmentUID';
1588 $EBMLidList[EBML_ID_CHAPTERTIMEEND] = 'ChapterTimeEnd';
1589 $EBMLidList[EBML_ID_CHAPTERTIMESTART] = 'ChapterTimeStart';
1590 $EBMLidList[EBML_ID_CHAPTERTRACK] = 'ChapterTrack';
1591 $EBMLidList[EBML_ID_CHAPTERTRACKNUMBER] = 'ChapterTrackNumber';
1592 $EBMLidList[EBML_ID_CHAPTERTRANSLATE] = 'ChapterTranslate';
1593 $EBMLidList[EBML_ID_CHAPTERTRANSLATECODEC] = 'ChapterTranslateCodec';
1594 $EBMLidList[EBML_ID_CHAPTERTRANSLATEEDITIONUID] = 'ChapterTranslateEditionUID';
1595 $EBMLidList[EBML_ID_CHAPTERTRANSLATEID] = 'ChapterTranslateID';
1596 $EBMLidList[EBML_ID_CHAPTERUID] = 'ChapterUID';
1597 $EBMLidList[EBML_ID_CLUSTER] = 'Cluster';
1598 $EBMLidList[EBML_ID_CLUSTERBLOCK] = 'ClusterBlock';
1599 $EBMLidList[EBML_ID_CLUSTERBLOCKADDID] = 'ClusterBlockAddID';
1600 $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONAL] = 'ClusterBlockAdditional';
1601 $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONID] = 'ClusterBlockAdditionID';
1602 $EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONS] = 'ClusterBlockAdditions';
1603 $EBMLidList[EBML_ID_CLUSTERBLOCKDURATION] = 'ClusterBlockDuration';
1604 $EBMLidList[EBML_ID_CLUSTERBLOCKGROUP] = 'ClusterBlockGroup';
1605 $EBMLidList[EBML_ID_CLUSTERBLOCKMORE] = 'ClusterBlockMore';
1606 $EBMLidList[EBML_ID_CLUSTERBLOCKVIRTUAL] = 'ClusterBlockVirtual';
1607 $EBMLidList[EBML_ID_CLUSTERCODECSTATE] = 'ClusterCodecState';
1608 $EBMLidList[EBML_ID_CLUSTERDELAY] = 'ClusterDelay';
1609 $EBMLidList[EBML_ID_CLUSTERDURATION] = 'ClusterDuration';
1610 $EBMLidList[EBML_ID_CLUSTERENCRYPTEDBLOCK] = 'ClusterEncryptedBlock';
1611 $EBMLidList[EBML_ID_CLUSTERFRAMENUMBER] = 'ClusterFrameNumber';
1612 $EBMLidList[EBML_ID_CLUSTERLACENUMBER] = 'ClusterLaceNumber';
1613 $EBMLidList[EBML_ID_CLUSTERPOSITION] = 'ClusterPosition';
1614 $EBMLidList[EBML_ID_CLUSTERPREVSIZE] = 'ClusterPrevSize';
1615 $EBMLidList[EBML_ID_CLUSTERREFERENCEBLOCK] = 'ClusterReferenceBlock';
1616 $EBMLidList[EBML_ID_CLUSTERREFERENCEPRIORITY] = 'ClusterReferencePriority';
1617 $EBMLidList[EBML_ID_CLUSTERREFERENCEVIRTUAL] = 'ClusterReferenceVirtual';
1618 $EBMLidList[EBML_ID_CLUSTERSILENTTRACKNUMBER] = 'ClusterSilentTrackNumber';
1619 $EBMLidList[EBML_ID_CLUSTERSILENTTRACKS] = 'ClusterSilentTracks';
1620 $EBMLidList[EBML_ID_CLUSTERSIMPLEBLOCK] = 'ClusterSimpleBlock';
1621 $EBMLidList[EBML_ID_CLUSTERTIMECODE] = 'ClusterTimecode';
1622 $EBMLidList[EBML_ID_CLUSTERTIMESLICE] = 'ClusterTimeSlice';
1623 $EBMLidList[EBML_ID_CODECDECODEALL] = 'CodecDecodeAll';
1624 $EBMLidList[EBML_ID_CODECDOWNLOADURL] = 'CodecDownloadURL';
1625 $EBMLidList[EBML_ID_CODECID] = 'CodecID';
1626 $EBMLidList[EBML_ID_CODECINFOURL] = 'CodecInfoURL';
1627 $EBMLidList[EBML_ID_CODECNAME] = 'CodecName';
1628 $EBMLidList[EBML_ID_CODECPRIVATE] = 'CodecPrivate';
1629 $EBMLidList[EBML_ID_CODECSETTINGS] = 'CodecSettings';
1630 $EBMLidList[EBML_ID_COLOURSPACE] = 'ColourSpace';
1631 $EBMLidList[EBML_ID_CONTENTCOMPALGO] = 'ContentCompAlgo';
1632 $EBMLidList[EBML_ID_CONTENTCOMPRESSION] = 'ContentCompression';
1633 $EBMLidList[EBML_ID_CONTENTCOMPSETTINGS] = 'ContentCompSettings';
1634 $EBMLidList[EBML_ID_CONTENTENCALGO] = 'ContentEncAlgo';
1635 $EBMLidList[EBML_ID_CONTENTENCKEYID] = 'ContentEncKeyID';
1636 $EBMLidList[EBML_ID_CONTENTENCODING] = 'ContentEncoding';
1637 $EBMLidList[EBML_ID_CONTENTENCODINGORDER] = 'ContentEncodingOrder';
1638 $EBMLidList[EBML_ID_CONTENTENCODINGS] = 'ContentEncodings';
1639 $EBMLidList[EBML_ID_CONTENTENCODINGSCOPE] = 'ContentEncodingScope';
1640 $EBMLidList[EBML_ID_CONTENTENCODINGTYPE] = 'ContentEncodingType';
1641 $EBMLidList[EBML_ID_CONTENTENCRYPTION] = 'ContentEncryption';
1642 $EBMLidList[EBML_ID_CONTENTSIGALGO] = 'ContentSigAlgo';
1643 $EBMLidList[EBML_ID_CONTENTSIGHASHALGO] = 'ContentSigHashAlgo';
1644 $EBMLidList[EBML_ID_CONTENTSIGKEYID] = 'ContentSigKeyID';
1645 $EBMLidList[EBML_ID_CONTENTSIGNATURE] = 'ContentSignature';
1646 $EBMLidList[EBML_ID_CRC32] = 'CRC32';
1647 $EBMLidList[EBML_ID_CUEBLOCKNUMBER] = 'CueBlockNumber';
1648 $EBMLidList[EBML_ID_CUECLUSTERPOSITION] = 'CueClusterPosition';
1649 $EBMLidList[EBML_ID_CUECODECSTATE] = 'CueCodecState';
1650 $EBMLidList[EBML_ID_CUEPOINT] = 'CuePoint';
1651 $EBMLidList[EBML_ID_CUEREFCLUSTER] = 'CueRefCluster';
1652 $EBMLidList[EBML_ID_CUEREFCODECSTATE] = 'CueRefCodecState';
1653 $EBMLidList[EBML_ID_CUEREFERENCE] = 'CueReference';
1654 $EBMLidList[EBML_ID_CUEREFNUMBER] = 'CueRefNumber';
1655 $EBMLidList[EBML_ID_CUEREFTIME] = 'CueRefTime';
1656 $EBMLidList[EBML_ID_CUES] = 'Cues';
1657 $EBMLidList[EBML_ID_CUETIME] = 'CueTime';
1658 $EBMLidList[EBML_ID_CUETRACK] = 'CueTrack';
1659 $EBMLidList[EBML_ID_CUETRACKPOSITIONS] = 'CueTrackPositions';
1660 $EBMLidList[EBML_ID_DATEUTC] = 'DateUTC';
1661 $EBMLidList[EBML_ID_DEFAULTDURATION] = 'DefaultDuration';
1662 $EBMLidList[EBML_ID_DISPLAYHEIGHT] = 'DisplayHeight';
1663 $EBMLidList[EBML_ID_DISPLAYUNIT] = 'DisplayUnit';
1664 $EBMLidList[EBML_ID_DISPLAYWIDTH] = 'DisplayWidth';
1665 $EBMLidList[EBML_ID_DOCTYPE] = 'DocType';
1666 $EBMLidList[EBML_ID_DOCTYPEREADVERSION] = 'DocTypeReadVersion';
1667 $EBMLidList[EBML_ID_DOCTYPEVERSION] = 'DocTypeVersion';
1668 $EBMLidList[EBML_ID_DURATION] = 'Duration';
1669 $EBMLidList[EBML_ID_EBML] = 'EBML';
1670 $EBMLidList[EBML_ID_EBMLMAXIDLENGTH] = 'EBMLMaxIDLength';
1671 $EBMLidList[EBML_ID_EBMLMAXSIZELENGTH] = 'EBMLMaxSizeLength';
1672 $EBMLidList[EBML_ID_EBMLREADVERSION] = 'EBMLReadVersion';
1673 $EBMLidList[EBML_ID_EBMLVERSION] = 'EBMLVersion';
1674 $EBMLidList[EBML_ID_EDITIONENTRY] = 'EditionEntry';
1675 $EBMLidList[EBML_ID_EDITIONFLAGDEFAULT] = 'EditionFlagDefault';
1676 $EBMLidList[EBML_ID_EDITIONFLAGHIDDEN] = 'EditionFlagHidden';
1677 $EBMLidList[EBML_ID_EDITIONFLAGORDERED] = 'EditionFlagOrdered';
1678 $EBMLidList[EBML_ID_EDITIONUID] = 'EditionUID';
1679 $EBMLidList[EBML_ID_FILEDATA] = 'FileData';
1680 $EBMLidList[EBML_ID_FILEDESCRIPTION] = 'FileDescription';
1681 $EBMLidList[EBML_ID_FILEMIMETYPE] = 'FileMimeType';
1682 $EBMLidList[EBML_ID_FILENAME] = 'FileName';
1683 $EBMLidList[EBML_ID_FILEREFERRAL] = 'FileReferral';
1684 $EBMLidList[EBML_ID_FILEUID] = 'FileUID';
1685 $EBMLidList[EBML_ID_FLAGDEFAULT] = 'FlagDefault';
1686 $EBMLidList[EBML_ID_FLAGENABLED] = 'FlagEnabled';
1687 $EBMLidList[EBML_ID_FLAGFORCED] = 'FlagForced';
1688 $EBMLidList[EBML_ID_FLAGINTERLACED] = 'FlagInterlaced';
1689 $EBMLidList[EBML_ID_FLAGLACING] = 'FlagLacing';
1690 $EBMLidList[EBML_ID_GAMMAVALUE] = 'GammaValue';
1691 $EBMLidList[EBML_ID_INFO] = 'Info';
1692 $EBMLidList[EBML_ID_LANGUAGE] = 'Language';
1693 $EBMLidList[EBML_ID_MAXBLOCKADDITIONID] = 'MaxBlockAdditionID';
1694 $EBMLidList[EBML_ID_MAXCACHE] = 'MaxCache';
1695 $EBMLidList[EBML_ID_MINCACHE] = 'MinCache';
1696 $EBMLidList[EBML_ID_MUXINGAPP] = 'MuxingApp';
1697 $EBMLidList[EBML_ID_NAME] = 'Name';
1698 $EBMLidList[EBML_ID_NEXTFILENAME] = 'NextFilename';
1699 $EBMLidList[EBML_ID_NEXTUID] = 'NextUID';
1700 $EBMLidList[EBML_ID_OUTPUTSAMPLINGFREQUENCY] = 'OutputSamplingFrequency';
1701 $EBMLidList[EBML_ID_PIXELCROPBOTTOM] = 'PixelCropBottom';
1702 $EBMLidList[EBML_ID_PIXELCROPLEFT] = 'PixelCropLeft';
1703 $EBMLidList[EBML_ID_PIXELCROPRIGHT] = 'PixelCropRight';
1704 $EBMLidList[EBML_ID_PIXELCROPTOP] = 'PixelCropTop';
1705 $EBMLidList[EBML_ID_PIXELHEIGHT] = 'PixelHeight';
1706 $EBMLidList[EBML_ID_PIXELWIDTH] = 'PixelWidth';
1707 $EBMLidList[EBML_ID_PREVFILENAME] = 'PrevFilename';
1708 $EBMLidList[EBML_ID_PREVUID] = 'PrevUID';
1709 $EBMLidList[EBML_ID_SAMPLINGFREQUENCY] = 'SamplingFrequency';
1710 $EBMLidList[EBML_ID_SEEK] = 'Seek';
1711 $EBMLidList[EBML_ID_SEEKHEAD] = 'SeekHead';
1712 $EBMLidList[EBML_ID_SEEKID] = 'SeekID';
1713 $EBMLidList[EBML_ID_SEEKPOSITION] = 'SeekPosition';
1714 $EBMLidList[EBML_ID_SEGMENT] = 'Segment';
1715 $EBMLidList[EBML_ID_SEGMENTFAMILY] = 'SegmentFamily';
1716 $EBMLidList[EBML_ID_SEGMENTFILENAME] = 'SegmentFilename';
1717 $EBMLidList[EBML_ID_SEGMENTUID] = 'SegmentUID';
1718 $EBMLidList[EBML_ID_SIMPLETAG] = 'SimpleTag';
1719 $EBMLidList[EBML_ID_CLUSTERSLICES] = 'ClusterSlices';
1720 $EBMLidList[EBML_ID_STEREOMODE] = 'StereoMode';
1721 $EBMLidList[EBML_ID_OLDSTEREOMODE] = 'OldStereoMode';
1722 $EBMLidList[EBML_ID_TAG] = 'Tag';
1723 $EBMLidList[EBML_ID_TAGATTACHMENTUID] = 'TagAttachmentUID';
1724 $EBMLidList[EBML_ID_TAGBINARY] = 'TagBinary';
1725 $EBMLidList[EBML_ID_TAGCHAPTERUID] = 'TagChapterUID';
1726 $EBMLidList[EBML_ID_TAGDEFAULT] = 'TagDefault';
1727 $EBMLidList[EBML_ID_TAGEDITIONUID] = 'TagEditionUID';
1728 $EBMLidList[EBML_ID_TAGLANGUAGE] = 'TagLanguage';
1729 $EBMLidList[EBML_ID_TAGNAME] = 'TagName';
1730 $EBMLidList[EBML_ID_TAGTRACKUID] = 'TagTrackUID';
1731 $EBMLidList[EBML_ID_TAGS] = 'Tags';
1732 $EBMLidList[EBML_ID_TAGSTRING] = 'TagString';
1733 $EBMLidList[EBML_ID_TARGETS] = 'Targets';
1734 $EBMLidList[EBML_ID_TARGETTYPE] = 'TargetType';
1735 $EBMLidList[EBML_ID_TARGETTYPEVALUE] = 'TargetTypeValue';
1736 $EBMLidList[EBML_ID_TIMECODESCALE] = 'TimecodeScale';
1737 $EBMLidList[EBML_ID_TITLE] = 'Title';
1738 $EBMLidList[EBML_ID_TRACKENTRY] = 'TrackEntry';
1739 $EBMLidList[EBML_ID_TRACKNUMBER] = 'TrackNumber';
1740 $EBMLidList[EBML_ID_TRACKOFFSET] = 'TrackOffset';
1741 $EBMLidList[EBML_ID_TRACKOVERLAY] = 'TrackOverlay';
1742 $EBMLidList[EBML_ID_TRACKS] = 'Tracks';
1743 $EBMLidList[EBML_ID_TRACKTIMECODESCALE] = 'TrackTimecodeScale';
1744 $EBMLidList[EBML_ID_TRACKTRANSLATE] = 'TrackTranslate';
1745 $EBMLidList[EBML_ID_TRACKTRANSLATECODEC] = 'TrackTranslateCodec';
1746 $EBMLidList[EBML_ID_TRACKTRANSLATEEDITIONUID] = 'TrackTranslateEditionUID';
1747 $EBMLidList[EBML_ID_TRACKTRANSLATETRACKID] = 'TrackTranslateTrackID';
1748 $EBMLidList[EBML_ID_TRACKTYPE] = 'TrackType';
1749 $EBMLidList[EBML_ID_TRACKUID] = 'TrackUID';
1750 $EBMLidList[EBML_ID_VIDEO] = 'Video';
1751 $EBMLidList[EBML_ID_VOID] = 'Void';
1752 $EBMLidList[EBML_ID_WRITINGAPP] = 'WritingApp';
1753 }
1754
1755 return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value));
1756 }
const EBML_ID_EDITIONUID
const EBML_ID_DOCTYPEREADVERSION
const EBML_ID_EBMLREADVERSION
const EBML_ID_SEGMENTFILENAME
const EBML_ID_TRACKNUMBER
const EBML_ID_FILENAME
const EBML_ID_SAMPLINGFREQUENCY
const EBML_ID_CLUSTERDELAY
const EBML_ID_TAGSTRING
const EBML_ID_TRACKOVERLAY
const EBML_ID_OLDSTEREOMODE
const EBML_ID_FILEUID
const EBML_ID_CONTENTCOMPALGO
const EBML_ID_CLUSTERBLOCKADDITIONS
const EBML_ID_SEEKID
const EBML_ID_SIMPLETAG
const EBML_ID_EBMLMAXIDLENGTH
const EBML_ID_PIXELCROPLEFT
const EBML_ID_TAGEDITIONUID
const EBML_ID_CONTENTSIGNATURE
const EBML_ID_TRACKENTRY
const EBML_ID_DURATION
const EBML_ID_EDITIONFLAGDEFAULT
const EBML_ID_CONTENTCOMPRESSION
const EBML_ID_NEXTUID
const EBML_ID_COLOURSPACE
const EBML_ID_FLAGDEFAULT
const EBML_ID_SEGMENTUID
const EBML_ID_ATTACHEDFILE
const EBML_ID_ATTACHMENTS
const EBML_ID_CLUSTERSILENTTRACKS
const EBML_ID_DOCTYPEVERSION
const EBML_ID_CHAPTERFLAGENABLED
const EBML_ID_CLUSTERSIMPLEBLOCK
const EBML_ID_CUEREFTIME
const EBML_ID_CLUSTERBLOCKVIRTUAL
const EBML_ID_TAGBINARY
const EBML_ID_TRACKTYPE
const EBML_ID_TRACKOFFSET
const EBML_ID_TARGETTYPEVALUE
const EBML_ID_CLUSTERBLOCK
const EBML_ID_CLUSTERBLOCKADDITIONAL
const EBML_ID_CODECPRIVATE
const EBML_ID_TRACKTRANSLATE
const EBML_ID_CHANNELS
const EBML_ID_CHAPTERSEGMENTEDITIONUID
const EBML_ID_CLUSTERFRAMENUMBER
const EBML_ID_CLUSTERCODECSTATE
const EBML_ID_DISPLAYHEIGHT
const EBML_ID_CODECINFOURL
const EBML_ID_CHAPTERTIMESTART
const EBML_ID_CODECDECODEALL
const EBML_ID_CLUSTERENCRYPTEDBLOCK
const EBML_ID_WRITINGAPP
const EBML_ID_TRACKTRANSLATEEDITIONUID
const EBML_ID_CHAPTERSEGMENTUID
const EBML_ID_PIXELHEIGHT
const EBML_ID_CUEREFERENCE
const EBML_ID_FILEREFERRAL
const EBML_ID_CHAPPROCESSCODECID
const EBML_ID_CLUSTERTIMECODE
const EBML_ID_CONTENTENCODINGTYPE
const EBML_ID_CHAPTERTRANSLATECODEC
const EBML_ID_CUEBLOCKNUMBER
const EBML_ID_CUECLUSTERPOSITION
const EBML_ID_CLUSTERBLOCKGROUP
const EBML_ID_TAGLANGUAGE
const EBML_ID_EDITIONFLAGORDERED
const EBML_ID_SEGMENTFAMILY
const EBML_ID_GAMMAVALUE
const EBML_ID_CLUSTERPOSITION
const EBML_ID_CUETRACKPOSITIONS
const EBML_ID_CLUSTERDURATION
const EBML_ID_CLUSTERREFERENCEVIRTUAL
const EBML_ID_DATEUTC
const EBML_ID_CLUSTERSILENTTRACKNUMBER
const EBML_ID_CONTENTENCODING
const EBML_ID_CONTENTENCODINGS
const EBML_ID_CUETRACK
const EBML_ID_CHAPTERFLAGHIDDEN
const EBML_ID_CLUSTERBLOCKADDID
const EBML_ID_NEXTFILENAME
const EBML_ID_TRACKTIMECODESCALE
const EBML_ID_CLUSTERBLOCKDURATION
const EBML_ID_TAGATTACHMENTUID
const EBML_ID_DEFAULTDURATION
const EBML_ID_PIXELCROPBOTTOM
const EBML_ID_CUEREFCLUSTER
const EBML_ID_DISPLAYWIDTH
const EBML_ID_CHAPTERTRACKNUMBER
const EBML_ID_FLAGLACING
const EBML_ID_CLUSTERLACENUMBER
const EBML_ID_CHAPLANGUAGE
const EBML_ID_CLUSTERREFERENCEPRIORITY
const EBML_ID_TRACKTRANSLATETRACKID
const EBML_ID_CHAPPROCESSCOMMAND
const EBML_ID_MUXINGAPP
const EBML_ID_CHAPTERS
getID3() by James Heinrich info@getid3.org //
const EBML_ID_CHAPPROCESS
const EBML_ID_EBMLMAXSIZELENGTH
const EBML_ID_FILEDATA
const EBML_ID_CHAPTERPHYSICALEQUIV
const EBML_ID_CLUSTERPREVSIZE
const EBML_ID_CUECODECSTATE
const EBML_ID_TARGETTYPE
const EBML_ID_CONTENTCOMPSETTINGS
const EBML_ID_PREVFILENAME
const EBML_ID_CONTENTSIGKEYID
const EBML_ID_CHAPPROCESSDATA
const EBML_ID_CHAPSTRING
const EBML_ID_TAGCHAPTERUID
const EBML_ID_CODECDOWNLOADURL
const EBML_ID_MAXBLOCKADDITIONID
const EBML_ID_CONTENTENCALGO
const EBML_ID_CHAPPROCESSTIME
const EBML_ID_SEGMENT
const EBML_ID_TAGNAME
const EBML_ID_FILEMIMETYPE
const EBML_ID_CLUSTERREFERENCEBLOCK
const EBML_ID_EBMLVERSION
const EBML_ID_PIXELCROPRIGHT
const EBML_ID_EDITIONFLAGHIDDEN
const EBML_ID_PREVUID
const EBML_ID_CONTENTENCKEYID
const EBML_ID_DOCTYPE
const EBML_ID_CHAPTERATOM
const EBML_ID_TAGDEFAULT
const EBML_ID_PIXELWIDTH
const EBML_ID_CLUSTERBLOCKMORE
const EBML_ID_ASPECTRATIOTYPE
const EBML_ID_TRACKS
const EBML_ID_PIXELCROPTOP
const EBML_ID_CHAPPROCESSPRIVATE
const EBML_ID_FLAGENABLED
const EBML_ID_MAXCACHE
const EBML_ID_TRACKUID
const EBML_ID_CONTENTENCODINGSCOPE
const EBML_ID_OUTPUTSAMPLINGFREQUENCY
const EBML_ID_CONTENTENCRYPTION
const EBML_ID_CUEREFNUMBER
const EBML_ID_CHANNELPOSITIONS
const EBML_ID_EDITIONENTRY
const EBML_ID_TAGTRACKUID
const EBML_ID_CHAPCOUNTRY
const EBML_ID_TRACKTRANSLATECODEC
const EBML_ID_CLUSTERSLICES
const EBML_ID_CODECSETTINGS
const EBML_ID_CONTENTSIGHASHALGO
const EBML_ID_BITDEPTH
const EBML_ID_MINCACHE
const EBML_ID_STEREOMODE
const EBML_ID_TIMECODESCALE
const EBML_ID_CHAPTERTRANSLATEID
const EBML_ID_LANGUAGE
const EBML_ID_CHAPTERTRANSLATE
const EBML_ID_CHAPTERTRANSLATEEDITIONUID
const EBML_ID_CLUSTER
const EBML_ID_DISPLAYUNIT
const EBML_ID_CUEPOINT
const EBML_ID_CHAPTERTIMEEND
const EBML_ID_CHAPTERDISPLAY
const EBML_ID_FLAGINTERLACED
const EBML_ID_FILEDESCRIPTION
const EBML_ID_FLAGFORCED
const EBML_ID_ATTACHMENTLINK
const EBML_ID_CLUSTERTIMESLICE
const EBML_ID_CODECNAME
const EBML_ID_CONTENTENCODINGORDER
const EBML_ID_CONTENTSIGALGO
const EBML_ID_CHAPTERTRACK
const EBML_ID_CLUSTERBLOCKADDITIONID
const EBML_ID_SEEKHEAD
const EBML_ID_CUEREFCODECSTATE
const EBML_ID_SEEKPOSITION
const EBML_ID_CHAPTERUID

References EBML_ID_ASPECTRATIOTYPE, EBML_ID_ATTACHEDFILE, EBML_ID_ATTACHMENTLINK, EBML_ID_ATTACHMENTS, EBML_ID_AUDIO, EBML_ID_BITDEPTH, EBML_ID_CHANNELPOSITIONS, EBML_ID_CHANNELS, EBML_ID_CHAPCOUNTRY, EBML_ID_CHAPLANGUAGE, EBML_ID_CHAPPROCESS, EBML_ID_CHAPPROCESSCODECID, EBML_ID_CHAPPROCESSCOMMAND, EBML_ID_CHAPPROCESSDATA, EBML_ID_CHAPPROCESSPRIVATE, EBML_ID_CHAPPROCESSTIME, EBML_ID_CHAPSTRING, EBML_ID_CHAPTERATOM, EBML_ID_CHAPTERDISPLAY, EBML_ID_CHAPTERFLAGENABLED, EBML_ID_CHAPTERFLAGHIDDEN, EBML_ID_CHAPTERPHYSICALEQUIV, EBML_ID_CHAPTERS, EBML_ID_CHAPTERSEGMENTEDITIONUID, EBML_ID_CHAPTERSEGMENTUID, EBML_ID_CHAPTERTIMEEND, EBML_ID_CHAPTERTIMESTART, EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERTRACKNUMBER, EBML_ID_CHAPTERTRANSLATE, EBML_ID_CHAPTERTRANSLATECODEC, EBML_ID_CHAPTERTRANSLATEEDITIONUID, EBML_ID_CHAPTERTRANSLATEID, EBML_ID_CHAPTERUID, EBML_ID_CLUSTER, EBML_ID_CLUSTERBLOCK, EBML_ID_CLUSTERBLOCKADDID, EBML_ID_CLUSTERBLOCKADDITIONAL, EBML_ID_CLUSTERBLOCKADDITIONID, EBML_ID_CLUSTERBLOCKADDITIONS, EBML_ID_CLUSTERBLOCKDURATION, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERBLOCKMORE, EBML_ID_CLUSTERBLOCKVIRTUAL, EBML_ID_CLUSTERCODECSTATE, EBML_ID_CLUSTERDELAY, EBML_ID_CLUSTERDURATION, EBML_ID_CLUSTERENCRYPTEDBLOCK, EBML_ID_CLUSTERFRAMENUMBER, EBML_ID_CLUSTERLACENUMBER, EBML_ID_CLUSTERPOSITION, EBML_ID_CLUSTERPREVSIZE, EBML_ID_CLUSTERREFERENCEBLOCK, EBML_ID_CLUSTERREFERENCEPRIORITY, EBML_ID_CLUSTERREFERENCEVIRTUAL, EBML_ID_CLUSTERSILENTTRACKNUMBER, EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERSIMPLEBLOCK, EBML_ID_CLUSTERSLICES, EBML_ID_CLUSTERTIMECODE, EBML_ID_CLUSTERTIMESLICE, EBML_ID_CODECDECODEALL, EBML_ID_CODECDOWNLOADURL, EBML_ID_CODECID, EBML_ID_CODECINFOURL, EBML_ID_CODECNAME, EBML_ID_CODECPRIVATE, EBML_ID_CODECSETTINGS, EBML_ID_COLOURSPACE, EBML_ID_CONTENTCOMPALGO, EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTCOMPSETTINGS, EBML_ID_CONTENTENCALGO, EBML_ID_CONTENTENCKEYID, EBML_ID_CONTENTENCODING, EBML_ID_CONTENTENCODINGORDER, EBML_ID_CONTENTENCODINGS, EBML_ID_CONTENTENCODINGSCOPE, EBML_ID_CONTENTENCODINGTYPE, EBML_ID_CONTENTENCRYPTION, EBML_ID_CONTENTSIGALGO, EBML_ID_CONTENTSIGHASHALGO, EBML_ID_CONTENTSIGKEYID, EBML_ID_CONTENTSIGNATURE, EBML_ID_CRC32, EBML_ID_CUEBLOCKNUMBER, EBML_ID_CUECLUSTERPOSITION, EBML_ID_CUECODECSTATE, EBML_ID_CUEPOINT, EBML_ID_CUEREFCLUSTER, EBML_ID_CUEREFCODECSTATE, EBML_ID_CUEREFERENCE, EBML_ID_CUEREFNUMBER, EBML_ID_CUEREFTIME, EBML_ID_CUES, EBML_ID_CUETIME, EBML_ID_CUETRACK, EBML_ID_CUETRACKPOSITIONS, EBML_ID_DATEUTC, EBML_ID_DEFAULTDURATION, EBML_ID_DISPLAYHEIGHT, EBML_ID_DISPLAYUNIT, EBML_ID_DISPLAYWIDTH, EBML_ID_DOCTYPE, EBML_ID_DOCTYPEREADVERSION, EBML_ID_DOCTYPEVERSION, EBML_ID_DURATION, EBML_ID_EBML, EBML_ID_EBMLMAXIDLENGTH, EBML_ID_EBMLMAXSIZELENGTH, EBML_ID_EBMLREADVERSION, EBML_ID_EBMLVERSION, EBML_ID_EDITIONENTRY, EBML_ID_EDITIONFLAGDEFAULT, EBML_ID_EDITIONFLAGHIDDEN, EBML_ID_EDITIONFLAGORDERED, EBML_ID_EDITIONUID, EBML_ID_FILEDATA, EBML_ID_FILEDESCRIPTION, EBML_ID_FILEMIMETYPE, EBML_ID_FILENAME, EBML_ID_FILEREFERRAL, EBML_ID_FILEUID, EBML_ID_FLAGDEFAULT, EBML_ID_FLAGENABLED, EBML_ID_FLAGFORCED, EBML_ID_FLAGINTERLACED, EBML_ID_FLAGLACING, EBML_ID_GAMMAVALUE, EBML_ID_INFO, EBML_ID_LANGUAGE, EBML_ID_MAXBLOCKADDITIONID, EBML_ID_MAXCACHE, EBML_ID_MINCACHE, EBML_ID_MUXINGAPP, EBML_ID_NAME, EBML_ID_NEXTFILENAME, EBML_ID_NEXTUID, EBML_ID_OLDSTEREOMODE, EBML_ID_OUTPUTSAMPLINGFREQUENCY, EBML_ID_PIXELCROPBOTTOM, EBML_ID_PIXELCROPLEFT, EBML_ID_PIXELCROPRIGHT, EBML_ID_PIXELCROPTOP, EBML_ID_PIXELHEIGHT, EBML_ID_PIXELWIDTH, EBML_ID_PREVFILENAME, EBML_ID_PREVUID, EBML_ID_SAMPLINGFREQUENCY, EBML_ID_SEEK, EBML_ID_SEEKHEAD, EBML_ID_SEEKID, EBML_ID_SEEKPOSITION, EBML_ID_SEGMENT, EBML_ID_SEGMENTFAMILY, EBML_ID_SEGMENTFILENAME, EBML_ID_SEGMENTUID, EBML_ID_SIMPLETAG, EBML_ID_STEREOMODE, EBML_ID_TAG, EBML_ID_TAGATTACHMENTUID, EBML_ID_TAGBINARY, EBML_ID_TAGCHAPTERUID, EBML_ID_TAGDEFAULT, EBML_ID_TAGEDITIONUID, EBML_ID_TAGLANGUAGE, EBML_ID_TAGNAME, EBML_ID_TAGS, EBML_ID_TAGSTRING, EBML_ID_TAGTRACKUID, EBML_ID_TARGETS, EBML_ID_TARGETTYPE, EBML_ID_TARGETTYPEVALUE, EBML_ID_TIMECODESCALE, EBML_ID_TITLE, EBML_ID_TRACKENTRY, EBML_ID_TRACKNUMBER, EBML_ID_TRACKOFFSET, EBML_ID_TRACKOVERLAY, EBML_ID_TRACKS, EBML_ID_TRACKTIMECODESCALE, EBML_ID_TRACKTRANSLATE, EBML_ID_TRACKTRANSLATECODEC, EBML_ID_TRACKTRANSLATEEDITIONUID, EBML_ID_TRACKTRANSLATETRACKID, EBML_ID_TRACKTYPE, EBML_ID_TRACKUID, EBML_ID_VIDEO, EBML_ID_VOID, and EBML_ID_WRITINGAPP.

Referenced by getEBMLelement(), and parseEBML().

+ Here is the caller graph for this function:

◆ EnsureBufferHasEnoughData()

getid3_matroska::EnsureBufferHasEnoughData (   $min_data = 1024)
private

Definition at line 1231 of file module.audio-video.matroska.php.

1231 {
1232 if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
1233 $read_bytes = max($min_data, $this->getid3->fread_buffer_size());
1234
1235 try {
1236 $this->fseek($this->current_offset);
1237 $this->EBMLbuffer_offset = $this->current_offset;
1238 $this->EBMLbuffer = $this->fread($read_bytes);
1239 $this->EBMLbuffer_length = strlen($this->EBMLbuffer);
1240 } catch (getid3_exception $e) {
1241 $this->warning('EBML parser: '.$e->getMessage());
1242 return false;
1243 }
1244
1245 if ($this->EBMLbuffer_length == 0 && $this->feof()) {
1246 return $this->error('EBML parser: ran out of file at offset '.$this->current_offset);
1247 }
1248 }
1249 return true;
1250 }
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1711
fread($bytes)
Definition: getid3.php:1683

References $current_offset, getid3_handler\error(), getid3_handler\feof(), getid3_handler\fread(), getid3_handler\fseek(), and getid3_handler\warning().

Referenced by getEBMLelement(), and readEBMLelementData().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ExtractCommentsSimpleTag()

getid3_matroska::ExtractCommentsSimpleTag (   $SimpleTagArray)
private

Definition at line 1341 of file module.audio-video.matroska.php.

1341 {
1342 if (!empty($SimpleTagArray['SimpleTag'])) {
1343 foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) {
1344 if (!empty($SimpleTagData['TagName']) && !empty($SimpleTagData['TagString'])) {
1345 $this->getid3->info['matroska']['comments'][strtolower($SimpleTagData['TagName'])][] = $SimpleTagData['TagString'];
1346 }
1347 if (!empty($SimpleTagData['SimpleTag'])) {
1348 $this->ExtractCommentsSimpleTag($SimpleTagData);
1349 }
1350 }
1351 }
1352
1353 return true;
1354 }

References ExtractCommentsSimpleTag().

Referenced by Analyze(), and ExtractCommentsSimpleTag().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDefaultStreamInfo()

static getid3_matroska::getDefaultStreamInfo (   $streams)
staticprivate

Definition at line 1769 of file module.audio-video.matroska.php.

1770 {
1771 foreach (array_reverse($streams) as $stream) {
1772 if ($stream['default']) {
1773 break;
1774 }
1775 }
1776
1777 $unset = array('default', 'name');
1778 foreach ($unset as $u) {
1779 if (isset($stream[$u])) {
1780 unset($stream[$u]);
1781 }
1782 }
1783
1784 $info = $stream;
1785 $info['streams'] = $streams;
1786
1787 return $info;
1788 }
$stream
PHP stream implementation.

References $info, and GuzzleHttp\Psr7\$stream.

Referenced by Analyze().

+ Here is the caller graph for this function:

◆ getEBMLelement()

getid3_matroska::getEBMLelement ( $element,
  $parent_end,
  $get_data = false 
)
private

Definition at line 1293 of file module.audio-video.matroska.php.

1293 {
1294 if ($this->current_offset >= $parent_end) {
1295 return false;
1296 }
1297
1298 if (!$this->EnsureBufferHasEnoughData()) {
1299 $this->current_offset = PHP_INT_MAX; // do not exit parser right now, allow to finish current loop to gather maximum information
1300 return false;
1301 }
1302
1303 $element = array();
1304
1305 // set offset
1306 $element['offset'] = $this->current_offset;
1307
1308 // get ID
1309 $element['id'] = $this->readEBMLint();
1310
1311 // get name
1312 $element['id_name'] = self::EBMLidName($element['id']);
1313
1314 // get length
1315 $element['length'] = $this->readEBMLint();
1316
1317 // get end offset
1318 $element['end'] = $this->current_offset + $element['length'];
1319
1320 // get raw data
1321 $dont_parse = (in_array($element['id'], $this->unuseful_elements) || $element['id_name'] == dechex($element['id']));
1322 if (($get_data === true || (is_array($get_data) && !in_array($element['id'], $get_data))) && !$dont_parse) {
1323 $element['data'] = $this->readEBMLelementData($element['length'], $element);
1324 }
1325
1326 return true;
1327 }
readEBMLelementData($length, $check_buffer=false)
EnsureBufferHasEnoughData($min_data=1024)

References $current_offset, EBMLidName(), EnsureBufferHasEnoughData(), readEBMLelementData(), and readEBMLint().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleEMBLClusterBlock()

getid3_matroska::HandleEMBLClusterBlock (   $element,
  $block_type,
$info 
)
private

Definition at line 1386 of file module.audio-video.matroska.php.

1386 {
1387 // http://www.matroska.org/technical/specs/index.html#block_structure
1388 // http://www.matroska.org/technical/specs/index.html#simpleblock_structure
1389
1390 $block_data = array();
1391 $block_data['tracknumber'] = $this->readEBMLint();
1392 $block_data['timecode'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(2), false, true);
1393 $block_data['flags_raw'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1));
1394
1395 if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1396 $block_data['flags']['keyframe'] = (($block_data['flags_raw'] & 0x80) >> 7);
1397 //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0x70) >> 4);
1398 }
1399 else {
1400 //$block_data['flags']['reserved1'] = (($block_data['flags_raw'] & 0xF0) >> 4);
1401 }
1402 $block_data['flags']['invisible'] = (bool)(($block_data['flags_raw'] & 0x08) >> 3);
1403 $block_data['flags']['lacing'] = (($block_data['flags_raw'] & 0x06) >> 1); // 00=no lacing; 01=Xiph lacing; 11=EBML lacing; 10=fixed-size lacing
1404 if ($block_type == EBML_ID_CLUSTERSIMPLEBLOCK) {
1405 $block_data['flags']['discardable'] = (($block_data['flags_raw'] & 0x01));
1406 }
1407 else {
1408 //$block_data['flags']['reserved2'] = (($block_data['flags_raw'] & 0x01) >> 0);
1409 }
1410 $block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);
1411
1412 // Lace (when lacing bit is set)
1413 if ($block_data['flags']['lacing'] > 0) {
1414 $block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
1415 if ($block_data['flags']['lacing'] != 0x02) {
1416 for ($i = 1; $i < $block_data['lace_frames']; $i ++) { // Lace-coded size of each frame of the lace, except for the last one (multiple uint8). *This is not used with Fixed-size lacing as it is calculated automatically from (total size of lace) / (number of frames in lace).
1417 if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing
1418 $block_data['lace_frames_size'][$i] = $this->readEBMLint(); // TODO: read size correctly, calc size for the last frame. For now offsets are deteminded OK with readEBMLint() and that's the most important thing.
1419 }
1420 else { // Xiph lacing
1421 $block_data['lace_frames_size'][$i] = 0;
1422 do {
1424 $block_data['lace_frames_size'][$i] += $size;
1425 }
1426 while ($size == 255);
1427 }
1428 }
1429 if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly
1430 $block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']);
1431 }
1432 }
1433 }
1434
1435 if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) {
1436 $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset;
1437 $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset;
1438 //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0;
1439 }
1440 //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'];
1441 //$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['duration'] = $block_data['timecode'] * ((isset($info['matroska']['info'][0]['TimecodeScale']) ? $info['matroska']['info'][0]['TimecodeScale'] : 1000000) / 1000000000);
1442
1443 // set offset manually
1444 $this->current_offset = $element['end'];
1445
1446 return $block_data;
1447 }
$size
Definition: RandomTest.php:84
static BlockLacingType($lacingtype)

References $current_offset, $i, $info, $size, getid3_lib\BigEndian2Int(), BlockLacingType(), EBML_ID_CLUSTERSIMPLEBLOCK, readEBMLelementData(), and readEBMLint().

Referenced by parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleEMBLSimpleTag()

getid3_matroska::HandleEMBLSimpleTag (   $parent_end)
private

Definition at line 1356 of file module.audio-video.matroska.php.

1356 {
1357 $simpletag_entry = array();
1358
1359 while ($this->getEBMLelement($element, $parent_end, array(EBML_ID_SIMPLETAG))) {
1360 switch ($element['id']) {
1361
1362 case EBML_ID_TAGNAME:
1364 case EBML_ID_TAGSTRING:
1365 case EBML_ID_TAGBINARY:
1366 $simpletag_entry[$element['id_name']] = $element['data'];
1367 break;
1368
1369 case EBML_ID_SIMPLETAG:
1370 $simpletag_entry[$element['id_name']][] = $this->HandleEMBLSimpleTag($element['end']);
1371 break;
1372
1373 case EBML_ID_TAGDEFAULT:
1374 $simpletag_entry[$element['id_name']] = (bool)getid3_lib::BigEndian2Int($element['data']);
1375 break;
1376
1377 default:
1378 $this->unhandledElement('tag.simpletag', __LINE__, $element);
1379 break;
1380 }
1381 }
1382
1383 return $simpletag_entry;
1384 }
getEBMLelement(&$element, $parent_end, $get_data=false)
unhandledElement($type, $line, $element)

References getid3_lib\BigEndian2Int(), EBML_ID_SIMPLETAG, EBML_ID_TAGBINARY, EBML_ID_TAGDEFAULT, EBML_ID_TAGLANGUAGE, EBML_ID_TAGNAME, EBML_ID_TAGSTRING, getEBMLelement(), HandleEMBLSimpleTag(), and unhandledElement().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parseEBML()

getid3_matroska::parseEBML ( $info)
private

Definition at line 499 of file module.audio-video.matroska.php.

499 {
500 // http://www.matroska.org/technical/specs/index.html#EBMLBasics
501 $this->current_offset = $info['avdataoffset'];
502
503 while ($this->getEBMLelement($top_element, $info['avdataend'])) {
504 switch ($top_element['id']) {
505
506 case EBML_ID_EBML:
507 $info['matroska']['header']['offset'] = $top_element['offset'];
508 $info['matroska']['header']['length'] = $top_element['length'];
509
510 while ($this->getEBMLelement($element_data, $top_element['end'], true)) {
511 switch ($element_data['id']) {
512
519 $element_data['data'] = getid3_lib::BigEndian2Int($element_data['data']);
520 break;
521
522 case EBML_ID_DOCTYPE:
523 $element_data['data'] = getid3_lib::trimNullByte($element_data['data']);
524 $info['matroska']['doctype'] = $element_data['data'];
525 $info['fileformat'] = $element_data['data'];
526 break;
527
528 default:
529 $this->unhandledElement('header', __LINE__, $element_data);
530 break;
531 }
532
533 unset($element_data['offset'], $element_data['end']);
534 $info['matroska']['header']['elements'][] = $element_data;
535 }
536 break;
537
538 case EBML_ID_SEGMENT:
539 $info['matroska']['segment'][0]['offset'] = $top_element['offset'];
540 $info['matroska']['segment'][0]['length'] = $top_element['length'];
541
542 while ($this->getEBMLelement($element_data, $top_element['end'])) {
543 if ($element_data['id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
544 $info['matroska']['segments'][] = $element_data;
545 }
546 switch ($element_data['id']) {
547
548 case EBML_ID_SEEKHEAD: // Contains the position of other level 1 elements.
549
550 while ($this->getEBMLelement($seek_entry, $element_data['end'])) {
551 switch ($seek_entry['id']) {
552
553 case EBML_ID_SEEK: // Contains a single seek entry to an EBML element
554 while ($this->getEBMLelement($sub_seek_entry, $seek_entry['end'], true)) {
555
556 switch ($sub_seek_entry['id']) {
557
558 case EBML_ID_SEEKID:
559 $seek_entry['target_id'] = self::EBML2Int($sub_seek_entry['data']);
560 $seek_entry['target_name'] = self::EBMLidName($seek_entry['target_id']);
561 break;
562
564 $seek_entry['target_offset'] = $element_data['offset'] + getid3_lib::BigEndian2Int($sub_seek_entry['data']);
565 break;
566
567 default:
568 $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); }
569 break;
570 }
571 if (!isset($seek_entry['target_id'])) {
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
576 $info['matroska']['seek'][] = $seek_entry;
577 }
578 break;
579
580 default:
581 $this->unhandledElement('seekhead', __LINE__, $seek_entry);
582 break;
583 }
584 }
585 break;
586
587 case EBML_ID_TRACKS: // A top-level block of information with many tracks described.
588 $info['matroska']['tracks'] = $element_data;
589
590 while ($this->getEBMLelement($track_entry, $element_data['end'])) {
591 switch ($track_entry['id']) {
592
593 case EBML_ID_TRACKENTRY: //subelements: Describes a track with all elements.
594
595 while ($this->getEBMLelement($subelement, $track_entry['end'], array(EBML_ID_VIDEO, EBML_ID_AUDIO, EBML_ID_CONTENTENCODINGS, EBML_ID_CODECPRIVATE))) {
596 switch ($subelement['id']) {
597
599 case EBML_ID_TRACKUID:
601 case EBML_ID_MINCACHE:
602 case EBML_ID_MAXCACHE:
604 case EBML_ID_DEFAULTDURATION: // nanoseconds per frame
605 $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
606 break;
607
609 $track_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
610 break;
611
612 case EBML_ID_CODECID:
613 case EBML_ID_LANGUAGE:
614 case EBML_ID_NAME:
616 $track_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
617 break;
618
620 $track_entry[$subelement['id_name']] = $this->readEBMLelementData($subelement['length'], true);
621 break;
622
628 $track_entry[$subelement['id_name']] = (bool) getid3_lib::BigEndian2Int($subelement['data']);
629 break;
630
631 case EBML_ID_VIDEO:
632
633 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
634 switch ($sub_subelement['id']) {
635
648 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
649 break;
650
652 $track_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
653 break;
654
656 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
657 break;
658
660 $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
661 break;
662
663 default:
664 $this->unhandledElement('track.video', __LINE__, $sub_subelement);
665 break;
666 }
667 }
668 break;
669
670 case EBML_ID_AUDIO:
671
672 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
673 switch ($sub_subelement['id']) {
674
675 case EBML_ID_CHANNELS:
676 case EBML_ID_BITDEPTH:
677 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
678 break;
679
682 $track_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Float($sub_subelement['data']);
683 break;
684
686 $track_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
687 break;
688
689 default:
690 $this->unhandledElement('track.audio', __LINE__, $sub_subelement);
691 break;
692 }
693 }
694 break;
695
697
698 while ($this->getEBMLelement($sub_subelement, $subelement['end'])) {
699 switch ($sub_subelement['id']) {
700
702
703 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTENCRYPTION))) {
704 switch ($sub_sub_subelement['id']) {
705
709 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
710 break;
711
713
714 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
715 switch ($sub_sub_sub_subelement['id']) {
716
718 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
719 break;
720
722 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
723 break;
724
725 default:
726 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
727 break;
728 }
729 }
730 break;
731
733
734 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
735 switch ($sub_sub_sub_subelement['id']) {
736
740 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
741 break;
742
746 $track_entry[$sub_subelement['id_name']][$sub_sub_subelement['id_name']][$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
747 break;
748
749 default:
750 $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
751 break;
752 }
753 }
754 break;
755
756 default:
757 $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement);
758 break;
759 }
760 }
761 break;
762
763 default:
764 $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement);
765 break;
766 }
767 }
768 break;
769
770 default:
771 $this->unhandledElement('track', __LINE__, $subelement);
772 break;
773 }
774 }
775
776 $info['matroska']['tracks']['tracks'][] = $track_entry;
777 break;
778
779 default:
780 $this->unhandledElement('tracks', __LINE__, $track_entry);
781 break;
782 }
783 }
784 break;
785
786 case EBML_ID_INFO: // Contains miscellaneous general information and statistics on the file.
787 $info_entry = array();
788
789 while ($this->getEBMLelement($subelement, $element_data['end'], true)) {
790 switch ($subelement['id']) {
791
793 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
794 break;
795
796 case EBML_ID_DURATION:
797 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Float($subelement['data']);
798 break;
799
800 case EBML_ID_DATEUTC:
801 $info_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
802 $info_entry[$subelement['id_name'].'_unix'] = self::EBMLdate2unix($info_entry[$subelement['id_name']]);
803 break;
804
806 case EBML_ID_PREVUID:
807 case EBML_ID_NEXTUID:
808 $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
809 break;
810
812 $info_entry[$subelement['id_name']][] = getid3_lib::trimNullByte($subelement['data']);
813 break;
814
818 case EBML_ID_TITLE:
821 $info_entry[$subelement['id_name']] = getid3_lib::trimNullByte($subelement['data']);
822 $info['matroska']['comments'][strtolower($subelement['id_name'])][] = $info_entry[$subelement['id_name']];
823 break;
824
826 $chaptertranslate_entry = array();
827
828 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
829 switch ($sub_subelement['id']) {
830
832 $chaptertranslate_entry[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data']);
833 break;
834
836 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
837 break;
838
840 $chaptertranslate_entry[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
841 break;
842
843 default:
844 $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement);
845 break;
846 }
847 }
848 $info_entry[$subelement['id_name']] = $chaptertranslate_entry;
849 break;
850
851 default:
852 $this->unhandledElement('info', __LINE__, $subelement);
853 break;
854 }
855 }
856 $info['matroska']['info'][] = $info_entry;
857 break;
858
859 case EBML_ID_CUES: // A top-level element to speed seeking access. All entries are local to the segment. Should be mandatory for non "live" streams.
860 if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
861 $this->current_offset = $element_data['end'];
862 break;
863 }
864 $cues_entry = array();
865
866 while ($this->getEBMLelement($subelement, $element_data['end'])) {
867 switch ($subelement['id']) {
868
869 case EBML_ID_CUEPOINT:
870 $cuepoint_entry = array();
871
872 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CUETRACKPOSITIONS))) {
873 switch ($sub_subelement['id']) {
874
876 $cuetrackpositions_entry = array();
877
878 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
879 switch ($sub_sub_subelement['id']) {
880
881 case EBML_ID_CUETRACK:
885 $cuetrackpositions_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
886 break;
887
888 default:
889 $this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement);
890 break;
891 }
892 }
893 $cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry;
894 break;
895
896 case EBML_ID_CUETIME:
897 $cuepoint_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
898 break;
899
900 default:
901 $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement);
902 break;
903 }
904 }
905 $cues_entry[] = $cuepoint_entry;
906 break;
907
908 default:
909 $this->unhandledElement('cues', __LINE__, $subelement);
910 break;
911 }
912 }
913 $info['matroska']['cues'] = $cues_entry;
914 break;
915
916 case EBML_ID_TAGS: // Element containing elements specific to Tracks/Chapters.
917 $tags_entry = array();
918
919 while ($this->getEBMLelement($subelement, $element_data['end'], false)) {
920 switch ($subelement['id']) {
921
922 case EBML_ID_TAG:
923 $tag_entry = array();
924
925 while ($this->getEBMLelement($sub_subelement, $subelement['end'], false)) {
926 switch ($sub_subelement['id']) {
927
928 case EBML_ID_TARGETS:
929 $targets_entry = array();
930
931 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], true)) {
932 switch ($sub_sub_subelement['id']) {
933
935 $targets_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
936 $targets_entry[strtolower($sub_sub_subelement['id_name']).'_long'] = self::TargetTypeValue($targets_entry[$sub_sub_subelement['id_name']]);
937 break;
938
940 $targets_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
941 break;
942
947 $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
948 break;
949
950 default:
951 $this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement);
952 break;
953 }
954 }
955 $tag_entry[$sub_subelement['id_name']] = $targets_entry;
956 break;
957
959 $tag_entry[$sub_subelement['id_name']][] = $this->HandleEMBLSimpleTag($sub_subelement['end']);
960 break;
961
962 default:
963 $this->unhandledElement('tags.tag', __LINE__, $sub_subelement);
964 break;
965 }
966 }
967 $tags_entry[] = $tag_entry;
968 break;
969
970 default:
971 $this->unhandledElement('tags', __LINE__, $subelement);
972 break;
973 }
974 }
975 $info['matroska']['tags'] = $tags_entry;
976 break;
977
978 case EBML_ID_ATTACHMENTS: // Contain attached files.
979
980 while ($this->getEBMLelement($subelement, $element_data['end'])) {
981 switch ($subelement['id']) {
982
984 $attachedfile_entry = array();
985
986 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_FILEDATA))) {
987 switch ($sub_subelement['id']) {
988
990 case EBML_ID_FILENAME:
992 $attachedfile_entry[$sub_subelement['id_name']] = $sub_subelement['data'];
993 break;
994
995 case EBML_ID_FILEDATA:
996 $attachedfile_entry['data_offset'] = $this->current_offset;
997 $attachedfile_entry['data_length'] = $sub_subelement['length'];
998
999 $attachedfile_entry[$sub_subelement['id_name']] = $this->saveAttachment(
1000 $attachedfile_entry['FileName'],
1001 $attachedfile_entry['data_offset'],
1002 $attachedfile_entry['data_length']);
1003
1004 $this->current_offset = $sub_subelement['end'];
1005 break;
1006
1007 case EBML_ID_FILEUID:
1008 $attachedfile_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1009 break;
1010
1011 default:
1012 $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement);
1013 break;
1014 }
1015 }
1016 $info['matroska']['attachments'][] = $attachedfile_entry;
1017 break;
1018
1019 default:
1020 $this->unhandledElement('attachments', __LINE__, $subelement);
1021 break;
1022 }
1023 }
1024 break;
1025
1026 case EBML_ID_CHAPTERS:
1027
1028 while ($this->getEBMLelement($subelement, $element_data['end'])) {
1029 switch ($subelement['id']) {
1030
1032 $editionentry_entry = array();
1033
1034 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CHAPTERATOM))) {
1035 switch ($sub_subelement['id']) {
1036
1037 case EBML_ID_EDITIONUID:
1038 $editionentry_entry[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1039 break;
1040
1044 $editionentry_entry[$sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_subelement['data']);
1045 break;
1046
1048 $chapteratom_entry = array();
1049
1050 while ($this->getEBMLelement($sub_sub_subelement, $sub_subelement['end'], array(EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERDISPLAY))) {
1051 switch ($sub_sub_subelement['id']) {
1052
1055 $chapteratom_entry[$sub_sub_subelement['id_name']] = $sub_sub_subelement['data'];
1056 break;
1057
1060 $chapteratom_entry[$sub_sub_subelement['id_name']] = (bool)getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1061 break;
1062
1063 case EBML_ID_CHAPTERUID:
1066 $chapteratom_entry[$sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
1067 break;
1068
1070 $chaptertrack_entry = array();
1071
1072 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1073 switch ($sub_sub_sub_subelement['id']) {
1074
1076 $chaptertrack_entry[$sub_sub_sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_sub_sub_subelement['data']);
1077 break;
1078
1079 default:
1080 $this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement);
1081 break;
1082 }
1083 }
1084 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry;
1085 break;
1086
1088 $chapterdisplay_entry = array();
1089
1090 while ($this->getEBMLelement($sub_sub_sub_subelement, $sub_sub_subelement['end'], true)) {
1091 switch ($sub_sub_sub_subelement['id']) {
1092
1093 case EBML_ID_CHAPSTRING:
1096 $chapterdisplay_entry[$sub_sub_sub_subelement['id_name']] = $sub_sub_sub_subelement['data'];
1097 break;
1098
1099 default:
1100 $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement);
1101 break;
1102 }
1103 }
1104 $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry;
1105 break;
1106
1107 default:
1108 $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement);
1109 break;
1110 }
1111 }
1112 $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry;
1113 break;
1114
1115 default:
1116 $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement);
1117 break;
1118 }
1119 }
1120 $info['matroska']['chapters'][] = $editionentry_entry;
1121 break;
1122
1123 default:
1124 $this->unhandledElement('chapters', __LINE__, $subelement);
1125 break;
1126 }
1127 }
1128 break;
1129
1130 case EBML_ID_CLUSTER: // The lower level element containing the (monolithic) Block structure.
1131 $cluster_entry = array();
1132
1133 while ($this->getEBMLelement($subelement, $element_data['end'], array(EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERSIMPLEBLOCK))) {
1134 switch ($subelement['id']) {
1135
1139 $cluster_entry[$subelement['id_name']] = getid3_lib::BigEndian2Int($subelement['data']);
1140 break;
1141
1143 $cluster_silent_tracks = array();
1144
1145 while ($this->getEBMLelement($sub_subelement, $subelement['end'], true)) {
1146 switch ($sub_subelement['id']) {
1147
1149 $cluster_silent_tracks[] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1150 break;
1151
1152 default:
1153 $this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement);
1154 break;
1155 }
1156 }
1157 $cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks;
1158 break;
1159
1161 $cluster_block_group = array('offset' => $this->current_offset);
1162
1163 while ($this->getEBMLelement($sub_subelement, $subelement['end'], array(EBML_ID_CLUSTERBLOCK))) {
1164 switch ($sub_subelement['id']) {
1165
1167 $cluster_block_group[$sub_subelement['id_name']] = $this->HandleEMBLClusterBlock($sub_subelement, EBML_ID_CLUSTERBLOCK, $info);
1168 break;
1169
1170 case EBML_ID_CLUSTERREFERENCEPRIORITY: // unsigned-int
1171 case EBML_ID_CLUSTERBLOCKDURATION: // unsigned-int
1172 $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::BigEndian2Int($sub_subelement['data']);
1173 break;
1174
1175 case EBML_ID_CLUSTERREFERENCEBLOCK: // signed-int
1176 $cluster_block_group[$sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_subelement['data'], false, true);
1177 break;
1178
1180 $cluster_block_group[$sub_subelement['id_name']] = getid3_lib::trimNullByte($sub_subelement['data']);
1181 break;
1182
1183 default:
1184 $this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement);
1185 break;
1186 }
1187 }
1188 $cluster_entry[$subelement['id_name']][] = $cluster_block_group;
1189 break;
1190
1192 $cluster_entry[$subelement['id_name']][] = $this->HandleEMBLClusterBlock($subelement, EBML_ID_CLUSTERSIMPLEBLOCK, $info);
1193 break;
1194
1195 default:
1196 $this->unhandledElement('cluster', __LINE__, $subelement);
1197 break;
1198 }
1199 $this->current_offset = $subelement['end'];
1200 }
1201 if (!self::$hide_clusters) {
1202 $info['matroska']['cluster'][] = $cluster_entry;
1203 }
1204
1205 // check to see if all the data we need exists already, if so, break out of the loop
1206 if (!self::$parse_whole_file) {
1207 if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
1208 if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
1209 if (count($info['matroska']['track_data_offsets']) == count($info['matroska']['tracks']['tracks'])) {
1210 return;
1211 }
1212 }
1213 }
1214 }
1215 break;
1216
1217 default:
1218 $this->unhandledElement('segment', __LINE__, $element_data);
1219 break;
1220 }
1221 }
1222 break;
1223
1224 default:
1225 $this->unhandledElement('root', __LINE__, $top_element);
1226 break;
1227 }
1228 }
1229 }
saveAttachment($name, $offset, $length, $image_mime=null)
Definition: getid3.php:1766
static trimNullByte($string)
static BigEndian2Float($byteword)
Definition: getid3.lib.php:185
static TargetTypeValue($target_type)
static EBML2Int($EBMLstring)
static EBMLdate2unix($EBMLdatestamp)
HandleEMBLClusterBlock($element, $block_type, &$info)

References $current_offset, $info, getid3_lib\BigEndian2Float(), getid3_lib\BigEndian2Int(), EBML2Int(), EBML_ID_ASPECTRATIOTYPE, EBML_ID_ATTACHEDFILE, EBML_ID_ATTACHMENTS, EBML_ID_AUDIO, EBML_ID_BITDEPTH, EBML_ID_CHANNELPOSITIONS, EBML_ID_CHANNELS, EBML_ID_CHAPCOUNTRY, EBML_ID_CHAPLANGUAGE, EBML_ID_CHAPSTRING, EBML_ID_CHAPTERATOM, EBML_ID_CHAPTERDISPLAY, EBML_ID_CHAPTERFLAGENABLED, EBML_ID_CHAPTERFLAGHIDDEN, EBML_ID_CHAPTERS, EBML_ID_CHAPTERSEGMENTEDITIONUID, EBML_ID_CHAPTERSEGMENTUID, EBML_ID_CHAPTERTIMEEND, EBML_ID_CHAPTERTIMESTART, EBML_ID_CHAPTERTRACK, EBML_ID_CHAPTERTRACKNUMBER, EBML_ID_CHAPTERTRANSLATE, EBML_ID_CHAPTERTRANSLATECODEC, EBML_ID_CHAPTERTRANSLATEEDITIONUID, EBML_ID_CHAPTERTRANSLATEID, EBML_ID_CHAPTERUID, EBML_ID_CLUSTER, EBML_ID_CLUSTERBLOCK, EBML_ID_CLUSTERBLOCKDURATION, EBML_ID_CLUSTERBLOCKGROUP, EBML_ID_CLUSTERCODECSTATE, EBML_ID_CLUSTERPOSITION, EBML_ID_CLUSTERPREVSIZE, EBML_ID_CLUSTERREFERENCEBLOCK, EBML_ID_CLUSTERREFERENCEPRIORITY, EBML_ID_CLUSTERSILENTTRACKNUMBER, EBML_ID_CLUSTERSILENTTRACKS, EBML_ID_CLUSTERSIMPLEBLOCK, EBML_ID_CLUSTERTIMECODE, EBML_ID_CODECDECODEALL, EBML_ID_CODECID, EBML_ID_CODECNAME, EBML_ID_CODECPRIVATE, EBML_ID_COLOURSPACE, EBML_ID_CONTENTCOMPALGO, EBML_ID_CONTENTCOMPRESSION, EBML_ID_CONTENTCOMPSETTINGS, EBML_ID_CONTENTENCALGO, EBML_ID_CONTENTENCKEYID, EBML_ID_CONTENTENCODING, EBML_ID_CONTENTENCODINGORDER, EBML_ID_CONTENTENCODINGS, EBML_ID_CONTENTENCODINGSCOPE, EBML_ID_CONTENTENCODINGTYPE, EBML_ID_CONTENTENCRYPTION, EBML_ID_CONTENTSIGALGO, EBML_ID_CONTENTSIGHASHALGO, EBML_ID_CONTENTSIGKEYID, EBML_ID_CONTENTSIGNATURE, EBML_ID_CUEBLOCKNUMBER, EBML_ID_CUECLUSTERPOSITION, EBML_ID_CUECODECSTATE, EBML_ID_CUEPOINT, EBML_ID_CUES, EBML_ID_CUETIME, EBML_ID_CUETRACK, EBML_ID_CUETRACKPOSITIONS, EBML_ID_DATEUTC, EBML_ID_DEFAULTDURATION, EBML_ID_DISPLAYHEIGHT, EBML_ID_DISPLAYUNIT, EBML_ID_DISPLAYWIDTH, EBML_ID_DOCTYPE, EBML_ID_DOCTYPEREADVERSION, EBML_ID_DOCTYPEVERSION, EBML_ID_DURATION, EBML_ID_EBML, EBML_ID_EBMLMAXIDLENGTH, EBML_ID_EBMLMAXSIZELENGTH, EBML_ID_EBMLREADVERSION, EBML_ID_EBMLVERSION, EBML_ID_EDITIONENTRY, EBML_ID_EDITIONFLAGDEFAULT, EBML_ID_EDITIONFLAGHIDDEN, EBML_ID_EDITIONFLAGORDERED, EBML_ID_EDITIONUID, EBML_ID_FILEDATA, EBML_ID_FILEDESCRIPTION, EBML_ID_FILEMIMETYPE, EBML_ID_FILENAME, EBML_ID_FILEUID, EBML_ID_FLAGDEFAULT, EBML_ID_FLAGENABLED, EBML_ID_FLAGFORCED, EBML_ID_FLAGINTERLACED, EBML_ID_FLAGLACING, EBML_ID_GAMMAVALUE, EBML_ID_INFO, EBML_ID_LANGUAGE, EBML_ID_MAXBLOCKADDITIONID, EBML_ID_MAXCACHE, EBML_ID_MINCACHE, EBML_ID_MUXINGAPP, EBML_ID_NAME, EBML_ID_NEXTFILENAME, EBML_ID_NEXTUID, EBML_ID_OLDSTEREOMODE, EBML_ID_OUTPUTSAMPLINGFREQUENCY, EBML_ID_PIXELCROPBOTTOM, EBML_ID_PIXELCROPLEFT, EBML_ID_PIXELCROPRIGHT, EBML_ID_PIXELCROPTOP, EBML_ID_PIXELHEIGHT, EBML_ID_PIXELWIDTH, EBML_ID_PREVFILENAME, EBML_ID_PREVUID, EBML_ID_SAMPLINGFREQUENCY, EBML_ID_SEEK, EBML_ID_SEEKHEAD, EBML_ID_SEEKID, EBML_ID_SEEKPOSITION, EBML_ID_SEGMENT, EBML_ID_SEGMENTFAMILY, EBML_ID_SEGMENTFILENAME, EBML_ID_SEGMENTUID, EBML_ID_SIMPLETAG, EBML_ID_STEREOMODE, EBML_ID_TAG, EBML_ID_TAGATTACHMENTUID, EBML_ID_TAGCHAPTERUID, EBML_ID_TAGEDITIONUID, EBML_ID_TAGS, EBML_ID_TAGTRACKUID, EBML_ID_TARGETS, EBML_ID_TARGETTYPE, EBML_ID_TARGETTYPEVALUE, EBML_ID_TIMECODESCALE, EBML_ID_TITLE, EBML_ID_TRACKENTRY, EBML_ID_TRACKNUMBER, EBML_ID_TRACKS, EBML_ID_TRACKTIMECODESCALE, EBML_ID_TRACKTYPE, EBML_ID_TRACKUID, EBML_ID_VIDEO, EBML_ID_WRITINGAPP, EBMLdate2unix(), EBMLidName(), getEBMLelement(), HandleEMBLClusterBlock(), HandleEMBLSimpleTag(), readEBMLelementData(), getid3_handler\saveAttachment(), TargetTypeValue(), getid3_lib\trimNullByte(), unhandledElement(), and getid3_handler\warning().

Referenced by Analyze().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readEBMLelementData()

getid3_matroska::readEBMLelementData (   $length,
  $check_buffer = false 
)
private

Definition at line 1284 of file module.audio-video.matroska.php.

1284 {
1285 if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) {
1286 return false;
1287 }
1288 $data = substr($this->EBMLbuffer, $this->current_offset - $this->EBMLbuffer_offset, $length);
1289 $this->current_offset += $length;
1290 return $data;
1291 }
$data
Definition: bench.php:6

References $data, and EnsureBufferHasEnoughData().

Referenced by getEBMLelement(), HandleEMBLClusterBlock(), and parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readEBMLint()

getid3_matroska::readEBMLint ( )
private

Definition at line 1252 of file module.audio-video.matroska.php.

1252 {
1253 $actual_offset = $this->current_offset - $this->EBMLbuffer_offset;
1254
1255 // get length of integer
1256 $first_byte_int = ord($this->EBMLbuffer[$actual_offset]);
1257 if (0x80 & $first_byte_int) {
1258 $length = 1;
1259 } elseif (0x40 & $first_byte_int) {
1260 $length = 2;
1261 } elseif (0x20 & $first_byte_int) {
1262 $length = 3;
1263 } elseif (0x10 & $first_byte_int) {
1264 $length = 4;
1265 } elseif (0x08 & $first_byte_int) {
1266 $length = 5;
1267 } elseif (0x04 & $first_byte_int) {
1268 $length = 6;
1269 } elseif (0x02 & $first_byte_int) {
1270 $length = 7;
1271 } elseif (0x01 & $first_byte_int) {
1272 $length = 8;
1273 } else {
1274 throw new Exception('invalid EBML integer (leading 0x00) at '.$this->current_offset);
1275 }
1276
1277 // read
1278 $int_value = self::EBML2Int(substr($this->EBMLbuffer, $actual_offset, $length));
1279 $this->current_offset += $length;
1280
1281 return $int_value;
1282 }

References $EBMLbuffer_offset, and EBML2Int().

Referenced by getEBMLelement(), and HandleEMBLClusterBlock().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TargetTypeValue()

static getid3_matroska::TargetTypeValue (   $target_type)
static

Definition at line 1497 of file module.audio-video.matroska.php.

1497 {
1498 // http://www.matroska.org/technical/specs/tagging/index.html
1499 static $TargetTypeValue = array();
1500 if (empty($TargetTypeValue)) {
1501 $TargetTypeValue[10] = 'A: ~ V:shot'; // the lowest hierarchy found in music or movies
1502 $TargetTypeValue[20] = 'A:subtrack/part/movement ~ V:scene'; // corresponds to parts of a track for audio (like a movement)
1503 $TargetTypeValue[30] = 'A:track/song ~ V:chapter'; // the common parts of an album or a movie
1504 $TargetTypeValue[40] = 'A:part/session ~ V:part/session'; // when an album or episode has different logical parts
1505 $TargetTypeValue[50] = 'A:album/opera/concert ~ V:movie/episode/concert'; // the most common grouping level of music and video (equals to an episode for TV series)
1506 $TargetTypeValue[60] = 'A:edition/issue/volume/opus ~ V:season/sequel/volume'; // a list of lower levels grouped together
1507 $TargetTypeValue[70] = 'A:collection ~ V:collection'; // the high hierarchy consisting of many different lower items
1508 }
1509 return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
1510 }
$target_type
Definition: goto.php:48

References $target_type.

Referenced by parseEBML().

+ Here is the caller graph for this function:

◆ unhandledElement()

getid3_matroska::unhandledElement (   $type,
  $line,
  $element 
)
private

Definition at line 1329 of file module.audio-video.matroska.php.

1329 {
1330 // warn only about unknown and missed elements, not about unuseful
1331 if (!in_array($element['id'], $this->unuseful_elements)) {
1332 $this->warning('Unhandled '.$type.' element ['.basename(__FILE__).':'.$line.'] ('.$element['id'].'::'.$element['id_name'].' ['.$element['length'].' bytes]) at '.$element['offset']);
1333 }
1334
1335 // increase offset for unparsed elements
1336 if (!isset($element['data'])) {
1337 $this->current_offset = $element['end'];
1338 }
1339 }
$type

References $type, and getid3_handler\warning().

Referenced by HandleEMBLSimpleTag(), and parseEBML().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $current_offset

getid3_matroska::$current_offset = 0
private

◆ $EBMLbuffer

getid3_matroska::$EBMLbuffer = ''
private

Definition at line 223 of file module.audio-video.matroska.php.

◆ $EBMLbuffer_length

getid3_matroska::$EBMLbuffer_length = 0
private

Definition at line 225 of file module.audio-video.matroska.php.

◆ $EBMLbuffer_offset

getid3_matroska::$EBMLbuffer_offset = 0
private

Definition at line 224 of file module.audio-video.matroska.php.

Referenced by readEBMLint().

◆ $hide_clusters

getid3_matroska::$hide_clusters = true
static

Definition at line 219 of file module.audio-video.matroska.php.

◆ $parse_whole_file

getid3_matroska::$parse_whole_file = false
static

Definition at line 220 of file module.audio-video.matroska.php.

◆ $unuseful_elements

getid3_matroska::$unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID)
private

Definition at line 227 of file module.audio-video.matroska.php.


The documentation for this class was generated from the following file: