Borewit / music-metadata-browser

Browser version of music-metadata parser Supporting a wide range of audio and tag formats.
MIT License
239 stars 21 forks source link

Nuxt 3 compatibility #947

Closed NILAXY closed 3 months ago

NILAXY commented 12 months ago

mmb is throwing an error when trying to parseBlob. Could be fixed by polyfilling, but process.nextTick is also required by mmb but already set with a custom function from Nuxt, so polyfilling it is not an option.

ReferenceError: Buffer is not defined
    at ReadStreamTokenizer.peekToken (AbstractTokenizer.js:37:28)
    at FlacParser.tryReadId3v2Headers (AbstractID3Parser.js:52:48)
    at FlacParser.parseID3v2 (AbstractID3Parser.js:39:20)
    at FlacParser.parse (AbstractID3Parser.js:24:24)
    at parse (ParserFactory.js:38:50)
_stream_readable.js:490 Uncaught (in promise) TypeError: process.nextTick is not a function
    at emitReadable (_stream_readable.js:490:13)
    at addChunk (_stream_readable.js:284:29)
    at readableAddChunk (_stream_readable.js:262:11)
    at Readable.push (_stream_readable.js:228:10)
    at ReadableWebToNodeStream._read (index.js:44:18)
kuankuan2007 commented 11 months ago

This is because your project is running in a browser environment and process and Buffer are in Node.js. Here's how I solved it:

npm i buffer
npm i process

And then register these two globally

import {Buffer} from "buffer"

window.Buffer=Buffer

window.process = require('process')
zefir-git commented 6 months ago

Not sure this has anything to do with Nuxt as I'm not using that and running into the same issue. As a "browser" version of music-metadata, no idea why this uses Node.js dependencies

artshade commented 3 months ago

Related: https://github.com/vitejs/vite/discussions/2785 (Using (Node’s) Buffer in your polymorphic Vite apps...)

zefir-git commented 3 months ago

Should not be using Buffer at all for something that's not made for Node.js. "Vanilla" JavaScript provides ArrayBuffer and Uint8Array (both also available in Node.js, but this library is for browser only anyways).

artshade commented 3 months ago

Should not be using Buffer at all for something that's not made for Node.js. "Vanilla" JavaScript provides ArrayBuffer and Uint8Array (both also available in Node.js, but this library is for browser only anyways).

What would you recommend instead of music-metadata-browser then for Vite and Vue for browser clients?

zefir-git commented 3 months ago

@artshade I don't use this lib anymore, but from what I remember Buffer is only used in a few places (2 or 3?) and the lines using process weren't important and can be removed. One simply needs to switch from Buffer to ArrayBuffer.

The polyfills just port your Node.js Buffer to the standard ES JS ArrayBuffer. This is hacky and a bad practice IMO, although it's just a few lines. Since this repo (being titled "...browser") doesn't need to work inside Node.js (although it still can since ArrayBuffer works in Node.js too), one doesn't need Buffer at all.

I'm personally used to using Buffer in all of my Node.js projects and I think the API is way nicer, but just using ArrayBuffer isn't that much of a big deal and can easily be achieved.

Borewit commented 3 months ago

Buffer is not o

@artshade I don't use this lib anymore, but from what I remember Buffer is only used in a few places (2 or 3?) and the lines using process weren't important and can be removed. One simply needs to switch from Buffer to ArrayBuffer.

Certainly not 2 or 3 places, probably few hundred places.

The polyfills just port your Node.js Buffer to the standard ES JS ArrayBuffer. This is hacky and a bad practice IMO, although it's just a few lines. Since this repo (being titled "...browser") doesn't need to work inside Node.js (although it still can since ArrayBuffer works in Node.js too), one doesn't need Buffer at all.

I'm personally used to using Buffer in all of my Node.js projects and I think the API is way nicer, but just using ArrayBuffer isn't that much of a big deal and can easily be achieved.

How would for example replace the Buffer.fromString function to decode from various text encoding?

zefir-git commented 3 months ago

Sorry, I only remember changing about 2-3 places where Buffer was used (was a while ago so I don't remember).

Buffer.fromString is replaced with TextEncoder, available in Node.js >= 11.0.0, Chrome >= 38, Firefox >= 18, etc.

Example:

const array: ArrayBuffer = new TextEncoder().encode("hello world").buffer;

(.encode returns Uint8Array i.e. array of unsigned 8 bit ints which can also be used)

edit: MDN actually recommends using TextEncoder#encodeInto as a more performent alternative to TextEncoder#encode()

Takes a string to encode and a destination Uint8Array to put resulting UTF-8 encoded text into, and returns an object indicating the progress of the encoding. This is potentially more performant than the older encode() method.

Borewit commented 3 months ago

Related to #417, maybe this will be a game changer: https://github.com/Borewit/token-types/pull/650