mirror of
https://github.com/KevinMidboe/spotify-downloader.git
synced 2025-10-29 18:00:15 +00:00
177 lines
6.9 KiB
Python
177 lines
6.9 KiB
Python
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 logzero import logger as log
|
|
|
|
from spotdl.const import TAG_PRESET, M4A_TAG_PRESET
|
|
|
|
|
|
def compare(music_file, metadata):
|
|
"""Check if the input music file title matches the expected title."""
|
|
already_tagged = False
|
|
try:
|
|
if music_file.endswith(".mp3"):
|
|
audiofile = EasyID3(music_file)
|
|
already_tagged = audiofile["title"][0] == metadata["name"]
|
|
elif music_file.endswith(".m4a"):
|
|
audiofile = MP4(music_file)
|
|
already_tagged = audiofile["\xa9nam"][0] == metadata["name"]
|
|
except (KeyError, TypeError):
|
|
pass
|
|
|
|
return already_tagged
|
|
|
|
|
|
def embed(music_file, meta_tags):
|
|
""" Embed metadata. """
|
|
embed = EmbedMetadata(music_file, meta_tags)
|
|
if music_file.endswith(".m4a"):
|
|
log.info("Applying metadata")
|
|
return embed.as_m4a()
|
|
elif music_file.endswith(".mp3"):
|
|
log.info("Applying metadata")
|
|
return embed.as_mp3()
|
|
elif music_file.endswith(".flac"):
|
|
log.info("Applying metadata")
|
|
return embed.as_flac()
|
|
else:
|
|
log.warning("Cannot embed metadata into given output extension")
|
|
return False
|
|
|
|
|
|
class EmbedMetadata:
|
|
def __init__(self, music_file, meta_tags):
|
|
self.music_file = music_file
|
|
self.meta_tags = meta_tags
|
|
self.spotify_metadata = meta_tags["spotify_metadata"]
|
|
self.provider = "spotify" if meta_tags["spotify_metadata"] else "youtube"
|
|
|
|
def as_mp3(self):
|
|
""" Embed metadata to MP3 files. """
|
|
music_file = self.music_file
|
|
meta_tags = self.meta_tags
|
|
# 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(music_file)
|
|
self._embed_basic_metadata(audiofile, preset=TAG_PRESET)
|
|
audiofile["media"] = meta_tags["type"]
|
|
audiofile["author"] = meta_tags["artists"][0]["name"]
|
|
audiofile["lyricist"] = meta_tags["artists"][0]["name"]
|
|
audiofile["arranger"] = meta_tags["artists"][0]["name"]
|
|
audiofile["performer"] = meta_tags["artists"][0]["name"]
|
|
audiofile["website"] = meta_tags["external_urls"][self.provider]
|
|
audiofile["length"] = str(meta_tags["duration"])
|
|
if meta_tags["publisher"]:
|
|
audiofile["encodedby"] = meta_tags["publisher"]
|
|
if meta_tags["external_ids"]["isrc"]:
|
|
audiofile["isrc"] = meta_tags["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(music_file)
|
|
audiofile["TORY"] = TORY(encoding=3, text=meta_tags["year"])
|
|
audiofile["TYER"] = TYER(encoding=3, text=meta_tags["year"])
|
|
if meta_tags["publisher"]:
|
|
audiofile["TPUB"] = TPUB(encoding=3, text=meta_tags["publisher"])
|
|
audiofile["COMM"] = COMM(encoding=3, text=meta_tags["external_urls"][self.provider])
|
|
if meta_tags["lyrics"]:
|
|
audiofile["USLT"] = USLT(
|
|
encoding=3, desc=u"Lyrics", text=meta_tags["lyrics"]
|
|
)
|
|
try:
|
|
albumart = urllib.request.urlopen(meta_tags["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)
|
|
return True
|
|
|
|
def as_m4a(self):
|
|
""" Embed metadata to M4A files. """
|
|
music_file = self.music_file
|
|
meta_tags = self.meta_tags
|
|
audiofile = MP4(music_file)
|
|
self._embed_basic_metadata(audiofile, preset=M4A_TAG_PRESET)
|
|
audiofile[M4A_TAG_PRESET["year"]] = meta_tags["year"]
|
|
audiofile[M4A_TAG_PRESET["comment"]] = meta_tags["external_urls"][self.provider]
|
|
if meta_tags["lyrics"]:
|
|
audiofile[M4A_TAG_PRESET["lyrics"]] = meta_tags["lyrics"]
|
|
try:
|
|
albumart = urllib.request.urlopen(meta_tags["album"]["images"][0]["url"])
|
|
audiofile[M4A_TAG_PRESET["albumart"]] = [
|
|
MP4Cover(albumart.read(), imageformat=MP4Cover.FORMAT_JPEG)
|
|
]
|
|
albumart.close()
|
|
except IndexError:
|
|
pass
|
|
|
|
audiofile.save()
|
|
return True
|
|
|
|
def as_flac(self):
|
|
music_file = self.music_file
|
|
meta_tags = self.meta_tags
|
|
audiofile = FLAC(music_file)
|
|
self._embed_basic_metadata(audiofile)
|
|
audiofile["year"] = meta_tags["year"]
|
|
audiofile["comment"] = meta_tags["external_urls"][self.provider]
|
|
if meta_tags["lyrics"]:
|
|
audiofile["lyrics"] = meta_tags["lyrics"]
|
|
|
|
image = Picture()
|
|
image.type = 3
|
|
image.desc = "Cover"
|
|
image.mime = "image/jpeg"
|
|
albumart = urllib.request.urlopen(meta_tags["album"]["images"][0]["url"])
|
|
image.data = albumart.read()
|
|
albumart.close()
|
|
audiofile.add_picture(image)
|
|
|
|
audiofile.save()
|
|
return True
|
|
|
|
def _embed_basic_metadata(self, audiofile, preset=TAG_PRESET):
|
|
meta_tags = self.meta_tags
|
|
audiofile[preset["artist"]] = meta_tags["artists"][0]["name"]
|
|
if meta_tags["album"]["artists"][0]["name"]:
|
|
audiofile[preset["albumartist"]] = meta_tags["album"]["artists"][0]["name"]
|
|
if meta_tags["album"]["name"]:
|
|
audiofile[preset["album"]] = meta_tags["album"]["name"]
|
|
audiofile[preset["title"]] = meta_tags["name"]
|
|
audiofile[preset["date"]] = meta_tags["release_date"]
|
|
audiofile[preset["originaldate"]] = meta_tags["release_date"]
|
|
if meta_tags["genre"]:
|
|
audiofile[preset["genre"]] = meta_tags["genre"]
|
|
if meta_tags["copyright"]:
|
|
audiofile[preset["copyright"]] = meta_tags["copyright"]
|
|
if self.music_file.endswith(".flac"):
|
|
audiofile[preset["discnumber"]] = str(meta_tags["disc_number"])
|
|
else:
|
|
audiofile[preset["discnumber"]] = [(meta_tags["disc_number"], 0)]
|
|
if self.music_file.endswith(".flac"):
|
|
audiofile[preset["tracknumber"]] = str(meta_tags["track_number"])
|
|
else:
|
|
if preset["tracknumber"] == TAG_PRESET["tracknumber"]:
|
|
audiofile[preset["tracknumber"]] = "{}/{}".format(
|
|
meta_tags["track_number"], meta_tags["total_tracks"]
|
|
)
|
|
else:
|
|
audiofile[preset["tracknumber"]] = [
|
|
(meta_tags["track_number"], meta_tags["total_tracks"])
|
|
]
|