musick/mobject.py
2023-06-05 09:26:36 +02:00

140 lines
4.1 KiB
Python

from mutagen.id3 import ID3, APIC, TIT2, TPE1, TALB, Encoding, PictureType
from mutagen.flac import FLAC, Picture
from pathlib import Path
import io
class MObject:
_file_bytes : bytes
_file_io : io.BytesIO
def __init__(self, fb : bytes):
self._file_bytes = fb
self._file_io = io.BytesIO(fb)
return
def get_bytes(self) -> bytes:
return self._file_io.getbuffer()
def get_title(self) -> str:
raise Exception("unimplemented")
def get_album(self) -> str:
raise Exception("unimplemented")
def get_artist(self) -> str:
raise Exception("unimplemented")
def get_cover(self) -> bytes:
raise Exception("unimplemented")
def set_artist(self, val : str) -> None:
raise Exception("unimplemented")
def set_album(self, val : str) -> None:
raise Exception("unimplemented")
def set_title(self, val : str) -> None:
raise Exception("unimplemented")
def set_cover(self, val : bytes, png : bool = False) -> None:
raise Exception("unimplemented")
class MMP3Object(MObject):
_id3 : ID3
def __init__(self, file : bytes):
super().__init__(self, file)
self._id3 = ID3()
self._id3.load(self._file_io, translate = True)
return
def get_title(self) -> str:
return self._id3.get("TIT2", default = TIT2(text = None)).text
def set_title(self, val : str) -> None:
self._id3.delall("TIT2")
self._id3.add(TIT2(text = val))
self._id3.save()
def get_album(self) -> str:
return self._id3.get("TALB", default = TALB(text = None)).text
def set_album(self, val : str) -> None:
self._id3.delall("TALB")
self._id3.add(TALB(text = val))
self._id3.save()
def get_artist(self) -> str:
return self._id3.get("TPE1", default = TPE1(text = None)).text
def set_artist(self, val : str):
self._id3.delall("TPE1")
self._id3.add(TPE1(text = val))
self._id3.save()
def get_cover(self) -> bytes:
cover = self._id3.get("APIC", default=APIC(encoding = Encoding.UTF8, mime = "image/jpeg", type=PictureType.COVER_FRONT, desc=u"Cover", data = None))
return cover.data
def set_cover(self, val : bytes, png : bool = False) -> None:
self._id3.delall("APIC")
self._id3.add(APIC(encoding = Encoding.UTF8, mime = "image/png" if png else "image/jpeg", type=PictureType.COVER_FRONT, desc=u"Cover", data = val))
self._id3.save()
class MFLACObject(MObject):
_flac : FLAC
def __init__(self, file : bytes):
super().__init__(self, file)
self._flac = FLAC(self._file_io)
return
def get_title(self) -> str:
return self._flac.get("TITLE", default = None)
def set_title(self, val : str) -> None:
self._flac["TITLE"] = val
self._flac.save()
def get_album(self) -> str:
return self._flac.get("ALBUM", default = None)
def set_album(self, val : str) -> None:
self._flac["ALBUM"] = val
self._flac.save()
def get_artist(self) -> str:
return self._flac.get("ARTIST", default = None)
def set_artist(self, val : str):
self._flac["ARTIST"] = val
self._flac.save()
def get_cover(self) -> bytes:
pics = self._flac.pictures
if len(pics) > 0:
return pics[0].data
else:
return None
def set_cover(self, val : bytes, png : bool = False) -> None:
self._flac.clear_pictures()
pic = Picture()
pic.type = PictureType.COVER_FRONT
pic.mime = "image/png" if png else "image/jpeg"
pic.desc = "Cover"
pic.data = val
self._flac.add_picture(pic)
self._flac.save()
def create_mobject(filepath : str) -> MObject:
fp = Path(filepath)
with open(fp, "rb") as f:
buf = f.read()
if (fp.suffix == "mp3"):
return MMP3Object(buf)
if (fp.suffix == "flac"):
return MFLACObject(buf)
return None