def test_render_bool(self): self.failUnlessEqual( MP4Tags()._MP4Tags__render_bool('pgap', True), b"\x00\x00\x00\x19pgap\x00\x00\x00\x11data" b"\x00\x00\x00\x15\x00\x00\x00\x00\x01") self.failUnlessEqual( MP4Tags()._MP4Tags__render_bool('pgap', False), b"\x00\x00\x00\x19pgap\x00\x00\x00\x11data" b"\x00\x00\x00\x15\x00\x00\x00\x00\x00")
def test_render_data(self): self.failUnlessEqual( MP4Tags()._MP4Tags__render_data('aART', 0, 1, [b'whee']), b"\x00\x00\x00\x1caART" b"\x00\x00\x00\x14data\x00\x00\x00\x01\x00\x00\x00\x00whee") self.failUnlessEqual( MP4Tags()._MP4Tags__render_data('aART', 0, 2, [b'whee', b'wee']), b"\x00\x00\x00/aART" b"\x00\x00\x00\x14data\x00\x00\x00\x02\x00\x00\x00\x00whee" b"\x00\x00\x00\x13data\x00\x00\x00\x02\x00\x00\x00\x00wee")
def test_render_text(self): self.failUnlessEqual( MP4Tags()._MP4Tags__render_text('purl', ['http://foo/bar.xml'], 0), b"\x00\x00\x00*purl\x00\x00\x00\"data\x00\x00\x00\x00\x00\x00" b"\x00\x00http://foo/bar.xml") self.failUnlessEqual( MP4Tags()._MP4Tags__render_text('aART', [u'\u0041lbum Artist']), b"\x00\x00\x00$aART\x00\x00\x00\x1cdata\x00\x00\x00\x01\x00\x00" b"\x00\x00\x41lbum Artist") self.failUnlessEqual( MP4Tags()._MP4Tags__render_text('aART', [u'Album Artist', u'Whee']), b"\x00\x00\x008aART\x00\x00\x00\x1cdata\x00\x00\x00\x01\x00\x00" b"\x00\x00Album Artist\x00\x00\x00\x14data\x00\x00\x00\x01\x00" b"\x00\x00\x00Whee")
def dict_to_mp4tag(d): """Convert python dictionary to MP4Tag object. """ tags = MP4Tags() tags.update(d) return tags
def m4a_tag(m4a_dirname, m4a_filename, artist, album, track, tracks, title, year, genre, bpms, compilation): # Print tags first #m4a = MP4(m4a_filename) #print(m4a.pprint()) # Delete existing tags id3 = MP4Tags() id3.delete(m4a_filename) # Artist, Composer id3['\xa9ART'] = artist id3['aART'] = artist id3['\xa9wrt'] = artist # Artistsort id3['soaa'] = artist id3['soar'] = artist id3['soco'] = artist # Album id3['\xa9alb'] = album # Albumsort id3['soal'] = album # Track id3['trkn'] = [(int(track), int(re.sub(pattern='.*\/', repl='', string=tracks)))] id3['disk'] = [(1, 1)] # Title id3['\xa9nam'] = title id3['sonm'] = title # Year id3['\xa9day'] = year # Genre id3['\xa9gen'] = genre # BPMs, Gapless album id3['tmpo'] = [(int(round(float(bpms), 0)))] id3['pgap'] = True # Compilation if (compilation): id3['cpil'] = True else: id3['cpil'] = False # Cover try: with open(str(m4a_dirname + '/Cover.jpg'), 'rb') as f: id3["covr"] = [ MP4Cover(f.read(), imageformat=MP4Cover.FORMAT_JPEG) ] except: print("Warning. No Cover.jpg in directory " + m4a_dirname + ".") # Save tags to file id3.save(m4a_filename)
def test_render_freeform(self): self.failUnlessEqual( MP4Tags()._MP4Tags__render_freeform( '----:net.sacredchao.Mutagen:test', ['whee', 'wee']), "\x00\x00\x00a----" "\x00\x00\x00\"mean\x00\x00\x00\x00net.sacredchao.Mutagen" "\x00\x00\x00\x10name\x00\x00\x00\x00test" "\x00\x00\x00\x14data\x00\x00\x00\x01\x00\x00\x00\x00whee" "\x00\x00\x00\x13data\x00\x00\x00\x01\x00\x00\x00\x00wee")
def test_render_integer_min_size(self): render_int = MP4Tags()._MP4Tags__render_integer data = render_int('stik', [42], 1) tags = self.wrap_ilst(data) assert tags['stik'] == [42] assert len(render_int('stik', [42], 2)) == len(data) + 1 assert len(render_int('stik', [42], 4)) == len(data) + 3 assert len(render_int('stik', [42], 8)) == len(data) + 7
def test_render_freeform(self): data = (b"\x00\x00\x00a----" b"\x00\x00\x00\"mean\x00\x00\x00\x00net.sacredchao.Mutagen" b"\x00\x00\x00\x10name\x00\x00\x00\x00test" b"\x00\x00\x00\x14data\x00\x00\x00\x01\x00\x00\x00\x00whee" b"\x00\x00\x00\x13data\x00\x00\x00\x01\x00\x00\x00\x00wee") key = '----:net.sacredchao.Mutagen:test' self.failUnlessEqual( MP4Tags()._MP4Tags__render_freeform(key, [b'whee', b'wee']), data)
def test_update_parents(self): file = open(self.filename) atoms = Atoms(file) self.assertEqual(77, atoms.atoms[0].length) self.assertEqual(61, atoms.atoms[0].children[0].length) tags = MP4Tags(atoms, file) tags['pgap'] = True tags.save(self.filename) file = open(self.filename) atoms = Atoms(file) # original size + 'pgap' size + padding self.assertEqual(77 + 25 + 974, atoms.atoms[0].length) self.assertEqual(61 + 25 + 974, atoms.atoms[0].children[0].length)
def load(self, fp): self.filename = fp.name fileobj = fp try: atoms = Atoms(fileobj) try: self.info = MP4Info(atoms, fileobj) except StandardError, err: raise MP4StreamInfoError, err, sys.exc_info()[2] try: self.tags = MP4Tags(atoms, fileobj) except MP4MetadataError: self.tags = None except StandardError, err: raise MP4MetadataError, err, sys.exc_info()[2]
def test_freeform_data(self): # http://code.google.com/p/mutagen/issues/detail?id=103 key = b"----:com.apple.iTunes:Encoding Params" value = (b"vers\x00\x00\x00\x01acbf\x00\x00\x00\x01brat\x00\x01\xf4" b"\x00cdcv\x00\x01\x05\x04") data = (b"\x00\x00\x00\x1cmean\x00\x00\x00\x00com.apple.iTunes\x00\x00" b"\x00\x1bname\x00\x00\x00\x00Encoding Params\x00\x00\x000data" b"\x00\x00\x00\x00\x00\x00\x00\x00vers\x00\x00\x00\x01acbf\x00" b"\x00\x00\x01brat\x00\x01\xf4\x00cdcv\x00\x01\x05\x04") tags = self.wrap_ilst(Atom.render(b"----", data)) v = tags[key][0] self.failUnlessEqual(v, value) self.failUnlessEqual(v.dataformat, MP4FreeForm.FORMAT_DATA) data = MP4Tags()._MP4Tags__render_freeform(key, v) v = self.wrap_ilst(data)[key][0] self.failUnlessEqual(v.dataformat, MP4FreeForm.FORMAT_DATA) data = MP4Tags()._MP4Tags__render_freeform(key, value) v = self.wrap_ilst(data)[key][0] self.failUnlessEqual(v.dataformat, MP4FreeForm.FORMAT_TEXT)
def tags_from_song_model_to_m4a(song, file_path): """ Read all the new model attributes and save them according to the MP4 tags of the m4a stored file """ # Creating an MP4 tag if not present or read it if present try: tags = MP4(file_path).tags except ValueError: tags = MP4Tags() save_song_attrs_to_mp4tags(tags, song) tags.save(file_path)
def test_update_parents(self): with open(self.filename, "rb") as fileobj: atoms = Atoms(fileobj) self.assertEqual(77, atoms.atoms[0].length) self.assertEqual(61, atoms.atoms[0].children[0].length) tags = MP4Tags(atoms, fileobj) tags['pgap'] = True tags.save(self.filename, padding=lambda x: 0) with open(self.filename, "rb") as fileobj: atoms = Atoms(fileobj) # original size + 'pgap' size + padding self.assertEqual(77 + 25 + 8, atoms.atoms[0].length) self.assertEqual(61 + 25 + 8, atoms.atoms[0].children[0].length)
def test_freeform_data(self): # https://github.com/quodlibet/mutagen/issues/103 key = "----:com.apple.iTunes:Encoding Params" value = (b"vers\x00\x00\x00\x01acbf\x00\x00\x00\x01brat\x00\x01\xf4" b"\x00cdcv\x00\x01\x05\x04") data = (b"\x00\x00\x00\x1cmean\x00\x00\x00\x00com.apple.iTunes\x00\x00" b"\x00\x1bname\x00\x00\x00\x00Encoding Params\x00\x00\x000data" b"\x00\x00\x00\x00\x00\x00\x00\x00vers\x00\x00\x00\x01acbf\x00" b"\x00\x00\x01brat\x00\x01\xf4\x00cdcv\x00\x01\x05\x04") tags = self.wrap_ilst(Atom.render(b"----", data)) v = tags[key][0] self.failUnlessEqual(v, value) self.failUnlessEqual(v.dataformat, AtomDataType.IMPLICIT) data = MP4Tags()._MP4Tags__render_freeform(key, v) v = self.wrap_ilst(data)[key][0] self.failUnlessEqual(v.dataformat, AtomDataType.IMPLICIT) data = MP4Tags()._MP4Tags__render_freeform(key, value) v = self.wrap_ilst(data)[key][0] self.failUnlessEqual(v.dataformat, AtomDataType.UTF8)
def test_parse_freeform(self): double_data = ( b"\x00\x00\x00a----" b"\x00\x00\x00\"mean\x00\x00\x00\x00net.sacredchao.Mutagen" b"\x00\x00\x00\x10name\x00\x00\x00\x00test" b"\x00\x00\x00\x14data\x00\x00\x00\x01\x00\x00\x00\x00whee" b"\x00\x00\x00\x13data\x00\x00\x00\x01\x00\x00\x00\x00wee") key = '----:net.sacredchao.Mutagen:test' double_atom = \ MP4Tags()._MP4Tags__render_freeform(key, [b'whee', b'wee']) tags = self.wrap_ilst(double_data) self.assertTrue(key in tags) self.assertEqual(tags[key], [b'whee', b'wee']) tags2 = self.wrap_ilst(double_atom) self.assertEqual(tags, tags2)
def wrap_ilst(self, data): ilst = Atom.render(b"ilst", data) meta = Atom.render(b"meta", b"\x00" * 4 + ilst) data = Atom.render(b"moov", Atom.render(b"udta", meta)) fileobj = BytesIO(data) return MP4Tags(Atoms(fileobj), fileobj)
def test_pprint_non_text_list(self): tags = MP4Tags() tags["tmpo"] = [120, 121] tags["trkn"] = [(1, 2), (3, 4)] tags.pprint()
def __init__(self, *args, **kwargs): self.__mp4 = MP4Tags(*args, **kwargs) self.load = self.__mp4.load self.save = self.__mp4.save self.delete = self.__mp4.delete
def wrap_ilst(self, data): ilst = Atom.render("ilst", data) meta = Atom.render("meta", "\x00" * 4 + ilst) data = Atom.render("moov", Atom.render("udta", meta)) fileobj = StringIO(data) return MP4Tags(Atoms(fileobj), fileobj)