from mutagen.easyid3 import EasyID3 from mutagen.id3 import ID3, TORY, TYER, TPUB, APIC, USLT, COMM from mutagen.mp4 import MP4, MP4Cover from mutagen.flac import Picture, FLAC import urllib.request from spotdl.metadata import EmbedderBase # Apple has specific tags - see mutagen docs - # http://mutagen.readthedocs.io/en/latest/api/mp4.html M4A_TAG_PRESET = { "album": "\xa9alb", "artist": "\xa9ART", "date": "\xa9day", "title": "\xa9nam", "year": "\xa9day", "originaldate": "purd", "comment": "\xa9cmt", "group": "\xa9grp", "writer": "\xa9wrt", "genre": "\xa9gen", "tracknumber": "trkn", "albumartist": "aART", "discnumber": "disk", "cpil": "cpil", "albumart": "covr", "copyright": "cprt", "tempo": "tmpo", "lyrics": "\xa9lyr", "comment": "\xa9cmt", } TAG_PRESET = {} for key in M4A_TAG_PRESET.keys(): TAG_PRESET[key] = key class EmbedderDefault(EmbedderBase): supported_formats = ("mp3", "opus", "flac") def __init__(self): super().__init__() self._m4a_tag_preset = M4A_TAG_PRESET self._tag_preset = TAG_PRESET # self.provider = "spotify" if metadata["spotify_metadata"] else "youtube" def as_mp3(self, path, metadata): """ Embed metadata to MP3 files. """ # EasyID3 is fun to use ;) # For supported easyid3 tags: # https://github.com/quodlibet/mutagen/blob/master/mutagen/easyid3.py # Check out somewhere at end of above linked file audiofile = EasyID3(path) self._embed_basic_metadata(audiofile, metadata, "mp3", preset=TAG_PRESET) audiofile["media"] = metadata["type"] audiofile["author"] = metadata["artists"][0]["name"] audiofile["lyricist"] = metadata["artists"][0]["name"] audiofile["arranger"] = metadata["artists"][0]["name"] audiofile["performer"] = metadata["artists"][0]["name"] provider = metadata["provider"] audiofile["website"] = metadata["external_urls"][provider] audiofile["length"] = str(metadata["duration"]) if metadata["publisher"]: audiofile["encodedby"] = metadata["publisher"] if metadata["external_ids"]["isrc"]: audiofile["isrc"] = metadata["external_ids"]["isrc"] audiofile.save(v2_version=3) # For supported id3 tags: # https://github.com/quodlibet/mutagen/blob/master/mutagen/id3/_frames.py # Each class represents an id3 tag audiofile = ID3(path) if metadata["year"]: audiofile["TORY"] = TORY(encoding=3, text=metadata["year"]) audiofile["TYER"] = TYER(encoding=3, text=metadata["year"]) if metadata["publisher"]: audiofile["TPUB"] = TPUB(encoding=3, text=metadata["publisher"]) provider = metadata["provider"] audiofile["COMM"] = COMM( encoding=3, text=metadata["external_urls"][provider] ) if metadata["lyrics"]: audiofile["USLT"] = USLT( encoding=3, desc=u"Lyrics", text=metadata["lyrics"] ) try: albumart = urllib.request.urlopen(metadata["album"]["images"][0]["url"]) audiofile["APIC"] = APIC( encoding=3, mime="image/jpeg", type=3, desc=u"Cover", data=albumart.read(), ) albumart.close() except IndexError: pass audiofile.save(v2_version=3) def as_opus(self, path): """ Embed metadata to M4A files. """ audiofile = MP4(path) self._embed_basic_metadata(audiofile, metadata, "opus", preset=M4A_TAG_PRESET) if metadata["year"]: audiofile[M4A_TAG_PRESET["year"]] = metadata["year"] provider = metadata["provider"] audiofile[M4A_TAG_PRESET["comment"]] = metadata["external_urls"][provider] if metadata["lyrics"]: audiofile[M4A_TAG_PRESET["lyrics"]] = metadata["lyrics"] try: albumart = urllib.request.urlopen(metadata["album"]["images"][0]["url"]) audiofile[M4A_TAG_PRESET["albumart"]] = [ MP4Cover(albumart.read(), imageformat=MP4Cover.FORMAT_JPEG) ] albumart.close() except IndexError: pass audiofile.save() def as_flac(self, path, metadata): audiofile = FLAC(path) self._embed_basic_metadata(audiofile, metadata, "flac") if metadata["year"]: audiofile["year"] = metadata["year"] provider = metadata["provider"] audiofile["comment"] = metadata["external_urls"][provider] if metadata["lyrics"]: audiofile["lyrics"] = metadata["lyrics"] image = Picture() image.type = 3 image.desc = "Cover" image.mime = "image/jpeg" albumart = urllib.request.urlopen(metadata["album"]["images"][0]["url"]) image.data = albumart.read() albumart.close() audiofile.add_picture(image) audiofile.save() def _embed_basic_metadata(self, audiofile, metadata, encoding, preset=TAG_PRESET): audiofile[preset["artist"]] = metadata["artists"][0]["name"] if metadata["album"]["artists"][0]["name"]: audiofile[preset["albumartist"]] = metadata["album"]["artists"][0]["name"] if metadata["album"]["name"]: audiofile[preset["album"]] = metadata["album"]["name"] audiofile[preset["title"]] = metadata["name"] if metadata["release_date"]: audiofile[preset["date"]] = metadata["release_date"] audiofile[preset["originaldate"]] = metadata["release_date"] if metadata["genre"]: audiofile[preset["genre"]] = metadata["genre"] if metadata["copyright"]: audiofile[preset["copyright"]] = metadata["copyright"] if encoding == "flac": audiofile[preset["discnumber"]] = str(metadata["disc_number"]) else: audiofile[preset["discnumber"]] = [(metadata["disc_number"], 0)] if encoding == "flac": audiofile[preset["tracknumber"]] = str(metadata["track_number"]) else: if preset["tracknumber"] == TAG_PRESET["tracknumber"]: audiofile[preset["tracknumber"]] = "{}/{}".format( metadata["track_number"], metadata["total_tracks"] ) else: audiofile[preset["tracknumber"]] = [ (metadata["track_number"], metadata["total_tracks"]) ]