From: epg <> Date: Thu, 2 Nov 2006 10:42:28 +0000 (+0000) Subject: Hm, why just copy front cover PICTUREs from flac to mp3? The flac X-Git-Url: https://diplodocus.org/git/flac-archive/commitdiff_plain/06b03f37a431a7e9763ee0306edad5a8946dfa84?ds=sidebyside;hp=7c8eeba5a67251012ecdebdba9a677b4aba04f9d Hm, why just copy front cover PICTUREs from flac to mp3? The flac PICTURE metadata block has the exact same metadata as the mp3 ID3v2 APIC frame; just copy them all. flac.c: (flac_pictures): Return fields in the same order they're found in the FLAC format. Convert the description to a unicode object rather than returning a UTF-8 encoded str object. taglib.cc: (taglib_apic): Take a list of picture tuples and add them all as APIC frames. (add_apic_frame_to_mp3): Take the list of picture tuples and pass them straight to taglib_apic. flac2mp3: (flac2mp3): Take a list of picture tuples instead of just one; pass them all to add_apic_frame_to_mp3. (find_pics): Rename from find_pic. Save all PICTURE metadata blocks rather than just saving the first front cover picture. --- diff --git a/flac.c b/flac.c index 9df8fcd..98378e4 100644 --- a/flac.c +++ b/flac.c @@ -10,7 +10,7 @@ flac_pictures(char *fn) FLAC__Metadata_Chain *chain; FLAC__Metadata_Iterator *iterator; FLAC__StreamMetadata *block; - PyObject *tuple, *list; + PyObject *description, *tuple, *list; chain = FLAC__metadata_chain_new(); if (chain == NULL) { @@ -53,16 +53,23 @@ flac_pictures(char *fn) continue; } - tuple = Py_BuildValue("(s#issiiii)", - block->data.picture.data, - block->data.picture.data_length, + description = PyUnicode_DecodeUTF8(block->data.picture.description, + strlen(block->data.picture.description), + "strict"); + if (description == NULL) { + return NULL; + } + + tuple = Py_BuildValue("(isOiiiis#)", block->data.picture.type, block->data.picture.mime_type, - block->data.picture.description, + description, block->data.picture.width, block->data.picture.height, block->data.picture.depth, - block->data.picture.colors); + block->data.picture.colors, + block->data.picture.data, + block->data.picture.data_length); if (tuple == NULL) { return NULL; } diff --git a/flac2mp3 b/flac2mp3 index b4ce99e..982a012 100755 --- a/flac2mp3 +++ b/flac2mp3 @@ -61,7 +61,7 @@ from org.diplodocus.util import run_or_die ################################################################################ # The child processes -def flac2mp3(fn, title, artist, album, date, track, skip_until, pic=None): +def flac2mp3(fn, title, artist, album, date, track, skip_until, pics=None): (title, artist, album, date) = [(x == None and 'unknown') or x for x in (title, artist, album, date)] try: @@ -100,8 +100,8 @@ def flac2mp3(fn, title, artist, album, date, track, skip_until, pic=None): lame_options, title, artist, album, date, track, quoted_outfile)) - if pic != None: - taglib.add_apic_frame_to_mp3(outfile, pic[0], pic[1], pic[2]) + if pics != None: + taglib.add_apic_frame_to_mp3(outfile, pics) return 0 @@ -201,17 +201,14 @@ def get_tags(fn): return tags -def find_pic(fn, tags): - pic = tags.get('__flac2mp3_PICTURE') +def find_pics(fn, tags): + pics = tags.get('__flac2mp3_PICTURE') - if not isinstance(pic, tuple): - for i in flac.get_pictures(fn): - if i[1] == flac.PICTURE_TYPE_FRONT_COVER: - pic = i[:3] - break - tags.set('__flac2mp3_PICTURE', pic) + if not isinstance(pics, list): + pics = flac.get_pictures(fn) + tags.set('__flac2mp3_PICTURE', pics) - return pic + return pics def main(argv): # Control the exit code for any uncaught exceptions. @@ -275,7 +272,7 @@ def main(argv): tags.gets('ARTIST', track), album, tags.gets('DATE', track), - track, args[i], find_pic(fn, tags)]) + track, args[i], find_pics(fn, tags)]) track = i + 2 except Exception, error: sys.stderr.write(getattr(error, 'msg', '')) diff --git a/taglib.cc b/taglib.cc index dd6526b..690df40 100644 --- a/taglib.cc +++ b/taglib.cc @@ -11,30 +11,15 @@ extern "C" { static PyObject *taglib_error; static PyObject * -taglib_apic(const char *fn, const char *image, int len, - int type, const char *mime_type) +taglib_apic(const char *fn, PyObject *list) { - TagLib::ByteVector *bv; - TagLib::ID3v2::AttachedPictureFrame *p; TagLib::MPEG::File *f; TagLib::ID3v2::Tag *t; - - bv = new TagLib::ByteVector (image, len); - if (bv == 0) { - return PyErr_NoMemory(); - } - - p = new TagLib::ID3v2::AttachedPictureFrame; - if (p == 0) { - return PyErr_NoMemory(); - } - - /* Um, look at all these void-returning functions. I'm sure they - * can fail, i just have no way to detect it... */ - p->setTextEncoding(TagLib::String::UTF8); - p->setType((TagLib::ID3v2::AttachedPictureFrame::Type)type); - p->setMimeType(mime_type); - p->setPicture(*bv); + PyObject *tuple, *description, *description_utf8; + int i, type, width, height, depth, colors, len; + const char *mime_type, *description_utf8_s, *image; + TagLib::ByteVector *bv; + TagLib::ID3v2::AttachedPictureFrame *p; /* GAH! Opening the file is entangled with allocating the object; * if this fails, am i out of memory, or is there a problem with @@ -50,8 +35,46 @@ taglib_apic(const char *fn, const char *image, int len, return 0; } - // another void-returning function that i bet fails - t->addFrame(p); + for (i = 0; i < PyList_Size(list); i++) { + tuple = PyList_GetItem(list, i); + if (!PyArg_ParseTuple(tuple, "isUiiiis#", + &type, &mime_type, &description, &width, &height, &depth, &colors, &image, &len)) { + return 0; + } + + description_utf8 = PyUnicode_AsEncodedString(description, "utf8", + "strict"); + if (description_utf8 == 0) { + return 0; + } + + description_utf8_s = PyString_AsString(description_utf8); + if (description_utf8_s == 0) { + return 0; + } + + bv = new TagLib::ByteVector (image, len); + if (bv == 0) { + return PyErr_NoMemory(); + } + + p = new TagLib::ID3v2::AttachedPictureFrame; + if (p == 0) { + return PyErr_NoMemory(); + } + + /* Um, look at all these void-returning functions. I'm sure + * they can fail, i just have no way to detect it... */ + p->setType((TagLib::ID3v2::AttachedPictureFrame::Type)type); + p->setMimeType(mime_type); + p->setDescription(description_utf8_s); + p->setTextEncoding(TagLib::String::UTF8); + // taglib doesn't support width, height, depth, colors. + p->setPicture(*bv); + + // another void-returning function that i bet fails + t->addFrame(p); + } errno = 0; if (!f->save()) { @@ -70,15 +93,14 @@ taglib_apic(const char *fn, const char *image, int len, static PyObject * add_apic_frame_to_mp3(PyObject *self, PyObject *args) { - const char *fn, *image, *mime_type; - int len, type; + const char *fn; + PyObject *list; - if (!PyArg_ParseTuple(args, "ss#is", &fn, &image, &len, - &type, &mime_type)) { + if (!PyArg_ParseTuple(args, "sO", &fn, &list)) { return 0; } - return taglib_apic(fn, image, len, type, mime_type); + return taglib_apic(fn, list); } static