UNPKG

music-metadata

Version:

Music metadata parser for Node.js, supporting virtual any audio and tag format.

75 lines (74 loc) 2.79 kB
import initDebug from 'debug'; import * as Flac from '../../flac/FlacToken.js'; import { FlacParser } from '../../flac/FlacParser.js'; import { FourCcToken } from '../../common/FourCC.js'; import { VorbisPictureToken } from '../vorbis/Vorbis.js'; const debug = initDebug('music-metadata:parser:ogg:theora'); /** * Ref: * - https://xiph.org/flac/ogg_mapping.html */ export class FlacStream { constructor(metadata, options, tokenizer) { this.durationOnLastPage = false; this.metadata = metadata; this.options = options; this.tokenizer = tokenizer; this.flacParser = new FlacParser(this.metadata, this.tokenizer, options); } /** * Vorbis 1 parser * @param header Ogg Page Header * @param pageData Page data */ async parsePage(header, pageData) { if (header.headerType.firstPage) { await this.parseFirstPage(header, pageData); } } calculateDuration() { debug('duration calculation not implemented'); } /** * Parse first Theora Ogg page. the initial identification header packet */ async parseFirstPage(_header, pageData) { debug('First Ogg/FLAC page'); const fourCC = await FourCcToken.get(pageData, 9); if (fourCC.toString() !== 'fLaC') { throw new Error('Invalid FLAC preamble'); } const blockHeader = await Flac.BlockHeader.get(pageData, 13); await this.parseDataBlock(blockHeader, pageData.subarray(13 + Flac.BlockHeader.len)); } async parseDataBlock(blockHeader, pageData) { debug(`blockHeader type=${blockHeader.type}, length=${blockHeader.length}`); switch (blockHeader.type) { case Flac.BlockType.STREAMINFO: { const streamInfo = Flac.BlockStreamInfo.get(pageData, 0); return this.flacParser.processsStreamInfo(streamInfo); } case Flac.BlockType.PADDING: break; case Flac.BlockType.APPLICATION: break; case Flac.BlockType.SEEKTABLE: break; case Flac.BlockType.VORBIS_COMMENT: return this.flacParser.parseComment(pageData); case Flac.BlockType.PICTURE: if (!this.options.skipCovers) { const picture = new VorbisPictureToken(pageData.length).get(pageData, 0); return this.flacParser.addPictureTag(picture); } break; default: this.metadata.addWarning(`Unknown block type: ${blockHeader.type}`); } // Ignore data block return this.tokenizer.ignore(blockHeader.length).then(); } flush() { return Promise.resolve(); } }