-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to parse audio without lazy loaded parsers? #2280
Comments
Hi @julianpoemp, the dynamic imports is not something what can be changed during runtime. I am sure there configurations in which the dynamic imports do not work in the browser, but here are certainly ways to make this working in the browser. I did actually implement this in favor for of browser usage, to improve initial application loading time. An example of a browser usage (based on Angular): https://audio-tag-analyzer.netlify.app/ |
Hi @Borewit, thank you for your answer. I'm using music-metadata in one of my Angular apps, too. Building the Angular app with the dynamic imports provided by music-metadata, there are no issues. The problem is as soon as you want to create a library with ESM, CJS, UMD, and IFEE support, you can't build it because of various issues originated by the dynamic imports. If you are interested in details of the problem I can create an example repository for reproduction. In TS projects the compiler recognizes if a function uses dynamic imports or not. So it should be possible add a version of the parse function that accepts a parser class as argument and uses it instead of a lazy loaded parser. Providing this would make music-metadata more open to a bigger audience. In a local repository I tested building music-metadata with vite with static parsers and changed the code as follows: /**
* Parse Web API File
* Requires Blob to be able to stream using a ReadableStreamBYOBReader, only available since Node.js ≥ 20
* @param blob - Blob to parse
* @param options - Parsing options
* @returns Metadata
*/
export async function parseBlob(
blob: Blob,
parserClass: any,
options: IOptions = {}
): Promise<IAudioMetadata> {
const fileInfo: IFileInfo = { mimeType: blob.type, size: blob.size };
if (blob instanceof File) {
fileInfo.path = (blob as File).name;
}
return parseWebStream(
blob.stream() as AnyWebByteStream,
parserClass,
fileInfo,
options
);
}
/**
* Parse audio from Web Stream.Readable
* @param webStream - WebStream to read the audio track from
* @param options - Parsing options
* @param fileInfo - File information object or MIME-type string
* @returns Metadata
*/
export function parseWebStream(
webStream: AnyWebByteStream,
parserClass: any,
fileInfo?: IFileInfo | string,
options: IOptions = {}
): Promise<IAudioMetadata> {
return parse(
fromWebStream(webStream, {
fileInfo:
typeof fileInfo === 'string' ? { mimeType: fileInfo } : fileInfo,
}),
parserClass,
options
);
}
async function parse(
tokenizer: ITokenizer,
parserClass: any,
opts?: IOptions
): Promise<IAudioMetadata> {
// Parser found, execute parser
const metadata = new MetadataCollector(opts);
const parser = new parserClass(metadata, tokenizer, opts);
await parser.parse();
return metadata.toCommonMetadata();
} That allows to use it like that: if(extension === ".mp3") {
const info = await parseBlob(blob, MpegParser, fileInfo);
} |
While dynamic imports do add complexity for module bundlers, I believe the actual issue belongs to the module blunder or how it is configured. Static imports in some modules don’t prevent lazy loading in others, so the root cause seems more related to the bundler's handling of these cases, not this module. Given that ESM is the official JavaScript module standard, moving towards it seems like the clear solution. If this is a runtime issue, a potential solution could be to introduce a ParserFactory. By default, it would use dynamic imports, but could be overridden with a static parser factory that directly loads the parser, avoiding dynamic imports. If the issue is related to TypeScript's compile-time handling of dynamic imports, solving it might be more difficult. Sure, migrating to static imports might work, but I’m hesitant to take that route as it would limit flexibility and modern practices. |
It's not a runtime issue, it's a compile time issue because of vite handling dynamic imports for umd. In my vite config I have to add Thank you very much! |
Has the question been asked before?
Question
Hi,
I would like to use music-metadata in one of my libraries. Because there are issues with the lazy loaded parsers, I want to use
parseBlob
for web (browser) without lazy loading. Is there any way to archive this?Cheers,
Julian
The text was updated successfully, but these errors were encountered: