: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
$block_data['flags']['lacing_type'] = self::BlockLacingType($block_data['flags']['lacing']);
// Lace (when lacing bit is set)
if ($block_data['flags']['lacing'] > 0) {
$block_data['lace_frames'] = getid3_lib::BigEndian2Int($this->readEBMLelementData(1)) + 1; // Number of frames in the lace-1 (uint8)
if ($block_data['flags']['lacing'] != 0x02) {
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).
if ($block_data['flags']['lacing'] == 0x03) { // EBML lacing
$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.
$block_data['lace_frames_size'][$i] = 0;
$size = getid3_lib::BigEndian2Int($this->readEBMLelementData(1));
$block_data['lace_frames_size'][$i] += $size;
if ($block_data['flags']['lacing'] == 0x01) { // calc size of the last frame only for Xiph lacing, till EBML sizes are now anyway determined incorrectly
$block_data['lace_frames_size'][] = $element['end'] - $this->current_offset - array_sum($block_data['lace_frames_size']);
if (!isset($info['matroska']['track_data_offsets'][$block_data['tracknumber']])) {
$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['offset'] = $this->current_offset;
$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'] = $element['end'] - $this->current_offset;
//$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] = 0;
//$info['matroska']['track_data_offsets'][$block_data['tracknumber']]['total_length'] += $info['matroska']['track_data_offsets'][$block_data['tracknumber']]['length'];
//$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);
$this->current_offset = $element['end'];
* @param string $EBMLstring
* @return int|float|false
private static function EBML2Int($EBMLstring) {
// http://matroska.org/specs/
// Element ID coded with an UTF-8 like system:
// 1xxx xxxx - Class A IDs (2^7 -2 possible values) (base 0x8X)
// 01xx xxxx xxxx xxxx - Class B IDs (2^14-2 possible values) (base 0x4X 0xXX)
// 001x xxxx xxxx xxxx xxxx xxxx - Class C IDs (2^21-2 possible values) (base 0x2X 0xXX 0xXX)
// 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - Class D IDs (2^28-2 possible values) (base 0x1X 0xXX 0xXX 0xXX)
// Values with all x at 0 and 1 are reserved (hence the -2).
// Data size, in octets, is also coded with an UTF-8 like system :
// 1xxx xxxx - value 0 to 2^7-2
// 01xx xxxx xxxx xxxx - value 0 to 2^14-2
// 001x xxxx xxxx xxxx xxxx xxxx - value 0 to 2^21-2
// 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^28-2
// 0000 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^35-2
// 0000 01xx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^42-2
// 0000 001x xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^49-2
// 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2
$first_byte_int = ord($EBMLstring[0]);
if (0x80 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x7F);
} elseif (0x40 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x3F);
} elseif (0x20 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x1F);
} elseif (0x10 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x0F);
} elseif (0x08 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x07);
} elseif (0x04 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x03);
} elseif (0x02 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x01);
} elseif (0x01 & $first_byte_int) {
$EBMLstring[0] = chr($first_byte_int & 0x00);
return getid3_lib::BigEndian2Int($EBMLstring);
* @param int $EBMLdatestamp
private static function EBMLdate2unix($EBMLdatestamp) {
// Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC)
// 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC
return round(($EBMLdatestamp / 1000000000) + 978307200);
* @param int $target_type
public static function TargetTypeValue($target_type) {
// http://www.matroska.org/technical/specs/tagging/index.html
static $TargetTypeValue = array();
if (empty($TargetTypeValue)) {
$TargetTypeValue[10] = 'A: ~ V:shot'; // the lowest hierarchy found in music or movies
$TargetTypeValue[20] = 'A:subtrack/part/movement ~ V:scene'; // corresponds to parts of a track for audio (like a movement)
$TargetTypeValue[30] = 'A:track/song ~ V:chapter'; // the common parts of an album or a movie
$TargetTypeValue[40] = 'A:part/session ~ V:part/session'; // when an album or episode has different logical parts
$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)
$TargetTypeValue[60] = 'A:edition/issue/volume/opus ~ V:season/sequel/volume'; // a list of lower levels grouped together
$TargetTypeValue[70] = 'A:collection ~ V:collection'; // the high hierarchy consisting of many different lower items
return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
public static function BlockLacingType($lacingtype) {
// http://matroska.org/technical/specs/index.html#block_structure
static $BlockLacingType = array();
if (empty($BlockLacingType)) {
$BlockLacingType[0x00] = 'no lacing';
$BlockLacingType[0x01] = 'Xiph lacing';
$BlockLacingType[0x02] = 'fixed-size lacing';
$BlockLacingType[0x03] = 'EBML lacing';
return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype);
public static function CodecIDtoCommonName($codecid) {
// http://www.matroska.org/technical/specs/codecid/index.html
static $CodecIDlist = array();
if (empty($CodecIDlist)) {
$CodecIDlist['A_AAC'] = 'aac';
$CodecIDlist['A_AAC/MPEG2/LC'] = 'aac';
$CodecIDlist['A_AC3'] = 'ac3';
$CodecIDlist['A_EAC3'] = 'eac3';
$CodecIDlist['A_DTS'] = 'dts';
$CodecIDlist['A_FLAC'] = 'flac';
$CodecIDlist['A_MPEG/L1'] = 'mp1';
$CodecIDlist['A_MPEG/L2'] = 'mp2';
$CodecIDlist['A_MPEG/L3'] = 'mp3';
$CodecIDlist['A_PCM/INT/LIT'] = 'pcm'; // PCM Integer Little Endian
$CodecIDlist['A_PCM/INT/BIG'] = 'pcm'; // PCM Integer Big Endian
$CodecIDlist['A_QUICKTIME/QDMC'] = 'quicktime'; // Quicktime: QDesign Music
$CodecIDlist['A_QUICKTIME/QDM2'] = 'quicktime'; // Quicktime: QDesign Music v2
$CodecIDlist['A_VORBIS'] = 'vorbis';
$CodecIDlist['V_MPEG1'] = 'mpeg';
$CodecIDlist['V_THEORA'] = 'theora';
$CodecIDlist['V_REAL/RV40'] = 'real';
$CodecIDlist['V_REAL/RV10'] = 'real';
$CodecIDlist['V_REAL/RV20'] = 'real';
$CodecIDlist['V_REAL/RV30'] = 'real';
$CodecIDlist['V_QUICKTIME'] = 'quicktime'; // Quicktime
$CodecIDlist['V_MPEG4/ISO/AP'] = 'mpeg4';
$CodecIDlist['V_MPEG4/ISO/ASP'] = 'mpeg4';
$CodecIDlist['V_MPEG4/ISO/AVC'] = 'h264';
$CodecIDlist['V_MPEG4/ISO/SP'] = 'mpeg4';
$CodecIDlist['V_VP8'] = 'vp8';
$CodecIDlist['V_MS/VFW/FOURCC'] = 'vcm'; // Microsoft (TM) Video Codec Manager (VCM)
$CodecIDlist['A_MS/ACM'] = 'acm'; // Microsoft (TM) Audio Codec Manager (ACM)
return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
private static function EBMLidName($value) {
static $EBMLidList = array();
if (empty($EBMLidList)) {
$EBMLidList[EBML_ID_ASPECTRATIOTYPE] = 'AspectRatioType';
$EBMLidList[EBML_ID_ATTACHEDFILE] = 'AttachedFile';
$EBMLidList[EBML_ID_ATTACHMENTLINK] = 'AttachmentLink';
$EBMLidList[EBML_ID_ATTACHMENTS] = 'Attachments';
$EBMLidList[EBML_ID_AUDIO] = 'Audio';
$EBMLidList[EBML_ID_BITDEPTH] = 'BitDepth';
$EBMLidList[EBML_ID_CHANNELPOSITIONS] = 'ChannelPositions';
$EBMLidList[EBML_ID_CHANNELS] = 'Channels';
$EBMLidList[EBML_ID_CHAPCOUNTRY] = 'ChapCountry';
$EBMLidList[EBML_ID_CHAPLANGUAGE] = 'ChapLanguage';
$EBMLidList[EBML_ID_CHAPPROCESS] = 'ChapProcess';
$EBMLidList[EBML_ID_CHAPPROCESSCODECID] = 'ChapProcessCodecID';
$EBMLidList[EBML_ID_CHAPPROCESSCOMMAND] = 'ChapProcessCommand';
$EBMLidList[EBML_ID_CHAPPROCESSDATA] = 'ChapProcessData';
$EBMLidList[EBML_ID_CHAPPROCESSPRIVATE] = 'ChapProcessPrivate';
$EBMLidList[EBML_ID_CHAPPROCESSTIME] = 'ChapProcessTime';
$EBMLidList[EBML_ID_CHAPSTRING] = 'ChapString';
$EBMLidList[EBML_ID_CHAPTERATOM] = 'ChapterAtom';
$EBMLidList[EBML_ID_CHAPTERDISPLAY] = 'ChapterDisplay';
$EBMLidList[EBML_ID_CHAPTERFLAGENABLED] = 'ChapterFlagEnabled';
$EBMLidList[EBML_ID_CHAPTERFLAGHIDDEN] = 'ChapterFlagHidden';
$EBMLidList[EBML_ID_CHAPTERPHYSICALEQUIV] = 'ChapterPhysicalEquiv';
$EBMLidList[EBML_ID_CHAPTERS] = 'Chapters';
$EBMLidList[EBML_ID_CHAPTERSEGMENTEDITIONUID] = 'ChapterSegmentEditionUID';
$EBMLidList[EBML_ID_CHAPTERSEGMENTUID] = 'ChapterSegmentUID';
$EBMLidList[EBML_ID_CHAPTERTIMEEND] = 'ChapterTimeEnd';
$EBMLidList[EBML_ID_CHAPTERTIMESTART] = 'ChapterTimeStart';
$EBMLidList[EBML_ID_CHAPTERTRACK] = 'ChapterTrack';
$EBMLidList[EBML_ID_CHAPTERTRACKNUMBER] = 'ChapterTrackNumber';
$EBMLidList[EBML_ID_CHAPTERTRANSLATE] = 'ChapterTranslate';
$EBMLidList[EBML_ID_CHAPTERTRANSLATECODEC] = 'ChapterTranslateCodec';
$EBMLidList[EBML_ID_CHAPTERTRANSLATEEDITIONUID] = 'ChapterTranslateEditionUID';
$EBMLidList[EBML_ID_CHAPTERTRANSLATEID] = 'ChapterTranslateID';
$EBMLidList[EBML_ID_CHAPTERUID] = 'ChapterUID';
$EBMLidList[EBML_ID_CLUSTER] = 'Cluster';
$EBMLidList[EBML_ID_CLUSTERBLOCK] = 'ClusterBlock';
$EBMLidList[EBML_ID_CLUSTERBLOCKADDID] = 'ClusterBlockAddID';
$EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONAL] = 'ClusterBlockAdditional';
$EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONID] = 'ClusterBlockAdditionID';
$EBMLidList[EBML_ID_CLUSTERBLOCKADDITIONS] = 'ClusterBlockAdditions';
$EBMLidList[EBML_ID_CLUSTERBLOCKDURATION] = 'ClusterBlockDuration';
$EBMLidList[EBML_ID_CLUSTERBLOCKGROUP] = 'ClusterBlockGroup';
$EBMLidList[EBML_ID_CLUSTERBLOCKMORE] = 'ClusterBlockMore';
$EBMLidList[EBML_ID_CLUSTERBLOCKVIRTUAL] = 'ClusterBlockVirtual';
$EBMLidList[EBML_ID_CLUSTERCODECSTATE] = 'ClusterCodecState';
$EBMLidList[EBML_ID_CLUSTERDELAY] = 'ClusterDelay';
$EBMLidList[EBML_ID_CLUSTERDURATION] = 'ClusterDuration';
$EBMLidList[EBML_ID_CLUSTERENCRYPTEDBLOCK] = 'ClusterEncryptedBlock';
$EBMLidList[EBML_ID_CLUSTERFRAMENUMBER] = 'ClusterFrameNumber';
$EBMLidList[EBML_ID_CLUSTERLACENUMBER] = 'ClusterLaceNumber';
$EBMLidList[EBML_ID_CLUSTERPOSITION] = 'ClusterPosition';
$EBMLidList[EBML_ID_CLUSTERPREVSIZE] = 'ClusterPrevSize';
$EBMLidList[EBML_ID_CLUSTERREFERENCEBLOCK] = 'ClusterReferenceBlock';
$EBMLidList[EBML_ID_CLUSTERREFERENCEPRIORITY] = 'ClusterReferencePriority';
$EBMLidList[EBML_ID_CLUSTERREFERENCEVIRTUAL] = 'ClusterReferenceVirtual';
$EBMLidList[EBML_ID_CLUSTERSILENTTRACKNUMBER] = 'ClusterSilentTrackNumber';
$EBMLidList[EBML_ID_CLUSTERSILENTTRACKS] = 'ClusterSilentTracks';
$EBMLidList[EBML_ID_CLUSTERSIMPLEBLOCK] = 'ClusterSimpleBlock';
$EBMLidList[EBML_ID_CLUSTERTIMECODE] = 'ClusterTimecode';
$EBMLidList[EBML_ID_CLUSTERTIMESLICE] = 'ClusterTimeSlice';
$EBMLidList[EBML_ID_CODECDECODEALL] = 'CodecDecodeAll';
$EBMLidList[EBML_ID_CODECDOWNLOADURL] = 'CodecDownloadURL';
$EBMLidList[EBML_ID_CODECID] = 'CodecID';
$EBMLidList[EBML_ID_CODECINFOURL] = 'CodecInfoURL';
$EBMLidList[EBML_ID_CODECNAME] = 'CodecName';
$EBMLidList[EBML_ID_CODECPRIVATE] = 'CodecPrivate';
$EBMLidList[EBML_ID_CODECSETTINGS] = 'CodecSettings';
$EBMLidList[EBML_ID_COLOURSPACE] = 'ColourSpace';
$EBMLidList[EBML_ID_CONTENTCOMPALGO] = 'ContentCompAlgo';
$EBMLidList[EBML_ID_CONTENTCOMPRESSION] = 'ContentCompression';
$EBMLidList[EBML_ID_CONTENTCOMPSETTINGS] = 'ContentCompSettings';
$EBMLidList[EBML_ID_CONTENTENCALGO] = 'ContentEncAlgo';
$EBMLidList[EBML_ID_CONTENTENCKEYID] = 'ContentEncKeyID';
$EBMLidList[EBML_ID_CONTENTENCODING] = 'ContentEncoding';
$EBMLidList[EBML_ID_CONTENTENCODINGORDER] = 'ContentEncodingOrder';
$EBMLidList[EBML_ID_CONTENTENCODINGS] = 'ContentEncodings';
$EBMLidList[EBML_ID_CONTENTENCODINGSCOPE] = 'ContentEncodingScope';
$EBMLidList[EBML_ID_CONTENTENCODINGTYPE] = 'ContentEncodingType';
$EBMLidList[EBML_ID_CONTENTENCRYPTION] = 'ContentEncryption';
$EBMLidList[EBML_ID_CONTENTSIGALGO] = 'ContentSigAlgo';
$EBMLidList[EBML_ID_CONTENTSIGHASHALGO] = 'ContentSigHashAlgo';
$EBMLidList[EBML_ID_CONTENTSIGKEYID] = 'ContentSigKeyID';
$EBMLidList[EBML_ID_CONTENTSIGNATURE] = 'ContentSignature';
$EBMLidList[EBML_ID_CRC32] = 'CRC32';
$EBMLidList[EBML_ID_CUEBLOCKNUMBER] = 'CueBlockNumber';
$EBMLidList[EBML_ID_CUECLUSTERPOSITION] = 'CueClusterPosition';
$EBMLidList[EBML_ID_CUECODECSTATE] = 'CueCodecState';
$EBMLidList[EBML_ID_CUEPOINT] = 'CuePoint';
$EBMLidList[EBML_ID_CUEREFCLUSTER] = 'CueRefCluster';
$EBMLidList[EBML_ID_CUEREFCODECSTATE] = 'CueRefCodecState';
$EBMLidList[EBML_ID_CUEREFERENCE] = 'CueReference';
$EBMLidList[EBML_ID_CUEREFNUMBER] = 'CueRefNumber';
$EBMLidList[EBML_ID_CUEREFTIME] = 'CueRefTime';
$EBMLidList[EBML_ID_CUES] = 'Cues';
$EBMLidList[EBML_ID_CUETIME] = 'CueTime';
$EBMLidList[EBML_ID_CUETRACK] = 'CueTrack';
$EBMLidList[EBML_ID_CUETRACKPOSITIONS] = 'CueTrackPositions';
$EBMLidList[EBML_ID_DATEUTC] = 'DateUTC';
$EBMLidList[EBML_ID_DEFAULTDURATION] = 'DefaultDuration';
$EBMLidList[EBML_ID_DISPLAYHEIGHT] = 'DisplayHeight';
$EBMLidList[EBML_ID_DISPLAYUNIT] = 'DisplayUnit';
$EBMLidList[EBML_ID_DISPLAYWIDTH] = 'DisplayWidth';
$EBMLidList[EBML_ID_DOCTYPE] = 'DocType';
$EBMLidList[EBML_ID_DOCTYPEREADVERSION] = 'DocTypeReadVersion';
$EBMLidList[EBML_ID_DOCTYPEVERSION] = 'DocTypeVersion';
$EBMLidList[EBML_ID_DURATION] = 'Duration';
$EBMLidList[EBML_ID_EBML] = 'EBML';
$EBMLidList[EBML_ID_EBMLMAXIDLENGTH] = 'EBMLMaxIDLength';
$EBMLidList[EBML_ID_EBMLMAXSIZELENGTH] = 'EBMLMaxSizeLength';
$EBMLidList[EBML_ID_EBMLREADVERSION] = 'EBMLReadVersion';
$EBMLidList[EBML_ID_EBMLVERSION] = 'EBMLVersion';
$EBMLidList[EBML_ID_EDITIONENTRY] = 'EditionEntry';
$EBMLidList[EBML_ID_EDITIONFLAGDEFAULT] = 'EditionFlagDefault';
$EBMLidList[EBML_ID_EDITIONFLAGHIDDEN] = 'EditionFlagHidden';
$EBMLidList[EBML_ID_EDITIONFLAGORDERED] = 'EditionFlagOrdered';
$EBMLidList[EBML_ID_EDITIONUID] = 'EditionUID';
$EBMLidList[EBML_ID_FILEDATA] = 'FileData';
$EBMLidList[EBML_ID_FILEDESCRIPTION] = 'FileDescription';
$EBMLidList[EBML_ID_FILEMIMETYPE] = 'FileMimeType';
$EBMLidList[EBML_ID_FILENAME] = 'FileName';
$EBMLidList[EBML_ID_FILEREFERRAL] = 'FileReferral';
$EBMLidList[EBML_ID_FILEUID] = 'FileUID';
$EBMLidList[EBML_ID_FLAGDEFAULT] = 'FlagDefault';
$EBMLidList[EBML_ID_FLAGENABLED] = 'FlagEnabled';
$EBMLidList[EBML_ID_FLAGFORCED] = 'FlagForced';
$EBMLidList[EBML_ID_FLAGINTERLACED] = 'FlagInterlaced';
$EBMLidList[EBML_ID_FLAGLACING] = 'FlagLacing';
$EBMLidList[EBML_ID_GAMMAVALUE] = 'GammaValue';
$EBMLidList[EBML_ID_INFO] = 'Info';
$EBMLidList[EBML_ID_LANGUAGE] = 'Language';
$EBMLidList[EBML_ID_MAXBLOCKADDITIONID] = 'MaxBlockAdditionID';
$EBMLidList[EBML_ID_MAXCACHE] = 'MaxCache';
$EBMLidList[EBML_ID_MINCACHE] = 'MinCache';
$EBMLidList[EBML_ID_MUXINGAPP] = 'MuxingApp';
$EBMLidList[EBML_ID_NAME] = 'Name';
$EBMLidList[EBML_ID_NEXTFILENAME] = 'NextFilename';
$EBMLidList[EBML_ID_NEXTUID] = 'NextUID';
$EBMLidList[EBML_ID_OUTPUTSAMPLINGFREQUENCY] = 'OutputSamplingFrequency';
$EBMLidList[EBML_ID_PIXELCROPBOTTOM] = 'PixelCropBottom';
$EBMLidList[EBML_ID_PIXELCROPLEFT] = 'PixelCropLeft';
$EBMLidList[EBML_ID_PIXELCROPRIGHT] = 'PixelCropRight';
$EBMLidList[EBML_ID_PIXELCROPTOP] = 'PixelCropTop';
$EBMLidList[EBML_ID_PIXELHEIGHT] = 'PixelHeight';
$EBMLidList[EBML_ID_PIXELWIDTH] = 'PixelWidth';
$EBMLidList[EBML_ID_PREVFILENAME] = 'PrevFilename';
$EBMLidList[EBML_ID_PREVUID] = 'PrevUID';
$EBMLidList[EBML_ID_SAMPLINGFREQUENCY] = 'SamplingFrequency';
$EBMLidList[EBML_ID_SEEK] = 'Seek';
$EBMLidList[EBML_ID_SEEKHEAD] = 'SeekHead';
$EBMLidList[EBML_ID_SEEKID] = 'SeekID';
$EBMLidList[EBML_ID_SEEKPOSITION] = 'SeekPosition';
$EBMLidList[EBML_ID_SEGMENT] = 'Segment';
$EBMLidList[EBML_ID_SEGMENTFAMILY] = 'SegmentFamily';
$EBMLidList[EBML_ID_SEGMENTFILENAME] = 'SegmentFilename';
$EBMLidList[EBML_ID_SEGMENTUID] = 'SegmentUID';
$EBMLidList[EBML_ID_SIMPLETAG] = 'SimpleTag';
$EBMLidList[EBML_ID_CLUSTERSLICES] = 'ClusterSlices';
$EBMLidList[EBML_ID_STEREOMODE] = 'StereoMode';
$EBMLidList[EBML_ID_OLDSTEREOMODE] = 'OldStereoMode';
$EBMLidList[EBML_ID_TAG] = 'Tag';
$EBMLidList[EBML_ID_TAGATTACHMENTUID] = 'TagAttachmentUID';
$EBMLidList[EBML_ID_TAGBINARY] = 'TagBinary';
$EBMLidList[EBML_ID_TAGCHAPTERUID] = 'TagChapterUID';
$EBMLidList[EBML_ID_TAGDEFAULT] = 'TagDefault';
$EBMLidList[EBML_ID_TAGEDITIONUID] = 'TagEditionUID';
$EBMLidList[EBML_ID_TAGLANGUAGE] = 'TagLanguage';
$EBMLidList[EBML_ID_TAGNAME] = 'TagName';
$EBMLidList[EBML_ID_TAGTRACKUID] = 'TagTrackUID';
$EBMLidList[EBML_ID_TAGS] = 'Tags';
$EBMLidList[EBML_ID_TAGSTRING] = 'TagString';
$EBMLidList[EBML_ID_TARGETS] = 'Targets';
$EBMLidList[EBML_ID_TARGETTYPE] = 'TargetType';
$EBMLidList[EBML_ID_TARGETTYPEVALUE] = 'TargetTypeValue';
$EBMLidList[EBML_ID_TIMECODESCALE] = 'TimecodeScale';
$EBMLidList[EBML_ID_TITLE] = 'Title';
$EBMLidList[EBML_ID_TRACKENTRY] = 'TrackEntry';
$EBMLidList[EBML_ID_TRACKNUMBER] = 'TrackNumber';
$EBMLidList[EBML_ID_TRACKOFFSET] = 'TrackOffset';
$EBMLidList[EBML_ID_TRACKOVERLAY] = 'TrackOverlay';
$EBMLidList[EBML_ID_TRACKS] = 'Tracks';
$EBMLidList[EBML_ID_TRACKTIMECODESCALE] = 'TrackTimecodeScale';
$EBMLidList[EBML_ID_TRACKTRANSLATE] = 'TrackTranslate';
$EBMLidList[EBML_ID_TRACKTRANSLATECODEC] = 'TrackTranslateCodec';
$EBMLidList[EBML_ID_TRACKTRANSLATEEDITIONUID] = 'TrackTranslateEditionUID';
$EBMLidList[EBML_ID_TRACKTRANSLATETRACKID] = 'TrackTranslateTrackID';
$EBMLidList[EBML_ID_TRACKTYPE] = 'TrackType';
$EBMLidList[EBML_ID_TRACKUID] = 'TrackUID';
$EBMLidList[EBML_ID_VIDEO] = 'Video';
$EBMLidList[EBML_ID_VOID] = 'Void';
$EBMLidList[EBML_ID_WRITINGAPP] = 'WritingApp';
return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value));
public static function displayUnit($value) {
// http://www.matroska.org/technical/specs/index.html#DisplayUnit
3 => 'Display Aspect Ratio');
return (isset($units[$value]) ? $units[$value] : 'unknown');
private static function getDefaultStreamInfo($streams)
foreach (array_reverse($streams) as $stream) {
if ($stream['default']) {
$unset = array('default', 'name');
if (isset($stream[$u])) {
$info['streams'] = $streams;