diff --git a/NEWS.txt b/NEWS.txt index 2c8cb778e..cb8c975fc 100644 --- a/NEWS.txt +++ b/NEWS.txt @@ -6,6 +6,8 @@ Version 0.9.0alpha12 - 2007-06-XX - On UNIX from "~/.picard" to "$XDG_CONFIG_HOME/MusicBrainz/Picard" (usually "~/.config/MusicBrainz/Picard") * Picard no longer logs every action and doesn't saves the logs. To enable more debug logging, use command line argument "-d" or "--debug" or environment variable "PICARD_DEBUG". + * New Features: + * Save embedded images to MP4 files. Version 0.9.0alpha11 - 2007-05-27 * New Features: diff --git a/picard/formats/mp4.py b/picard/formats/mp4.py index 4265745a8..d04ef92f2 100644 --- a/picard/formats/mp4.py +++ b/picard/formats/mp4.py @@ -17,7 +17,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -from mutagen.mp4 import MP4 +from mutagen.mp4 import MP4, MP4Cover from picard.file import File from picard.metadata import Metadata from picard.util import encode_filename @@ -130,7 +130,14 @@ class MP4File(File): else: file.tags["disk"] = [(int(self.metadata["discnumber"]), 0)] - # TODO save embedded images + covr = [] + for mime, data in self.metadata.images: + if mime == "image/jpeg": + covr.append(MP4Cover(data, format=MP4Cover.FORMAT_JPEG)) + else: + covr.append(MP4Cover(data, format=MP4Cover.FORMAT_PNG)) + if covr: + file.tags["covr"] = covr file.save() diff --git a/picard/metadata.py b/picard/metadata.py index 3a63c911f..51891a891 100644 --- a/picard/metadata.py +++ b/picard/metadata.py @@ -78,12 +78,15 @@ class Metadata(LockableObject): @needs_write_lock def update(self, other): - for name, values in other._items.iteritems(): - self._items[name] = values + for name, values in other.rawitems(): + self._items[name] = values[:] + if other.images: + self.images = other.images[:] @needs_write_lock def clear(self): self._items = {} + self.images = [] def __get(self, name, default=None): values = self._items.get(name, None) diff --git a/test/test_formats.py b/test/test_formats.py index 66daa0892..5a9f139d5 100644 --- a/test/test_formats.py +++ b/test/test_formats.py @@ -286,3 +286,44 @@ class WavPackTest(FormatsTest): ('releasestatus', ['Foo']), ('releasetype', ['Foo']), ] + + +class TestCoverArt(unittest.TestCase): + + def _set_up(self, original): + fd, self.filename = mkstemp(suffix=os.path.splitext(original)[1]) + os.close(fd) + shutil.copy(original, self.filename) + QtCore.QObject.tagger = FakeTagger() + QtCore.QObject.config = FakeConfig() + + def _tear_down(self): + os.unlink(self.filename) + + def test_mp3(self): + self._test_cover_art(os.path.join('test', 'data', 'test.mp3')) + + def test_mp4(self): + self._test_cover_art(os.path.join('test', 'data', 'test.m4a')) + + def _test_cover_art(self, filename): + self._set_up(filename) + try: + f = picard.formats.open(self.filename) + f.metadata.clear() + f.metadata.add_image("image/jpeg", "JFIFfoobar") + f.save() + f = picard.formats.open(self.filename) + f._load() + self.assertEqual(f.metadata.images[0][0], "image/jpeg") + self.assertEqual(f.metadata.images[0][1], "JFIFfoobar") + f = picard.formats.open(self.filename) + f.metadata.clear() + f.metadata.add_image("image/png", "PNGfoobar") + f.save() + f = picard.formats.open(self.filename) + f._load() + self.assertEqual(f.metadata.images[0][0], "image/png") + self.assertEqual(f.metadata.images[0][1], "PNGfoobar") + finally: + self._tear_down()