43081j / id3

A JavaScript ID3 tags parser for Node & browsers.
MIT License
335 stars 63 forks source link

Fix loading of cover images by using getUint32 instead of getUint32Synch to get the frame size #21

Closed Avnerus closed 5 years ago

Avnerus commented 9 years ago

I'm not sure if this is the correct solution but it worked for me

Avnerus commented 9 years ago

I've added another fix to support genre numbers inside parenthesis. I noticed most of the times the genre is encoded as a number inside parenthesis like: (17) This also includes a fix to not encode the \u0000 character which I saw is already on another pull request

43081j commented 9 years ago

What error were you getting when you had getUint32Synch?

The ID3v2 spec states:

The size is excluding the frame header ('total frame size' - 10 bytes) and stored as a 32 bit synchsafe integer.

So changing it to getUint32 seems the wrong way to go about fixing your issue.

defenderjim commented 9 years ago

I too am having the same problem with partial image being decoded. Also, for the Adobe XMP PRIV tag, the length is not SynchSafe. Always passing a non SynchSafe value, still results with properly decoded values. This also ties into issue #28 that I opened.

Also, for some of my mp3s, if the PRIV tag is not decoded, it won't get to the image and parse it out. I have some code for that if interested.

hidez8891 commented 8 years ago

ID3v2.4 extended header is used synchsafe integer.

Where the 'Extended header size' is the size of the whole extended header, stored as a 32 bit synchsafe integer.

But, ID3v2.3 extended header is not used synchsafe integer.

Where the 'Extended header size', currently 6 or 10 bytes, excludes itself.

defenderjim commented 8 years ago

hidez8891, thanks for the info. Modified code with your explanation. Checked in and created pull request.

hidez8891 commented 8 years ago

It works fine. Thank you!

defenderjim commented 8 years ago

hidez8891, You're welcome! One last thing, I found, for the PRIV tag, going from ArrayBuffer to String was a bit tricky. I post the code here for future reference:

if (tags.v2.private != null) {
    var len = tags.v2.private.data.byteLength ;
    var encodedStr = String.fromCharCode.apply(null, new Uint8Array(tags.v2.private.data));
    var decodedString = decodeURIComponent(escape( encodedStr ));
}

And for others, here is how to display the image: Perhaps the author would be kind enough to update the readme:

if (tags.v2.image != null) {
    var blob = new Blob( [ a ], { type: "image/png" } );
    var urlCreator = window.URL || window.webkitURL;
    var imageUrl = urlCreator.createObjectURL( blob );

    $('#image).attr('src', imageUrl);
}