music-metadata
Advanced tools
Comparing version 10.6.0 to 10.6.1
import * as strtok3 from 'strtok3'; | ||
import type { IOptions, IRandomReader, IApeHeader } from '../type.js'; | ||
import type { IOptions, IApeHeader } from '../type.js'; | ||
import type { INativeMetadataCollector } from '../common/MetadataCollector.js'; | ||
import { BasicParser } from '../common/BasicParser.js'; | ||
import { type IFooter, type IHeader } from './APEv2Token.js'; | ||
import type { IRandomAccessTokenizer } from 'strtok3'; | ||
declare const ApeContentError_base: { | ||
@@ -30,6 +31,6 @@ new (message: string): { | ||
* Calculates the APEv1 / APEv2 first field offset | ||
* @param reader | ||
* @param tokenizer | ||
* @param offset | ||
*/ | ||
static findApeFooterOffset(reader: IRandomReader, offset: number): Promise<IApeHeader | undefined>; | ||
static findApeFooterOffset(tokenizer: IRandomAccessTokenizer, offset: number): Promise<IApeHeader | undefined>; | ||
private static parseTagFooter; | ||
@@ -36,0 +37,0 @@ private ape; |
@@ -35,9 +35,11 @@ import initDebug from 'debug'; | ||
* Calculates the APEv1 / APEv2 first field offset | ||
* @param reader | ||
* @param tokenizer | ||
* @param offset | ||
*/ | ||
static async findApeFooterOffset(reader, offset) { | ||
static async findApeFooterOffset(tokenizer, offset) { | ||
// Search for APE footer header at the end of the file | ||
const apeBuf = new Uint8Array(TagFooter.len); | ||
await reader.randomRead(apeBuf, 0, TagFooter.len, offset - TagFooter.len); | ||
const position = tokenizer.position; | ||
await tokenizer.readBuffer(apeBuf, { position: offset - TagFooter.len }); | ||
tokenizer.setPosition(position); | ||
const tagFooter = TagFooter.get(apeBuf, 0); | ||
@@ -44,0 +46,0 @@ if (tagFooter.ID === 'APETAGEX') { |
/** | ||
* Primary entry point, Node.js specific entry point is MusepackParser.ts | ||
*/ | ||
import { type AnyWebByteStream, type IFileInfo, type ITokenizer } from 'strtok3'; | ||
import type { IAudioMetadata, INativeTagDict, IOptions, IPicture, IPrivateOptions, IRandomReader, ITag } from './type.js'; | ||
import { type AnyWebByteStream, type IFileInfo, type ITokenizer, type IRandomAccessTokenizer } from 'strtok3'; | ||
import type { IAudioMetadata, INativeTagDict, IOptions, IPicture, IPrivateOptions, ITag } from './type.js'; | ||
export type { IFileInfo } from 'strtok3'; | ||
@@ -59,3 +59,3 @@ export { type IAudioMetadata, type IOptions, type ITag, type INativeTagDict, type ICommonTagsResult, type IFormat, type IPicture, type IRatio, type IChapter, type ILyricsTag, LyricsContentType, TimestampFormat, IMetadataEventTag, IMetadataEvent } from './type.js'; | ||
export declare function selectCover(pictures?: IPicture[]): IPicture | null; | ||
export declare function scanAppendingHeaders(randomReader: IRandomReader, options?: IPrivateOptions): Promise<void>; | ||
export declare function scanAppendingHeaders(tokenizer: IRandomAccessTokenizer, options?: IPrivateOptions): Promise<void>; | ||
export declare function loadMusicMetadata(): Promise<typeof import('music-metadata')>; |
@@ -6,3 +6,2 @@ /** | ||
import { ParserFactory } from './ParserFactory.js'; | ||
import { RandomUint8ArrayReader } from './common/RandomUint8ArrayReader.js'; | ||
import { APEv2Parser } from './apev2/APEv2Parser.js'; | ||
@@ -45,4 +44,2 @@ import { hasID3v1Header } from './id3v1/ID3v1Parser.js'; | ||
export async function parseBuffer(uint8Array, fileInfo, options = {}) { | ||
const bufferReader = new RandomUint8ArrayReader(uint8Array); | ||
await scanAppendingHeaders(bufferReader, options); | ||
const tokenizer = fromBuffer(uint8Array, { fileInfo: typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo }); | ||
@@ -96,10 +93,11 @@ return parseFromTokenizer(tokenizer, options); | ||
} | ||
export async function scanAppendingHeaders(randomReader, options = {}) { | ||
let apeOffset = randomReader.fileSize; | ||
if (await hasID3v1Header(randomReader)) { | ||
export async function scanAppendingHeaders(tokenizer, options = {}) { | ||
let apeOffset = tokenizer.fileInfo.size; | ||
if (await hasID3v1Header(tokenizer)) { | ||
apeOffset -= 128; | ||
const lyricsLen = await getLyricsHeaderLength(randomReader); | ||
const lyricsLen = await getLyricsHeaderLength(tokenizer); | ||
apeOffset -= lyricsLen; | ||
} | ||
options.apeHeader = await APEv2Parser.findApeFooterOffset(randomReader, apeOffset); | ||
options.apeHeader = await APEv2Parser.findApeFooterOffset(tokenizer, apeOffset); | ||
} | ||
//# sourceMappingURL=core.js.map |
@@ -1,4 +0,4 @@ | ||
import type { ITokenizer } from 'strtok3'; | ||
import type { IRandomAccessTokenizer, ITokenizer } from 'strtok3'; | ||
import { BasicParser } from '../common/BasicParser.js'; | ||
import type { IPrivateOptions, IRandomReader } from '../type.js'; | ||
import type { IPrivateOptions } from '../type.js'; | ||
import type { INativeMetadataCollector } from '../common/MetadataCollector.js'; | ||
@@ -17,2 +17,2 @@ /** | ||
} | ||
export declare function hasID3v1Header(reader: IRandomReader): Promise<boolean>; | ||
export declare function hasID3v1Header(tokenizer: IRandomAccessTokenizer): Promise<boolean>; |
@@ -127,6 +127,8 @@ import initDebug from 'debug'; | ||
} | ||
export async function hasID3v1Header(reader) { | ||
if (reader.fileSize >= 128) { | ||
export async function hasID3v1Header(tokenizer) { | ||
if (tokenizer.fileInfo.size >= 128) { | ||
const tag = new Uint8Array(3); | ||
await reader.randomRead(tag, 0, tag.length, reader.fileSize - 128); | ||
const position = tokenizer.position; | ||
await tokenizer.readBuffer(tag, { position: tokenizer.fileInfo.size - 128 }); | ||
tokenizer.setPosition(position); // Restore tokenizer position | ||
return new TextDecoder('latin1').decode(tag) === 'TAG'; | ||
@@ -133,0 +135,0 @@ } |
@@ -6,5 +6,4 @@ /** | ||
import initDebug from 'debug'; | ||
import { parseFromTokenizer, scanAppendingHeaders } from './core.js'; | ||
import { parseFromTokenizer, } from './core.js'; | ||
import { ParserFactory } from './ParserFactory.js'; | ||
import { RandomFileReader } from './common/RandomFileReader.js'; | ||
export * from './core.js'; | ||
@@ -32,9 +31,2 @@ const debug = initDebug('music-metadata:parser'); | ||
const fileTokenizer = await fromFile(filePath); | ||
const fileReader = await RandomFileReader.init(filePath, fileTokenizer.fileInfo.size); | ||
try { | ||
await scanAppendingHeaders(fileReader, options); | ||
} | ||
finally { | ||
await fileReader.close(); | ||
} | ||
const parserFactory = new ParserFactory(); | ||
@@ -41,0 +33,0 @@ try { |
@@ -1,3 +0,3 @@ | ||
import type { IRandomReader } from '../type.js'; | ||
import type { IRandomAccessTokenizer } from 'strtok3'; | ||
export declare const endTag2 = "LYRICS200"; | ||
export declare function getLyricsHeaderLength(reader: IRandomReader): Promise<number>; | ||
export declare function getLyricsHeaderLength(tokenizer: IRandomAccessTokenizer): Promise<number>; |
export const endTag2 = 'LYRICS200'; | ||
export async function getLyricsHeaderLength(reader) { | ||
if (reader.fileSize >= 143) { | ||
export async function getLyricsHeaderLength(tokenizer) { | ||
const fileSize = tokenizer.fileInfo.size; | ||
if (fileSize >= 143) { | ||
const buf = new Uint8Array(15); | ||
await reader.randomRead(buf, 0, buf.length, reader.fileSize - 143); | ||
const position = tokenizer.position; | ||
await tokenizer.readBuffer(buf, { position: fileSize - 143 }); | ||
tokenizer.setPosition(position); // Restore position | ||
const txt = new TextDecoder('latin1').decode(buf); | ||
@@ -14,1 +17,2 @@ const tag = txt.slice(6); | ||
} | ||
//# sourceMappingURL=Lyrics3.js.map |
@@ -21,2 +21,3 @@ import { fileTypeFromBuffer } from 'file-type'; | ||
import { amrParserLoader } from './amr/AmrLoader.js'; | ||
import { scanAppendingHeaders } from './core.js'; | ||
const debug = initDebug('music-metadata:parser:factory'); | ||
@@ -57,2 +58,9 @@ export function parseHttpContentType(contentType) { | ||
async parse(tokenizer, parserLoader, opts) { | ||
if (tokenizer.supportsRandomAccess()) { | ||
debug('tokenizer supports random-access, scanning for appending headers'); | ||
await scanAppendingHeaders(tokenizer, opts); | ||
} | ||
else { | ||
debug('tokenizer does not support random-access, cannot scan for appending headers'); | ||
} | ||
if (!parserLoader) { | ||
@@ -59,0 +67,0 @@ const buf = new Uint8Array(4100); |
@@ -598,21 +598,2 @@ import type { TagType } from './common/GenericTagTypes.js'; | ||
export type Observer = (update: IMetadataEvent) => void; | ||
/** | ||
* Provides random data read access | ||
* Used read operations on file of buffers | ||
*/ | ||
export interface IRandomReader { | ||
/** | ||
* Total length of file or buffer | ||
*/ | ||
fileSize: number; | ||
/** | ||
* Read from a given position of an abstracted file or buffer. | ||
* @param {Uint8Array} buffer the buffer that the data will be written to. | ||
* @param {number} offset the offset in the buffer to start writing at. | ||
* @param {number} length an integer specifying the number of bytes to read. | ||
* @param {number} position an argument specifying where to begin reading from in the file. | ||
* @return {Promise<number>} bytes read | ||
*/ | ||
randomRead(buffer: Uint8Array, offset: number, length: number, position: number): Promise<number>; | ||
} | ||
export interface ILyricsText { | ||
@@ -619,0 +600,0 @@ text: string; |
{ | ||
"name": "music-metadata", | ||
"description": "Music metadata parser for Node.js, supporting virtual any audio and tag format.", | ||
"version": "10.6.0", | ||
"version": "10.6.1", | ||
"author": { | ||
@@ -112,4 +112,5 @@ "name": "Borewit", | ||
"file-type": "^19.6.0", | ||
"link": "^2.1.1", | ||
"media-typer": "^1.1.0", | ||
"strtok3": "^9.0.1", | ||
"strtok3": "^9.1.1", | ||
"token-types": "^6.0.0", | ||
@@ -125,15 +126,14 @@ "uint8array-extras": "^1.4.0" | ||
"@types/media-typer": "^1.1.3", | ||
"@types/mocha": "^10.0.9", | ||
"@types/node": "^22.9.0", | ||
"@types/mocha": "^10.0.10", | ||
"@types/node": "^22.10.1", | ||
"c8": "^10.1.2", | ||
"chai": "^5.1.2", | ||
"chai-as-promised": "^8.0.0", | ||
"chai-as-promised": "^8.0.1", | ||
"del-cli": "^6.0.0", | ||
"mime": "^4.0.4", | ||
"mocha": "^10.8.2", | ||
"prettier": "^3.3.3", | ||
"remark-cli": "^12.0.1", | ||
"remark-preset-lint-consistent": "^6.0.0", | ||
"ts-node": "^10.9.2", | ||
"typescript": "^5.6.3" | ||
"typescript": "^5.7.2" | ||
}, | ||
@@ -140,0 +140,0 @@ "engines": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18
519924
9
199
12249
+ Addedlink@^2.1.1
+ Addedlink@2.1.1(transitive)
Updatedstrtok3@^9.1.1