Software: Apache. PHP/8.1.30 uname -a: Linux server1.tuhinhossain.com 5.15.0-163-generic #173-Ubuntu SMP Tue Oct 14 17:51:00 UTC uid=1002(picotech) gid=1003(picotech) groups=1003(picotech),0(root) Safe-mode: OFF (not secure) /home/picotech/domains/wa.picotech.app/public_html/node_modules/music-metadata/lib/id3v2/ drwxr-xr-x | |
| Viewing file: Select action/file-type: "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FrameParser = exports.parseGenre = void 0;
const debug_1 = require("debug");
const Token = require("token-types");
const util = require("../common/Util");
const ID3v2Token_1 = require("./ID3v2Token");
const ID3v1Parser_1 = require("../id3v1/ID3v1Parser");
const debug = (0, debug_1.default)('music-metadata:id3v2:frame-parser');
const defaultEnc = 'latin1'; // latin1 == iso-8859-1;
function parseGenre(origVal) {
// match everything inside parentheses
const genres = [];
let code;
let word = '';
for (const c of origVal) {
if (typeof code === 'string') {
if (c === '(' && code === '') {
word += '(';
code = undefined;
}
else if (c === ')') {
if (word !== '') {
genres.push(word);
word = '';
}
const genre = parseGenreCode(code);
if (genre) {
genres.push(genre);
}
code = undefined;
}
else
code += c;
}
else if (c === '(') {
code = '';
}
else {
word += c;
}
}
if (word) {
if (genres.length === 0 && word.match(/^\d*$/)) {
word = ID3v1Parser_1.Genres[word];
}
genres.push(word);
}
return genres;
}
exports.parseGenre = parseGenre;
function parseGenreCode(code) {
if (code === 'RX')
return 'Remix';
if (code === 'CR')
return 'Cover';
if (code.match(/^\d*$/)) {
return ID3v1Parser_1.Genres[code];
}
}
class FrameParser {
/**
* Create id3v2 frame parser
* @param major - Major version, e.g. (4) for id3v2.4
* @param warningCollector - Used to collect decode issue
*/
constructor(major, warningCollector) {
this.major = major;
this.warningCollector = warningCollector;
}
readData(uint8Array, type, includeCovers) {
if (uint8Array.length === 0) {
this.warningCollector.addWarning(`id3v2.${this.major} header has empty tag type=${type}`);
return;
}
const { encoding, bom } = ID3v2Token_1.TextEncodingToken.get(uint8Array, 0);
const length = uint8Array.length;
let offset = 0;
let output = []; // ToDo
const nullTerminatorLength = FrameParser.getNullTerminatorLength(encoding);
let fzero;
const out = {};
debug(`Parsing tag type=${type}, encoding=${encoding}, bom=${bom}`);
switch (type !== 'TXXX' && type[0] === 'T' ? 'T*' : type) {
case 'T*': // 4.2.1. Text information frames - details
case 'IPLS': // v2.3: Involved people list
case 'MVIN':
case 'MVNM':
case 'PCS':
case 'PCST':
let text;
try {
text = util.decodeString(uint8Array.slice(1), encoding).replace(/\x00+$/, '');
}
catch (error) {
this.warningCollector.addWarning(`id3v2.${this.major} type=${type} header has invalid string value: ${error.message}`);
}
switch (type) {
case 'TMCL': // Musician credits list
case 'TIPL': // Involved people list
case 'IPLS': // Involved people list
output = this.splitValue(type, text);
output = FrameParser.functionList(output);
break;
case 'TRK':
case 'TRCK':
case 'TPOS':
output = text;
break;
case 'TCOM':
case 'TEXT':
case 'TOLY':
case 'TOPE':
case 'TPE1':
case 'TSRC':
// id3v2.3 defines that TCOM, TEXT, TOLY, TOPE & TPE1 values are separated by /
output = this.splitValue(type, text);
break;
case 'TCO':
case 'TCON':
output = this.splitValue(type, text).map(v => parseGenre(v)).reduce((acc, val) => acc.concat(val), []);
break;
case 'PCS':
case 'PCST':
// TODO: Why `default` not results `1` but `''`?
output = this.major >= 4 ? this.splitValue(type, text) : [text];
output = (Array.isArray(output) && output[0] === '') ? 1 : 0;
break;
default:
output = this.major >= 4 ? this.splitValue(type, text) : [text];
}
break;
case 'TXXX':
output = FrameParser.readIdentifierAndData(uint8Array, offset + 1, length, encoding);
output = {
description: output.id,
text: this.splitValue(type, util.decodeString(output.data, encoding).replace(/\x00+$/, ''))
};
break;
case 'PIC':
case 'APIC':
if (includeCovers) {
const pic = {};
offset += 1;
switch (this.major) {
case 2:
pic.format = util.decodeString(uint8Array.slice(offset, offset + 3), 'latin1'); // 'latin1'; // latin1 == iso-8859-1;
offset += 3;
break;
case 3:
case 4:
fzero = util.findZero(uint8Array, offset, length, defaultEnc);
pic.format = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
offset = fzero + 1;
break;
default:
throw new Error('Warning: unexpected major versionIndex: ' + this.major);
}
pic.format = FrameParser.fixPictureMimeType(pic.format);
pic.type = ID3v2Token_1.AttachedPictureType[uint8Array[offset]];
offset += 1;
fzero = util.findZero(uint8Array, offset, length, encoding);
pic.description = util.decodeString(uint8Array.slice(offset, fzero), encoding);
offset = fzero + nullTerminatorLength;
pic.data = Buffer.from(uint8Array.slice(offset, length));
output = pic;
}
break;
case 'CNT':
case 'PCNT':
output = Token.UINT32_BE.get(uint8Array, 0);
break;
case 'SYLT':
// skip text encoding (1 byte),
// language (3 bytes),
// time stamp format (1 byte),
// content tagTypes (1 byte),
// content descriptor (1 byte)
offset += 7;
output = [];
while (offset < length) {
const txt = uint8Array.slice(offset, offset = util.findZero(uint8Array, offset, length, encoding));
offset += 5; // push offset forward one + 4 byte timestamp
output.push(util.decodeString(txt, encoding));
}
break;
case 'ULT':
case 'USLT':
case 'COM':
case 'COMM':
offset += 1;
out.language = util.decodeString(uint8Array.slice(offset, offset + 3), defaultEnc);
offset += 3;
fzero = util.findZero(uint8Array, offset, length, encoding);
out.description = util.decodeString(uint8Array.slice(offset, fzero), encoding);
offset = fzero + nullTerminatorLength;
out.text = util.decodeString(uint8Array.slice(offset, length), encoding).replace(/\x00+$/, '');
output = [out];
break;
case 'UFID':
output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
output = { owner_identifier: output.id, identifier: output.data };
break;
case 'PRIV': // private frame
output = FrameParser.readIdentifierAndData(uint8Array, offset, length, defaultEnc);
output = { owner_identifier: output.id, data: output.data };
break;
case 'POPM': // Popularimeter
fzero = util.findZero(uint8Array, offset, length, defaultEnc);
const email = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
offset = fzero + 1;
const dataLen = length - offset;
output = {
email,
rating: Token.UINT8.get(uint8Array, offset),
counter: dataLen >= 5 ? Token.UINT32_BE.get(uint8Array, offset + 1) : undefined
};
break;
case 'GEOB': { // General encapsulated object
fzero = util.findZero(uint8Array, offset + 1, length, encoding);
const mimeType = util.decodeString(uint8Array.slice(offset + 1, fzero), defaultEnc);
offset = fzero + 1;
fzero = util.findZero(uint8Array, offset, length - offset, encoding);
const filename = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
offset = fzero + 1;
fzero = util.findZero(uint8Array, offset, length - offset, encoding);
const description = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
output = {
type: mimeType,
filename,
description,
data: uint8Array.slice(offset + 1, length)
};
break;
}
// W-Frames:
case 'WCOM':
case 'WCOP':
case 'WOAF':
case 'WOAR':
case 'WOAS':
case 'WORS':
case 'WPAY':
case 'WPUB':
// Decode URL
output = util.decodeString(uint8Array.slice(offset, fzero), defaultEnc);
break;
case 'WXXX': {
// Decode URL
fzero = util.findZero(uint8Array, offset + 1, length, encoding);
const description = util.decodeString(uint8Array.slice(offset + 1, fzero), encoding);
offset = fzero + (encoding === 'utf16le' ? 2 : 1);
output = { description, url: util.decodeString(uint8Array.slice(offset, length), defaultEnc) };
break;
}
case 'WFD':
case 'WFED':
output = util.decodeString(uint8Array.slice(offset + 1, util.findZero(uint8Array, offset + 1, length, encoding)), encoding);
break;
case 'MCDI': {
// Music CD identifier
output = uint8Array.slice(0, length);
break;
}
default:
debug('Warning: unsupported id3v2-tag-type: ' + type);
break;
}
return output;
}
static fixPictureMimeType(pictureType) {
pictureType = pictureType.toLocaleLowerCase();
switch (pictureType) {
case 'jpg':
return 'image/jpeg';
case 'png':
return 'image/png';
}
return pictureType;
}
/**
* Converts TMCL (Musician credits list) or TIPL (Involved people list)
* @param entries
*/
static functionList(entries) {
const res = {};
for (let i = 0; i + 1 < entries.length; i += 2) {
const names = entries[i + 1].split(',');
res[entries[i]] = res.hasOwnProperty(entries[i]) ? res[entries[i]].concat(names) : names;
}
return res;
}
/**
* id3v2.4 defines that multiple T* values are separated by 0x00
* id3v2.3 defines that TCOM, TEXT, TOLY, TOPE & TPE1 values are separated by /
* @param tag - Tag name
* @param text - Concatenated tag value
* @returns Split tag value
*/
splitValue(tag, text) {
let values;
if (this.major < 4) {
values = text.split(/\x00/g);
if (values.length > 1) {
this.warningCollector.addWarning(`ID3v2.${this.major} ${tag} uses non standard null-separator.`);
}
else {
values = text.split(/\//g);
}
}
else {
values = text.split(/\x00/g);
}
return FrameParser.trimArray(values);
}
static trimArray(values) {
return values.map(value => value.replace(/\x00+$/, '').trim());
}
static readIdentifierAndData(uint8Array, offset, length, encoding) {
const fzero = util.findZero(uint8Array, offset, length, encoding);
const id = util.decodeString(uint8Array.slice(offset, fzero), encoding);
offset = fzero + FrameParser.getNullTerminatorLength(encoding);
return { id, data: uint8Array.slice(offset, length) };
}
static getNullTerminatorLength(enc) {
return enc === 'utf16le' ? 2 : 1;
}
}
exports.FrameParser = FrameParser;
|
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0041 ]-- |