LordSputnik / mutagen

Project to create a Python 3 library, functionally equivalent to mutagen.
GNU General Public License v2.0
37 stars 3 forks source link

bug when writing a picture to an oggvorbis? #23

Closed fossfreedom closed 10 years ago

fossfreedom commented 10 years ago

Hi,

thanks for your port - this is a quick query hopefully. I'm using your 1.22 branch.

I've got a jpg which I'm attempting to write to an OggVorbis file

snippet:

    image = flac.Picture()
    image.type = 3 # Cover image
    image.data = open(art_location, "rb").read()
    image.mime = mimetypestr
    image.desc = 'cover description'
    tags.setdefault("METADATA_BLOCK_PICTURE",
        []).append(base64.b64encode(image.write()))

where art_location is pointing to a valid jpeg file location.

in python2 I would use "image.data = open(art_location, "r").read()" - this snippet would work. In python3 - this would fail with "UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte"

Thus - I'm reading as binary.

However when writing the tag this error occurs:

snippet:


Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/mutagenx/_vorbis.py", line 172, in validate
    value.encode("utf-8")
AttributeError: 'bytes' object has no attribute 'encode'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/mutagenx/ogg.py", line 504, in save
    self.tags._inject(fileobj)
  File "/usr/lib/python3/dist-packages/mutagenx/oggvorbis.py", line 114, in _inject
    packets[0] = b"\x03vorbis" + self.write()
  File "/usr/lib/python3/dist-packages/mutagenx/_vorbis.py", line 188, in write
    self.validate()
  File "/usr/lib/python3/dist-packages/mutagenx/_vorbis.py", line 174, in validate
    raise ValueError("%r is not a valid value" % value)
ValueError: b'AAAAAwAAAAppbWFnZS9qcGVnAAAAEWNvd

Any thoughts on how to resolve this?

LordSputnik commented 10 years ago

Thanks for letting me know about this - I'll look into it later today!

LordSputnik commented 10 years ago

So, all comment data has to be UTF-8 encoded, and according to http://wiki.xiph.org/VorbisComment#Cover_art, the picture should be base64 encoded within the VorbisComment... You seem to be doing this correctly.

Just checked and the output of base64.b64encode in Python 3 is bytes. I think the problem here is the validation and writing of UTF-8 byte strings in mutagenx. In Python 2, str.encode and unicode.encode both existed - str.encode('utf-8') did nothing if the string was already UTF-8. So I'll have to update the validation and writing code to handle bytes specifically - perhaps a UTF-8 decode followed by a UTF-8 encode.

LordSputnik commented 10 years ago

Ok, I've committed a fix to this repo - not currently planning to put it on PyPI for another few days, so if you need it urgently, get it from here.

Alternatively, for now you should be able to get around it by doing:

base64.b64encode(data).decode("utf-8")

which'll pass in a Unicode value to be verified.

fossfreedom commented 10 years ago

absolutely superb!

Many many thanks. The fixes work great. Cheers :)