Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const dataAtom = await this.tokenizer.readToken(new AtomToken.DataAtom(metaAtom.header.length - AtomToken.Header.len));
if (dataAtom.type.set !== 0) {
throw new Error('Unsupported type-set != 0: ' + dataAtom.type.set);
}
// Use well-known-type table
// Ref: https://developer.apple.com/library/content/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW35
switch (dataAtom.type.type) {
case 0: // reserved: Reserved for use where no type needs to be indicated
switch (tagKey) {
case 'trkn':
case 'disk':
const num = Token.UINT8.get(dataAtom.value, 3);
const of = Token.UINT8.get(dataAtom.value, 5);
// console.log(" %s[data] = %s/%s", tagKey, num, of);
this.addTag(tagKey, num + '/' + of);
break;
case 'gnre':
const genreInt = Token.UINT8.get(dataAtom.value, 1);
const genreStr = Genres[genreInt - 1];
// console.log(" %s[data] = %s", tagKey, genreStr);
this.addTag(tagKey, genreStr);
break;
default:
// console.log(" reserved-data: name=%s, len=%s, set=%s, type=%s, locale=%s, value{ hex=%s, ascii=%s }",
// header.name, header.length, dataAtom.type.set, dataAtom.type.type, dataAtom.locale, dataAtom.value.toString('hex'), dataAtom.value.toString('ascii'));
}
break;
case 'CMPR': // 3.2.3 Compression Type Chunk
const compressionIdCode = (await this.tokenizer.readToken(FourCcToken)).trim();
const count = await this.tokenizer.readToken(Token.UINT8);
const compressionName = await this.tokenizer.readToken(new Token.StringType(count, 'ascii'));
if (compressionIdCode === 'DSD') {
this.metadata.setFormat('lossless', true);
this.metadata.setFormat('bitsPerSample', 1);
}
this.metadata.setFormat('codec', `${compressionIdCode} (${compressionName})`);
break;
case 'ABSS': // 3.2.4 Absolute Start Time Chunk
const hours = await this.tokenizer.readToken(Token.UINT16_BE);
const minutes = await this.tokenizer.readToken(Token.UINT8);
const seconds = await this.tokenizer.readToken(Token.UINT8);
const samples = await this.tokenizer.readToken(Token.UINT32_BE);
debug(`ABSS ${hours}:${minutes}:${seconds}.${samples}`);
break;
case 'LSCO': // 3.2.5 Loudspeaker Configuration Chunk
const lsConfig = await this.tokenizer.readToken(Token.UINT16_BE);
debug(`LSCO lsConfig=${lsConfig}`);
break;
case 'COMT':
default:
debug(`Unknown sound-property-chunk[ID=${sndPropHeader.chunkID}, size=${sndPropHeader.chunkSize}]`);
await this.tokenizer.ignore(sndPropHeader.chunkSize);
}
const remaining = sndPropHeader.chunkSize - (this.tokenizer.position - p0);
if (remaining > 0) {
switch (sndPropHeader.chunkID.trim()) {
case 'FS': // 3.2.1 Sample Rate Chunk
const sampleRate = await this.tokenizer.readToken(Token.UINT32_BE);
this.metadata.setFormat('sampleRate', sampleRate);
break;
case 'CHNL': // 3.2.2 Channels Chunk
const numChannels = await this.tokenizer.readToken(Token.UINT16_BE);
this.metadata.setFormat('numberOfChannels', numChannels);
await this.handleChannelChunks(sndPropHeader.chunkSize - Token.UINT16_BE.len);
break;
case 'CMPR': // 3.2.3 Compression Type Chunk
const compressionIdCode = (await this.tokenizer.readToken(FourCcToken)).trim();
const count = await this.tokenizer.readToken(Token.UINT8);
const compressionName = await this.tokenizer.readToken(new Token.StringType(count, 'ascii'));
if (compressionIdCode === 'DSD') {
this.metadata.setFormat('lossless', true);
this.metadata.setFormat('bitsPerSample', 1);
}
this.metadata.setFormat('codec', `${compressionIdCode} (${compressionName})`);
break;
case 'ABSS': // 3.2.4 Absolute Start Time Chunk
const hours = await this.tokenizer.readToken(Token.UINT16_BE);
const minutes = await this.tokenizer.readToken(Token.UINT8);
const seconds = await this.tokenizer.readToken(Token.UINT8);
const samples = await this.tokenizer.readToken(Token.UINT32_BE);
debug(`ABSS ${hours}:${minutes}:${seconds}.${samples}`);
break;
get: (buf, off): IId3v1Header => {
const header = new Id3v1StringType(3).get(buf, off);
return header === "TAG" ? {
header,
title: new Id3v1StringType(30).get(buf, off + 3),
artist: new Id3v1StringType(30).get(buf, off + 33),
album: new Id3v1StringType(30).get(buf, off + 63),
year: new Id3v1StringType(4).get(buf, off + 93),
comment: new Id3v1StringType(28).get(buf, off + 97),
// ID3v1.1 separator for track
zeroByte: Token.UINT8.get(buf, off + 127),
// track: ID3v1.1 field added by Michael Mutschler
track: Token.UINT8.get(buf, off + 126),
genre: Token.UINT8.get(buf, off + 127)
} : null;
}
};
get: (buf, off): IId3v1Header => {
const header = new Id3v1StringType(3).get(buf, off);
return header === "TAG" ? {
header,
title: new Id3v1StringType(30).get(buf, off + 3),
artist: new Id3v1StringType(30).get(buf, off + 33),
album: new Id3v1StringType(30).get(buf, off + 63),
year: new Id3v1StringType(4).get(buf, off + 93),
comment: new Id3v1StringType(28).get(buf, off + 97),
// ID3v1.1 separator for track
zeroByte: Token.UINT8.get(buf, off + 127),
// track: ID3v1.1 field added by Michael Mutschler
track: Token.UINT8.get(buf, off + 126),
genre: Token.UINT8.get(buf, off + 127)
} : null;
}
};
get: (buf, off) => {
return {
crc: Token.UINT32_LE.get(buf, off),
streamVersion: Token.UINT8.get(buf, off + 4)
};
}
};
private async readVariableSizeField(len: number = 1, hb: number = 0): Promise {
let n = await this.tokenizer.readNumber(Token.UINT8);
if ((n & 0x80) === 0) {
return {len, value: hb + n};
}
n &= 0x7F;
n += hb;
return this.readVariableSizeField(len + 1, n << 7);
}
}
private async parseEbml(level: number, posDone: number): Promise {
const ebml: IEBML = {segments: []};
while (this.tokenizer.position < posDone) {
const e = await this.readElement();
switch (e.id) {
case 0x18538067:
const segment = await this.parseSegment(level + 1, this.tokenizer.position + e.len);
const duration = segment.segmentInfo.duration * segment.segmentInfo.timecodeScale / 1000000000;
this.metadata.setFormat('duration', duration);
ebml.segments.push(segment);
break;
case 0x4286:
ebml.version = await this.tokenizer.readNumber(Token.UINT8);
break;
case 0x42f7:
ebml.readVersion = await this.readUint(e);
break;
case 0x42f2:
ebml.maxIDWidth = await this.readUint(e);
break;
case 0x42f3:
ebml.maxSizeWidth = await this.readUint(e);
break;
case 0x4282:
ebml.docType = await this.readString(e);
break;
case 0x4287:
ebml.docTypeVersion = await this.readUint(e);
break;