UNPKG

id3-parser

Version:
55 lines (48 loc) 1.86 kB
import GENRES from '../constants/genres'; import { IBytes, IID3V1Tag } from '../interface'; import { readBytesToUTF8 } from '../bytesUtil'; const V1_MIN_LENGTH = 128; /** * Parse ID3v1 metadata from binary bytes. * @description * ID3v1 tag occupies 128 bytes, beginning with the string TAG 128 bytes * from the end of the file. * * And the format is like: header(3) + title(30) + artist(30) + * album(30) + year(4) + comment(30) + genre(1). * * And extended tag is only supported by few programs, so we ignore it. * @param bytes binary bytes. */ export default function parseV1Data(bytes: IBytes): false | IID3V1Tag { if (!bytes || bytes.length < V1_MIN_LENGTH) { return false; } bytes = bytes.slice(bytes.length - V1_MIN_LENGTH); const tags: IID3V1Tag = { version: { major: 1, minor: 0, }, }; const flag = readBytesToUTF8(bytes, 3); if (flag !== 'TAG') { return false; } // Strings are either space- or zero-padded. So remove them. const reWhiteSpace = /(^[\s0]+|[\s0]+$)/; tags.title = readBytesToUTF8(bytes.slice(3), 30).replace(reWhiteSpace, ''); tags.artist = readBytesToUTF8(bytes.slice(33), 30).replace(reWhiteSpace, ''); tags.album = readBytesToUTF8(bytes.slice(63), 30).replace(reWhiteSpace, ''); tags.year = readBytesToUTF8(bytes.slice(93), 4).replace(reWhiteSpace, ''); // If there is a zero byte at [125], the comment is 28 bytes and the remaining 2 are [0, trackno] if (bytes[125] === 0) { tags.comments = readBytesToUTF8(bytes.slice(97), 28).replace(reWhiteSpace, ''); tags.version.minor = 1; tags.track = bytes[126]; } else { tags.comments = readBytesToUTF8(bytes.slice(97), 30).replace(reWhiteSpace, ''); } tags.genre = GENRES[bytes[127]] || ''; return tags; }