Initial working version

This commit is contained in:
Samuel Kent
2022-12-22 20:22:22 +11:00
parent ce9675a1cc
commit ced7fa5092
902 changed files with 150252 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
import { IContainerType } from './types';
/**
* Elements of document type description
* Derived from https://github.com/tungol/EBML/blob/master/doctypes/matroska.dtd
* Extended with:
* https://www.matroska.org/technical/specs/index.html
*/
export declare const elements: IContainerType;
+279
View File
@@ -0,0 +1,279 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.elements = void 0;
const types_1 = require("./types");
/**
* Elements of document type description
* Derived from https://github.com/tungol/EBML/blob/master/doctypes/matroska.dtd
* Extended with:
* https://www.matroska.org/technical/specs/index.html
*/
exports.elements = {
0x1a45dfa3: {
name: 'ebml',
container: {
0x4286: { name: 'ebmlVersion', value: types_1.DataType.uint },
0x42f7: { name: 'ebmlReadVersion', value: types_1.DataType.uint },
0x42f2: { name: 'ebmlMaxIDWidth', value: types_1.DataType.uint },
0x42f3: { name: 'ebmlMaxSizeWidth', value: types_1.DataType.uint },
0x4282: { name: 'docType', value: types_1.DataType.string },
0x4287: { name: 'docTypeVersion', value: types_1.DataType.uint },
0x4285: { name: 'docTypeReadVersion', value: types_1.DataType.uint } // 5.1.7
}
},
// Matroska segments
0x18538067: {
name: 'segment',
container: {
// Meta Seek Information
0x114d9b74: {
name: 'seekHead',
container: {
0x4dbb: {
name: 'seek',
container: {
0x53ab: { name: 'seekId', value: types_1.DataType.binary },
0x53ac: { name: 'seekPosition', value: types_1.DataType.uint }
}
}
}
},
// Segment Information
0x1549a966: {
name: 'info',
container: {
0x73a4: { name: 'uid', value: types_1.DataType.uid },
0x7384: { name: 'filename', value: types_1.DataType.string },
0x3cb923: { name: 'prevUID', value: types_1.DataType.uid },
0x3c83ab: { name: 'prevFilename', value: types_1.DataType.string },
0x3eb923: { name: 'nextUID', value: types_1.DataType.uid },
0x3e83bb: { name: 'nextFilename', value: types_1.DataType.string },
0x2ad7b1: { name: 'timecodeScale', value: types_1.DataType.uint },
0x4489: { name: 'duration', value: types_1.DataType.float },
0x4461: { name: 'dateUTC', value: types_1.DataType.uint },
0x7ba9: { name: 'title', value: types_1.DataType.string },
0x4d80: { name: 'muxingApp', value: types_1.DataType.string },
0x5741: { name: 'writingApp', value: types_1.DataType.string }
}
},
// Cluster
0x1f43b675: {
name: 'cluster',
multiple: true,
container: {
0xe7: { name: 'timecode', value: types_1.DataType.uid },
0xa3: { name: 'unknown', value: types_1.DataType.binary },
0xa7: { name: 'position', value: types_1.DataType.uid },
0xab: { name: 'prevSize', value: types_1.DataType.uid }
}
},
// Track
0x1654ae6b: {
name: 'tracks',
container: {
0xae: {
name: 'entries',
multiple: true,
container: {
0xd7: { name: 'trackNumber', value: types_1.DataType.uint },
0x73c5: { name: 'uid', value: types_1.DataType.uid },
0x83: { name: 'trackType', value: types_1.DataType.uint },
0xb9: { name: 'flagEnabled', value: types_1.DataType.bool },
0x88: { name: 'flagDefault', value: types_1.DataType.bool },
0x55aa: { name: 'flagForced', value: types_1.DataType.bool },
0x9c: { name: 'flagLacing', value: types_1.DataType.bool },
0x6de7: { name: 'minCache', value: types_1.DataType.uint },
0x6de8: { name: 'maxCache', value: types_1.DataType.uint },
0x23e383: { name: 'defaultDuration', value: types_1.DataType.uint },
0x23314f: { name: 'timecodeScale', value: types_1.DataType.float },
0x536e: { name: 'name', value: types_1.DataType.string },
0x22b59c: { name: 'language', value: types_1.DataType.string },
0x86: { name: 'codecID', value: types_1.DataType.string },
0x63a2: { name: 'codecPrivate', value: types_1.DataType.binary },
0x258688: { name: 'codecName', value: types_1.DataType.string },
0x3a9697: { name: 'codecSettings', value: types_1.DataType.string },
0x3b4040: { name: 'codecInfoUrl', value: types_1.DataType.string },
0x26b240: { name: 'codecDownloadUrl', value: types_1.DataType.string },
0xaa: { name: 'codecDecodeAll', value: types_1.DataType.bool },
0x6fab: { name: 'trackOverlay', value: types_1.DataType.uint },
// Video
0xe0: {
name: 'video',
container: {
0x9a: { name: 'flagInterlaced', value: types_1.DataType.bool },
0x53b8: { name: 'stereoMode', value: types_1.DataType.uint },
0xb0: { name: 'pixelWidth', value: types_1.DataType.uint },
0xba: { name: 'pixelHeight', value: types_1.DataType.uint },
0x54b0: { name: 'displayWidth', value: types_1.DataType.uint },
0x54ba: { name: 'displayHeight', value: types_1.DataType.uint },
0x54b3: { name: 'aspectRatioType', value: types_1.DataType.uint },
0x2eb524: { name: 'colourSpace', value: types_1.DataType.uint },
0x2fb523: { name: 'gammaValue', value: types_1.DataType.float }
}
},
// Audio
0xe1: {
name: 'audio',
container: {
0xb5: { name: 'samplingFrequency', value: types_1.DataType.float },
0x78b5: { name: 'outputSamplingFrequency', value: types_1.DataType.float },
0x9f: { name: 'channels', value: types_1.DataType.uint },
0x94: { name: 'channels', value: types_1.DataType.uint },
0x7d7b: { name: 'channelPositions', value: types_1.DataType.binary },
0x6264: { name: 'bitDepth', value: types_1.DataType.uint }
}
},
// Content Encoding
0x6d80: {
name: 'contentEncodings',
container: {
0x6240: {
name: 'contentEncoding',
container: {
0x5031: { name: 'order', value: types_1.DataType.uint },
0x5032: { name: 'scope', value: types_1.DataType.bool },
0x5033: { name: 'type', value: types_1.DataType.uint },
0x5034: {
name: 'contentEncoding',
container: {
0x4254: { name: 'contentCompAlgo', value: types_1.DataType.uint },
0x4255: { name: 'contentCompSettings', value: types_1.DataType.binary }
}
},
0x5035: {
name: 'contentEncoding',
container: {
0x47e1: { name: 'contentEncAlgo', value: types_1.DataType.uint },
0x47e2: { name: 'contentEncKeyID', value: types_1.DataType.binary },
0x47e3: { name: 'contentSignature ', value: types_1.DataType.binary },
0x47e4: { name: 'ContentSigKeyID ', value: types_1.DataType.binary },
0x47e5: { name: 'contentSigAlgo ', value: types_1.DataType.uint },
0x47e6: { name: 'contentSigHashAlgo ', value: types_1.DataType.uint }
}
},
0x6264: { name: 'bitDepth', value: types_1.DataType.uint }
}
}
}
}
}
}
}
},
// Cueing Data
0x1c53bb6b: {
name: 'cues',
container: {
0xbb: {
name: 'cuePoint',
container: {
0xb3: { name: 'cueTime', value: types_1.DataType.uid },
0xb7: {
name: 'positions',
container: {
0xf7: { name: 'track', value: types_1.DataType.uint },
0xf1: { name: 'clusterPosition', value: types_1.DataType.uint },
0x5378: { name: 'blockNumber', value: types_1.DataType.uint },
0xea: { name: 'codecState', value: types_1.DataType.uint },
0xdb: {
name: 'reference', container: {
0x96: { name: 'time', value: types_1.DataType.uint },
0x97: { name: 'cluster', value: types_1.DataType.uint },
0x535f: { name: 'number', value: types_1.DataType.uint },
0xeb: { name: 'codecState', value: types_1.DataType.uint }
}
},
0xf0: { name: 'relativePosition', value: types_1.DataType.uint } // extended
}
}
}
}
}
},
// Attachment
0x1941a469: {
name: 'attachments',
container: {
0x61a7: {
name: 'attachedFiles',
multiple: true,
container: {
0x467e: { name: 'description', value: types_1.DataType.string },
0x466e: { name: 'name', value: types_1.DataType.string },
0x4660: { name: 'mimeType', value: types_1.DataType.string },
0x465c: { name: 'data', value: types_1.DataType.binary },
0x46ae: { name: 'uid', value: types_1.DataType.uid }
}
}
}
},
// Chapters
0x1043a770: {
name: 'chapters',
container: {
0x45b9: {
name: 'editionEntry',
container: {
0xb6: {
name: 'chapterAtom',
container: {
0x73c4: { name: 'uid', value: types_1.DataType.uid },
0x91: { name: 'timeStart', value: types_1.DataType.uint },
0x92: { name: 'timeEnd', value: types_1.DataType.uid },
0x98: { name: 'hidden', value: types_1.DataType.bool },
0x4598: { name: 'enabled', value: types_1.DataType.uid },
0x8f: { name: 'track', container: {
0x89: { name: 'trackNumber', value: types_1.DataType.uid },
0x80: {
name: 'display', container: {
0x85: { name: 'string', value: types_1.DataType.string },
0x437c: { name: 'language ', value: types_1.DataType.string },
0x437e: { name: 'country ', value: types_1.DataType.string }
}
}
}
}
}
}
}
}
}
},
// Tagging
0x1254c367: {
name: 'tags',
container: {
0x7373: {
name: 'tag',
multiple: true,
container: {
0x63c0: {
name: 'target',
container: {
0x63c5: { name: 'tagTrackUID', value: types_1.DataType.uid },
0x63c4: { name: 'tagChapterUID', value: types_1.DataType.uint },
0x63c6: { name: 'tagAttachmentUID', value: types_1.DataType.uid },
0x63ca: { name: 'targetType', value: types_1.DataType.string },
0x68ca: { name: 'targetTypeValue', value: types_1.DataType.uint },
0x63c9: { name: 'tagEditionUID', value: types_1.DataType.uid } // extended
}
},
0x67c8: {
name: 'simpleTags',
multiple: true,
container: {
0x45a3: { name: 'name', value: types_1.DataType.string },
0x4487: { name: 'string', value: types_1.DataType.string },
0x4485: { name: 'binary', value: types_1.DataType.binary },
0x447a: { name: 'language', value: types_1.DataType.string },
0x447b: { name: 'languageIETF', value: types_1.DataType.string },
0x4484: { name: 'default', value: types_1.DataType.bool } // extended
}
}
}
}
}
}
}
}
};
+37
View File
@@ -0,0 +1,37 @@
import { INativeMetadataCollector } from '../common/MetadataCollector';
import { ITokenizer } from 'strtok3/lib/core';
import { IOptions } from '../type';
import { ITokenParser } from '../ParserFactory';
import { BasicParser } from '../common/BasicParser';
/**
* Extensible Binary Meta Language (EBML) parser
* https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
* http://matroska.sourceforge.net/technical/specs/rfc/index.html
*
* WEBM VP8 AUDIO FILE
*/
export declare class MatroskaParser extends BasicParser {
private padding;
private parserMap;
private ebmlMaxIDLength;
private ebmlMaxSizeLength;
constructor();
/**
* Initialize parser with output (metadata), input (tokenizer) & parsing options (options).
* @param {INativeMetadataCollector} metadata Output
* @param {ITokenizer} tokenizer Input
* @param {IOptions} options Parsing options
*/
init(metadata: INativeMetadataCollector, tokenizer: ITokenizer, options: IOptions): ITokenParser;
parse(): Promise<void>;
private parseContainer;
private readVintData;
private readElement;
private isMaxValue;
private readFloat;
private readFlag;
private readUint;
private readString;
private readBuffer;
private addTag;
}
+235
View File
@@ -0,0 +1,235 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MatroskaParser = void 0;
const Token = require("token-types");
const _debug = require("debug");
const BasicParser_1 = require("../common/BasicParser");
const types_1 = require("./types");
const matroskaDtd = require("./MatroskaDtd");
const debug = _debug('music-metadata:parser:matroska');
/**
* Extensible Binary Meta Language (EBML) parser
* https://en.wikipedia.org/wiki/Extensible_Binary_Meta_Language
* http://matroska.sourceforge.net/technical/specs/rfc/index.html
*
* WEBM VP8 AUDIO FILE
*/
class MatroskaParser extends BasicParser_1.BasicParser {
constructor() {
super();
this.padding = 0;
this.parserMap = new Map();
this.ebmlMaxIDLength = 4;
this.ebmlMaxSizeLength = 8;
this.parserMap.set(types_1.DataType.uint, e => this.readUint(e));
this.parserMap.set(types_1.DataType.string, e => this.readString(e));
this.parserMap.set(types_1.DataType.binary, e => this.readBuffer(e));
this.parserMap.set(types_1.DataType.uid, async (e) => await this.readUint(e) === 1);
this.parserMap.set(types_1.DataType.bool, e => this.readFlag(e));
this.parserMap.set(types_1.DataType.float, e => this.readFloat(e));
}
/**
* Initialize parser with output (metadata), input (tokenizer) & parsing options (options).
* @param {INativeMetadataCollector} metadata Output
* @param {ITokenizer} tokenizer Input
* @param {IOptions} options Parsing options
*/
init(metadata, tokenizer, options) {
super.init(metadata, tokenizer, options);
return this;
}
async parse() {
const matroska = await this.parseContainer(matroskaDtd.elements, this.tokenizer.fileInfo.size, []);
this.metadata.setFormat('container', `EBML/${matroska.ebml.docType}`);
if (matroska.segment) {
const info = matroska.segment.info;
if (info) {
const timecodeScale = info.timecodeScale ? info.timecodeScale : 1000000;
const duration = info.duration * timecodeScale / 1000000000;
this.addTag('segment:title', info.title);
this.metadata.setFormat('duration', duration);
}
const audioTracks = matroska.segment.tracks;
if (audioTracks && audioTracks.entries) {
audioTracks.entries.forEach(entry => {
const stream = {
codecName: entry.codecID.replace('A_', '').replace('V_', ''),
codecSettings: entry.codecSettings,
flagDefault: entry.flagDefault,
flagLacing: entry.flagLacing,
flagEnabled: entry.flagEnabled,
language: entry.language,
name: entry.name,
type: entry.trackType,
audio: entry.audio,
video: entry.video
};
this.metadata.addStreamInfo(stream);
});
const audioTrack = audioTracks.entries
.filter(entry => {
return entry.trackType === types_1.TrackType.audio.valueOf();
})
.reduce((acc, cur) => {
if (!acc) {
return cur;
}
if (!acc.flagDefault && cur.flagDefault) {
return cur;
}
if (cur.trackNumber && cur.trackNumber < acc.trackNumber) {
return cur;
}
return acc;
}, null);
if (audioTrack) {
this.metadata.setFormat('codec', audioTrack.codecID.replace('A_', ''));
this.metadata.setFormat('sampleRate', audioTrack.audio.samplingFrequency);
this.metadata.setFormat('numberOfChannels', audioTrack.audio.channels);
}
if (matroska.segment.tags) {
matroska.segment.tags.tag.forEach(tag => {
const target = tag.target;
const targetType = target.targetTypeValue ? types_1.TargetType[target.targetTypeValue] : (target.targetType ? target.targetType : 'track');
tag.simpleTags.forEach(simpleTag => {
const value = simpleTag.string ? simpleTag.string : simpleTag.binary;
this.addTag(`${targetType}:${simpleTag.name}`, value);
});
});
}
if (matroska.segment.attachments) {
matroska.segment.attachments.attachedFiles
.filter(file => file.mimeType.startsWith('image/'))
.map(file => {
return {
data: file.data,
format: file.mimeType,
description: file.description,
name: file.name
};
}).forEach(picture => {
this.addTag('picture', picture);
});
}
}
}
}
async parseContainer(container, posDone, path) {
const tree = {};
while (this.tokenizer.position < posDone) {
let element;
try {
element = await this.readElement();
}
catch (error) {
if (error.message === 'End-Of-Stream') {
break;
}
throw error;
}
const type = container[element.id];
if (type) {
debug(`Element: name=${type.name}, container=${!!type.container}`);
if (type.container) {
const res = await this.parseContainer(type.container, element.len >= 0 ? this.tokenizer.position + element.len : -1, path.concat([type.name]));
if (type.multiple) {
if (!tree[type.name]) {
tree[type.name] = [];
}
tree[type.name].push(res);
}
else {
tree[type.name] = res;
}
}
else {
tree[type.name] = await this.parserMap.get(type.value)(element);
}
}
else {
switch (element.id) {
case 0xec: // void
this.padding += element.len;
await this.tokenizer.ignore(element.len);
break;
default:
debug(`parseEbml: path=${path.join('/')}, unknown element: id=${element.id.toString(16)}`);
this.padding += element.len;
await this.tokenizer.ignore(element.len);
}
}
}
return tree;
}
async readVintData(maxLength) {
const msb = await this.tokenizer.peekNumber(Token.UINT8);
let mask = 0x80;
let oc = 1;
// Calculate VINT_WIDTH
while ((msb & mask) === 0) {
if (oc > maxLength) {
throw new Error('VINT value exceeding maximum size');
}
++oc;
mask >>= 1;
}
const id = Buffer.alloc(oc);
await this.tokenizer.readBuffer(id);
return id;
}
async readElement() {
const id = await this.readVintData(this.ebmlMaxIDLength);
const lenField = await this.readVintData(this.ebmlMaxSizeLength);
lenField[0] ^= 0x80 >> (lenField.length - 1);
const nrLen = Math.min(6, lenField.length); // JavaScript can max read 6 bytes integer
return {
id: id.readUIntBE(0, id.length),
len: lenField.readUIntBE(lenField.length - nrLen, nrLen)
};
}
isMaxValue(vintData) {
if (vintData.length === this.ebmlMaxSizeLength) {
for (let n = 1; n < this.ebmlMaxSizeLength; ++n) {
if (vintData[n] !== 0xff)
return false;
}
return true;
}
return false;
}
async readFloat(e) {
switch (e.len) {
case 0:
return 0.0;
case 4:
return this.tokenizer.readNumber(Token.Float32_BE);
case 8:
return this.tokenizer.readNumber(Token.Float64_BE);
case 10:
return this.tokenizer.readNumber(Token.Float64_BE);
default:
throw new Error(`Invalid IEEE-754 float length: ${e.len}`);
}
}
async readFlag(e) {
return (await this.readUint(e)) === 1;
}
async readUint(e) {
const buf = await this.readBuffer(e);
const nrLen = Math.min(6, e.len); // JavaScript can max read 6 bytes integer
return buf.readUIntBE(e.len - nrLen, nrLen);
}
async readString(e) {
const rawString = await this.tokenizer.readToken(new Token.StringType(e.len, 'utf-8'));
return rawString.replace(/\00.*$/g, '');
}
async readBuffer(e) {
const buf = Buffer.alloc(e.len);
await this.tokenizer.readBuffer(buf);
return buf;
}
addTag(tagId, value) {
this.metadata.addTag('matroska', tagId, value);
}
}
exports.MatroskaParser = MatroskaParser;
+4
View File
@@ -0,0 +1,4 @@
import { CaseInsensitiveTagMap } from '../common/CaseInsensitiveTagMap';
export declare class MatroskaTagMapper extends CaseInsensitiveTagMap {
constructor();
}
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MatroskaTagMapper = void 0;
const CaseInsensitiveTagMap_1 = require("../common/CaseInsensitiveTagMap");
/**
* EBML Tag map
*/
const ebmlTagMap = {
'segment:title': 'title',
'album:ARTIST': 'albumartist',
'album:ARTISTSORT': 'albumartistsort',
'album:TITLE': 'album',
'album:DATE_RECORDED': 'originaldate',
'album:PART_NUMBER': 'disk',
'album:TOTAL_PARTS': 'totaltracks',
'track:ARTIST': 'artist',
'track:ARTISTSORT': 'artistsort',
'track:TITLE': 'title',
'track:PART_NUMBER': 'track',
'track:MUSICBRAINZ_TRACKID': 'musicbrainz_recordingid',
'track:MUSICBRAINZ_ALBUMID': 'musicbrainz_albumid',
'track:MUSICBRAINZ_ARTISTID': 'musicbrainz_artistid',
'track:PUBLISHER': 'label',
'track:GENRE': 'genre',
'track:ENCODER': 'encodedby',
'track:ENCODER_OPTIONS': 'encodersettings',
'edition:TOTAL_PARTS': 'totaldiscs',
picture: 'picture'
};
class MatroskaTagMapper extends CaseInsensitiveTagMap_1.CaseInsensitiveTagMap {
constructor() {
super(['matroska'], ebmlTagMap);
}
}
exports.MatroskaTagMapper = MatroskaTagMapper;
+175
View File
@@ -0,0 +1,175 @@
/// <reference types="node" />
export interface IHeader {
id: number;
len: number;
}
export declare enum DataType {
string = 0,
uint = 1,
uid = 2,
bool = 3,
binary = 4,
float = 5
}
export interface IElementType<T> {
readonly name: string;
readonly value?: DataType;
readonly container?: IContainerType;
readonly multiple?: boolean;
}
export interface IContainerType {
[id: number]: IElementType<string | number | boolean | Buffer>;
}
export interface ITree {
[name: string]: string | number | boolean | Buffer | ITree | ITree[];
}
export interface ISeekHead {
id?: Buffer;
position?: number;
}
export interface IMetaSeekInformation {
seekHeads: ISeekHead[];
}
export interface ISegmentInformation {
uid?: Buffer;
timecodeScale?: number;
duration?: number;
dateUTC?: number;
title?: string;
muxingApp?: string;
writingApp?: string;
}
export interface ITrackEntry {
uid?: Buffer;
trackNumber?: number;
trackType?: TrackType;
audio?: ITrackAudio;
video?: ITrackVideo;
flagEnabled?: boolean;
flagDefault?: boolean;
flagLacing?: boolean;
defaultDuration?: number;
trackTimecodeScale?: number;
name?: string;
language?: string;
codecID?: string;
codecPrivate?: Buffer;
codecName?: string;
codecSettings?: string;
codecInfoUrl?: string;
codecDownloadUrl?: string;
codecDecodeAll?: string;
trackOverlay?: string;
}
export interface ITrackVideo {
flagInterlaced?: boolean;
stereoMode?: number;
pixelWidth?: number;
pixelHeight?: number;
displayWidth?: number;
displayHeight?: number;
displayUnit?: number;
aspectRatioType?: number;
colourSpace?: Buffer;
gammaValue?: number;
}
export interface ITrackAudio {
samplingFrequency?: number;
outputSamplingFrequency?: number;
channels?: number;
channelPositions?: Buffer;
bitDepth?: number;
}
export interface ICuePoint {
cueTime?: number;
cueTrackPositions: ICueTrackPosition[];
}
export interface ICueTrackPosition {
cueTrack?: number;
cueClusterPosition?: number;
cueBlockNumber?: number;
cueCodecState?: number;
cueReference?: ICueReference;
}
export interface ICueReference {
cueRefTime?: number;
cueRefCluster?: number;
cueRefNumber?: number;
cueRefCodecState?: number;
}
export interface ISimpleTag {
name?: string;
string?: string;
binary?: Buffer;
language?: string;
default?: boolean;
}
export declare enum TargetType {
shot = 10,
scene = 20,
track = 30,
part = 40,
album = 50,
edition = 60,
collection = 70
}
export declare enum TrackType {
video = 1,
audio = 2,
complex = 3,
logo = 4,
subtitle = 17,
button = 18,
control = 32
}
export interface ITarget {
trackUID?: Buffer;
chapterUID?: Buffer;
attachmentUID?: Buffer;
targetTypeValue?: TargetType;
targetType?: string;
}
export interface ITag {
target: ITarget;
simpleTags: ISimpleTag[];
}
export interface ITags {
tag: ITag[];
}
export interface ITrackElement {
entries?: ITrackEntry[];
}
export interface IAttachmedFile {
description?: string;
name: string;
mimeType: string;
data: Buffer;
uid: string;
}
export interface IAttachments {
attachedFiles?: IAttachmedFile[];
}
export interface IMatroskaSegment {
metaSeekInfo?: IMetaSeekInformation;
seekHeads?: ISeekHead[];
info?: ISegmentInformation;
tracks?: ITrackElement;
tags?: ITags;
cues?: ICuePoint[];
attachments?: IAttachments;
}
export interface IEbmlElements {
version?: number;
readVersion?: number;
maxIDWidth?: number;
maxSizeWidth?: number;
docType?: string;
docTypeVersion?: number;
docTypeReadVersion?: number;
}
export interface IEbmlDoc {
ebml: IEbmlElements;
}
export interface IMatroskaDoc extends IEbmlDoc {
segment: IMatroskaSegment;
}
+32
View File
@@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TrackType = exports.TargetType = exports.DataType = void 0;
var DataType;
(function (DataType) {
DataType[DataType["string"] = 0] = "string";
DataType[DataType["uint"] = 1] = "uint";
DataType[DataType["uid"] = 2] = "uid";
DataType[DataType["bool"] = 3] = "bool";
DataType[DataType["binary"] = 4] = "binary";
DataType[DataType["float"] = 5] = "float";
})(DataType = exports.DataType || (exports.DataType = {}));
var TargetType;
(function (TargetType) {
TargetType[TargetType["shot"] = 10] = "shot";
TargetType[TargetType["scene"] = 20] = "scene";
TargetType[TargetType["track"] = 30] = "track";
TargetType[TargetType["part"] = 40] = "part";
TargetType[TargetType["album"] = 50] = "album";
TargetType[TargetType["edition"] = 60] = "edition";
TargetType[TargetType["collection"] = 70] = "collection";
})(TargetType = exports.TargetType || (exports.TargetType = {}));
var TrackType;
(function (TrackType) {
TrackType[TrackType["video"] = 1] = "video";
TrackType[TrackType["audio"] = 2] = "audio";
TrackType[TrackType["complex"] = 3] = "complex";
TrackType[TrackType["logo"] = 4] = "logo";
TrackType[TrackType["subtitle"] = 17] = "subtitle";
TrackType[TrackType["button"] = 18] = "button";
TrackType[TrackType["control"] = 32] = "control";
})(TrackType = exports.TrackType || (exports.TrackType = {}));