Fix issues with converting single tracks

This commit is contained in:
nathom 2021-04-19 13:25:49 -07:00
parent 86d877f1f5
commit 383159d5f4
5 changed files with 68 additions and 33 deletions

View file

@ -83,13 +83,9 @@ class Track:
self.id = None
self.__dict__.update(kwargs)
# TODO: remove these
self.container = "FLAC"
self.sampling_rate = 44100
self.bit_depth = 16
self.downloaded = False
self.tagged = False
self.converted = False
# TODO: find better solution
for attr in ("quality", "folder", "meta"):
setattr(self, attr, None)
@ -440,24 +436,37 @@ class Track:
if album_meta is not None:
self.meta.add_album_meta(album_meta) # extend meta with album info
if self.quality in (2, 3, 4):
self.container = "FLAC"
logger.debug("Tagging file with %s container", self.container)
audio = FLAC(self.path)
elif self.quality <= 1:
if self.client.source == "tidal":
self.container = "AAC"
# TODO: make this cleaner
if self.converted:
if self.container == 'FLAC':
audio = FLAC(self.path)
elif self.container in ("AAC", "ALAC", "MP4"):
audio = MP4(self.path)
else:
self.container = "MP3"
elif self.container == 'MP3':
audio = ID3()
try:
audio = ID3(self.path)
except ID3NoHeaderError:
audio = ID3()
logger.debug("Tagging file with %s container", self.container)
else:
raise InvalidQuality(f'Invalid quality: "{self.quality}"')
if self.quality in (2, 3, 4):
self.container = "FLAC"
logger.debug("Tagging file with %s container", self.container)
audio = FLAC(self.path)
elif self.quality <= 1:
if self.client.source == "tidal":
self.container = "AAC"
audio = MP4(self.path)
else:
self.container = "MP3"
try:
audio = ID3(self.path)
except ID3NoHeaderError:
audio = ID3()
logger.debug("Tagging file with %s container", self.container)
else:
raise InvalidQuality(f'Invalid quality: "{self.quality}"')
# automatically generate key, value pairs based on container
tags = self.meta.tags(self.container)
@ -467,7 +476,7 @@ class Track:
if embed_cover and cover is None:
assert hasattr(self, "cover_path")
cover = Tracklist.get_cover_obj(
self.cover_path, self.quality, self.client.source
self.cover_path, self.container, self.client.source
)
if isinstance(audio, FLAC):
@ -547,6 +556,8 @@ class Track:
if not kwargs.get("stay_temp", False):
self.move(self.final_path)
self.converted = True
@property
def title(self) -> str:
"""The title of the track.
@ -848,7 +859,7 @@ class Tracklist(list):
@staticmethod
def get_cover_obj(
cover_path: str, quality: int, source: str
cover_path: str, container: str, source: str
) -> Union[Picture, APIC]:
"""Given the path to an image and a quality id, return an initialized
cover object that can be used for every track in the album.
@ -869,12 +880,14 @@ class Tracklist(list):
return cover_obj
if quality > 1:
if container == 'FLAC':
cover = Picture
elif source == "tidal":
elif container == 'MP3':
cover = APIC
elif container in ('AAC', 'ALAC', 'MP4'):
cover = MP4Cover
else:
cover = APIC
raise Exception(container)
if cover is Picture:
size_ = os.path.getsize(cover_path)
@ -891,8 +904,6 @@ class Tracklist(list):
with open(cover_path, "rb") as img:
return cover(img.read(), imageformat=MP4Cover.FORMAT_JPEG)
raise InvalidQuality(f"Quality {quality} not allowed")
def download_message(self) -> str:
"""The message to display after calling `Tracklist.download`.

View file

@ -143,6 +143,9 @@ def filter_discography(ctx, **kwargs):
def search(ctx, **kwargs):
"""Search and download media in interactive mode.
The QUERY must be surrounded in quotes if it contains spaces. If your query
contains single quotes, use double quotes, and vice versa.
Example usage:
$ rip search 'fleetwood mac rumours'

View file

@ -186,6 +186,8 @@ class MusicDL(list):
item.download(**arguments)
if isinstance(item, Track):
item.tag()
if arguments['conversion']['enabled']:
item.convert(**arguments['conversion'])
if self.db != [] and hasattr(item, "id"):
self.db.add(item.id)

View file

@ -18,7 +18,7 @@ from .constants import ALBUM_KEYS, FLAC_MAX_BLOCKSIZE, FOLDER_FORMAT
from .db import MusicDB
from .exceptions import InvalidSourceError, NonStreamable
from .metadata import TrackMetadata
from .utils import clean_format, safe_get, tidal_cover_url, tqdm_download
from .utils import clean_format, safe_get, tidal_cover_url, tqdm_download, get_container
logger = logging.getLogger(__name__)
@ -132,8 +132,9 @@ class Album(Tracklist):
embed_cover = kwargs.get("embed_cover", True) # embed by default
if self.client.source != "deezer" and embed_cover:
# container generated when formatting folder name
self.cover_obj = self.get_cover_obj(
cover_path, self.quality, self.client.source
cover_path, self.container, self.client.source
)
else:
self.cover_obj = None
@ -220,14 +221,11 @@ class Album(Tracklist):
return fmt
def _get_formatted_folder(self, parent_folder: str, quality: int) -> str:
if quality >= 2:
self.container = "FLAC"
else:
# necessary to format the folder
self.container = get_container(quality, self.client.source)
if self.container in ('AAC', 'MP3'):
# lossy codecs don't have these metrics
self.bit_depth = self.sampling_rate = None
if self.client.source == "tidal":
self.container = "AAC"
else:
self.container = "MP3"
formatted_folder = clean_format(self.folder_format, self._get_formatter())

View file

@ -277,3 +277,24 @@ def extract_interpreter_url(url: str) -> str:
r = session.get(url)
artist_id = re.search(r"getSimilarArtist\(\s*'(\w+)'", r.text).group(1)
return artist_id
def get_container(quality: int, source: str) -> str:
"""Get the "container" given the quality. `container` can also be the
the codec; both work.
:param quality: quality id
:type quality: int
:param source:
:type source: str
:rtype: str
"""
if quality >= 2:
container = "FLAC"
else:
if source == "tidal":
container = "AAC"
else:
container = "MP3"
return container