2023-12-19 23:58:57 +01:00
|
|
|
import mutagen
|
|
|
|
|
import requests
|
2024-01-14 17:29:39 +01:00
|
|
|
from mutagen import flac, id3, mp4
|
2023-12-19 23:58:57 +01:00
|
|
|
from mutagen.id3 import APIC, TALB, TCOM, TCOP, TDRC, TIT2, TOPE, TPE1, TRCK, TSRC, USLT
|
|
|
|
|
|
2024-01-14 23:27:39 +01:00
|
|
|
from tidal_dl_ng.constants import REQUESTS_TIMEOUT_SEC
|
|
|
|
|
|
2023-12-19 23:58:57 +01:00
|
|
|
|
|
|
|
|
class Metadata:
|
2024-01-23 17:22:10 +01:00
|
|
|
path_file: str
|
|
|
|
|
title: str
|
|
|
|
|
album: str
|
|
|
|
|
albumartist: str
|
|
|
|
|
artists: [str]
|
|
|
|
|
copy_right: str
|
|
|
|
|
tracknumber: int
|
|
|
|
|
discnumber: int
|
|
|
|
|
totaldisc: int
|
|
|
|
|
totaltrack: int
|
|
|
|
|
date: str
|
|
|
|
|
composer: [str]
|
|
|
|
|
isrc: str
|
|
|
|
|
lyrics: str
|
|
|
|
|
path_cover: str
|
|
|
|
|
url_cover: str
|
|
|
|
|
m: mutagen.mp4.MP4 | mutagen.mp4.MP4 | mutagen.flac.FLAC
|
2023-12-19 23:58:57 +01:00
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
|
self,
|
|
|
|
|
path_file: str,
|
|
|
|
|
album: str = "",
|
|
|
|
|
title: str = "",
|
2024-03-19 07:23:35 +01:00
|
|
|
artists: str = "",
|
2023-12-19 23:58:57 +01:00
|
|
|
copy_right: str = "",
|
|
|
|
|
tracknumber: int = 0,
|
|
|
|
|
discnumber: int = 0,
|
|
|
|
|
totaltrack: int = 0,
|
|
|
|
|
totaldisc: int = 0,
|
2024-01-13 11:57:11 +01:00
|
|
|
composer: list[str] | None = None,
|
2023-12-19 23:58:57 +01:00
|
|
|
isrc: str = "",
|
|
|
|
|
albumartist: str = "",
|
|
|
|
|
date: str = "",
|
|
|
|
|
lyrics: str = "",
|
|
|
|
|
path_cover: str = "",
|
|
|
|
|
url_cover: str = "",
|
|
|
|
|
):
|
|
|
|
|
self.path_file = path_file
|
|
|
|
|
self.title = title
|
|
|
|
|
self.album = album
|
|
|
|
|
self.albumartist = albumartist
|
|
|
|
|
self.artists = artists
|
|
|
|
|
self.copy_right = copy_right
|
|
|
|
|
self.tracknumber = tracknumber
|
|
|
|
|
self.discnumber = discnumber
|
|
|
|
|
self.totaldisc = totaldisc
|
|
|
|
|
self.totaltrack = totaltrack
|
|
|
|
|
self.date = date
|
|
|
|
|
self.composer = composer
|
|
|
|
|
self.isrc = isrc
|
|
|
|
|
self.lyrics = lyrics
|
|
|
|
|
self.path_cover = path_cover
|
|
|
|
|
self.url_cover = url_cover
|
2024-01-14 17:29:39 +01:00
|
|
|
self.m: mutagen.mp4.MP4 | mutagen.flac.FLAC | mutagen.mp3.MP3 = mutagen.File(self.path_file)
|
2023-12-19 23:58:57 +01:00
|
|
|
|
|
|
|
|
def _cover(self) -> bool:
|
2024-01-10 19:41:02 +01:00
|
|
|
result: bool = False
|
|
|
|
|
data_cover: str | bytes = self.cover_data(url=self.url_cover, path_file=self.path_cover)
|
2023-12-19 23:58:57 +01:00
|
|
|
|
|
|
|
|
if data_cover:
|
2024-01-14 17:29:39 +01:00
|
|
|
if isinstance(self.m, mutagen.flac.FLAC):
|
2023-12-19 23:58:57 +01:00
|
|
|
flac_cover = flac.Picture()
|
2024-01-14 17:29:39 +01:00
|
|
|
flac_cover.type = id3.PictureType.COVER_FRONT
|
2023-12-19 23:58:57 +01:00
|
|
|
flac_cover.data = data_cover
|
|
|
|
|
flac_cover.mime = "image/jpeg"
|
|
|
|
|
|
|
|
|
|
self.m.clear_pictures()
|
|
|
|
|
self.m.add_picture(flac_cover)
|
2024-01-14 17:29:39 +01:00
|
|
|
elif isinstance(self.m, mutagen.mp3.MP3):
|
2023-12-19 23:58:57 +01:00
|
|
|
self.m.tags.add(APIC(encoding=3, data=data_cover))
|
2024-01-14 17:29:39 +01:00
|
|
|
elif isinstance(self.m, mutagen.mp4.MP4):
|
2023-12-19 23:58:57 +01:00
|
|
|
cover_mp4 = mp4.MP4Cover(data_cover)
|
|
|
|
|
self.m.tags["covr"] = [cover_mp4]
|
|
|
|
|
|
|
|
|
|
result = True
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
def save(self):
|
2024-01-14 17:29:39 +01:00
|
|
|
if not self.m.tags:
|
|
|
|
|
self.m.add_tags()
|
|
|
|
|
|
|
|
|
|
if isinstance(self.m, mutagen.flac.FLAC):
|
2023-12-19 23:58:57 +01:00
|
|
|
self.set_flac()
|
2024-01-14 17:29:39 +01:00
|
|
|
elif isinstance(self.m, mutagen.mp3.MP3):
|
2023-12-19 23:58:57 +01:00
|
|
|
self.set_mp3()
|
2024-01-14 17:29:39 +01:00
|
|
|
elif isinstance(self.m, mutagen.mp4.MP4):
|
2023-12-19 23:58:57 +01:00
|
|
|
self.set_mp4()
|
|
|
|
|
|
|
|
|
|
self._cover()
|
|
|
|
|
self.m.save()
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def set_flac(self):
|
2024-11-10 14:45:17 +01:00
|
|
|
self.m.tags["TITLE"] = self.title
|
|
|
|
|
self.m.tags["ALBUM"] = self.album
|
|
|
|
|
self.m.tags["ALBUMARTIST"] = self.albumartist
|
|
|
|
|
self.m.tags["ARTIST"] = self.artists
|
|
|
|
|
self.m.tags["COPYRIGHT"] = self.copy_right
|
|
|
|
|
self.m.tags["TRACKNUMBER"] = str(self.tracknumber)
|
|
|
|
|
self.m.tags["TRACKTOTAL"] = str(self.totaltrack)
|
|
|
|
|
self.m.tags["DISCNUMBER"] = str(self.discnumber)
|
|
|
|
|
self.m.tags["DISCTOTAL"] = str(self.totaldisc)
|
|
|
|
|
self.m.tags["DATE"] = self.date
|
|
|
|
|
self.m.tags["COMPOSER"] = ", ".join(self.composer) if self.composer else ""
|
|
|
|
|
self.m.tags["ISRC"] = self.isrc
|
|
|
|
|
self.m.tags["LYRICS"] = self.lyrics
|
2023-12-19 23:58:57 +01:00
|
|
|
|
|
|
|
|
def set_mp3(self):
|
|
|
|
|
self.m.tags.add(TIT2(encoding=3, text=self.title))
|
|
|
|
|
self.m.tags.add(TALB(encoding=3, text=self.album))
|
|
|
|
|
self.m.tags.add(TOPE(encoding=3, text=self.albumartist))
|
2024-03-19 07:23:35 +01:00
|
|
|
self.m.tags.add(TPE1(encoding=3, text=self.artists))
|
2023-12-19 23:58:57 +01:00
|
|
|
self.m.tags.add(TCOP(encoding=3, text=self.copy_right))
|
|
|
|
|
self.m.tags.add(TRCK(encoding=3, text=str(self.tracknumber)))
|
|
|
|
|
self.m.tags.add(TRCK(encoding=3, text=self.discnumber))
|
|
|
|
|
self.m.tags.add(TDRC(encoding=3, text=self.date))
|
2024-01-12 10:21:34 +01:00
|
|
|
self.m.tags.add(TCOM(encoding=3, text=", ".join(self.composer) if self.composer else ""))
|
2023-12-19 23:58:57 +01:00
|
|
|
self.m.tags.add(TSRC(encoding=3, text=self.isrc))
|
|
|
|
|
self.m.tags.add(USLT(encoding=3, lang="eng", desc="desc", text=self.lyrics))
|
|
|
|
|
|
|
|
|
|
def set_mp4(self):
|
|
|
|
|
self.m.tags["\xa9nam"] = self.title
|
|
|
|
|
self.m.tags["\xa9alb"] = self.album
|
|
|
|
|
self.m.tags["aART"] = self.albumartist
|
2024-03-19 07:23:35 +01:00
|
|
|
self.m.tags["\xa9ART"] = self.artists
|
2023-12-19 23:58:57 +01:00
|
|
|
self.m.tags["cprt"] = self.copy_right
|
|
|
|
|
self.m.tags["trkn"] = [[self.tracknumber, self.totaltrack]]
|
|
|
|
|
self.m.tags["disk"] = [[self.discnumber, self.totaldisc]]
|
|
|
|
|
# self.m.tags['\xa9gen'] = self.genre
|
|
|
|
|
self.m.tags["\xa9day"] = self.date
|
2024-01-12 10:21:34 +01:00
|
|
|
self.m.tags["\xa9wrt"] = ", ".join(self.composer) if self.composer else ""
|
2023-12-19 23:58:57 +01:00
|
|
|
self.m.tags["\xa9lyr"] = self.lyrics
|
2024-04-21 19:18:05 +02:00
|
|
|
self.m.tags["isrc"] = self.isrc
|
2024-01-10 19:41:02 +01:00
|
|
|
|
2024-03-25 16:53:27 +01:00
|
|
|
@staticmethod
|
|
|
|
|
def cover_data(url: str = None, path_file: str = None) -> str | bytes:
|
2024-01-10 19:41:02 +01:00
|
|
|
result: str | bytes = ""
|
|
|
|
|
|
|
|
|
|
if url:
|
|
|
|
|
try:
|
2024-01-12 08:38:41 +01:00
|
|
|
result = requests.get(url, timeout=REQUESTS_TIMEOUT_SEC).content
|
2024-01-12 11:41:12 +01:00
|
|
|
except Exception as e:
|
|
|
|
|
# TODO: Implement propper logging.
|
|
|
|
|
print(e)
|
2024-01-10 19:41:02 +01:00
|
|
|
elif path_file:
|
|
|
|
|
try:
|
|
|
|
|
with open(path_file, "rb") as f:
|
|
|
|
|
result = f.read()
|
2024-01-12 12:35:18 +01:00
|
|
|
except OSError as e:
|
|
|
|
|
# TODO: Implement propper logging.
|
|
|
|
|
print(e)
|
2024-01-10 19:41:02 +01:00
|
|
|
|
|
|
|
|
return result
|