mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-31 07:18:26 -04:00
Fix issues with converting single tracks
This commit is contained in:
parent
86d877f1f5
commit
383159d5f4
5 changed files with 68 additions and 33 deletions
|
@ -83,13 +83,9 @@ class Track:
|
||||||
self.id = None
|
self.id = None
|
||||||
self.__dict__.update(kwargs)
|
self.__dict__.update(kwargs)
|
||||||
|
|
||||||
# TODO: remove these
|
|
||||||
self.container = "FLAC"
|
|
||||||
self.sampling_rate = 44100
|
|
||||||
self.bit_depth = 16
|
|
||||||
|
|
||||||
self.downloaded = False
|
self.downloaded = False
|
||||||
self.tagged = False
|
self.tagged = False
|
||||||
|
self.converted = False
|
||||||
# TODO: find better solution
|
# TODO: find better solution
|
||||||
for attr in ("quality", "folder", "meta"):
|
for attr in ("quality", "folder", "meta"):
|
||||||
setattr(self, attr, None)
|
setattr(self, attr, None)
|
||||||
|
@ -440,24 +436,37 @@ class Track:
|
||||||
if album_meta is not None:
|
if album_meta is not None:
|
||||||
self.meta.add_album_meta(album_meta) # extend meta with album info
|
self.meta.add_album_meta(album_meta) # extend meta with album info
|
||||||
|
|
||||||
if self.quality in (2, 3, 4):
|
# TODO: make this cleaner
|
||||||
self.container = "FLAC"
|
if self.converted:
|
||||||
logger.debug("Tagging file with %s container", self.container)
|
if self.container == 'FLAC':
|
||||||
audio = FLAC(self.path)
|
audio = FLAC(self.path)
|
||||||
elif self.quality <= 1:
|
elif self.container in ("AAC", "ALAC", "MP4"):
|
||||||
if self.client.source == "tidal":
|
|
||||||
self.container = "AAC"
|
|
||||||
audio = MP4(self.path)
|
audio = MP4(self.path)
|
||||||
else:
|
elif self.container == 'MP3':
|
||||||
self.container = "MP3"
|
audio = ID3()
|
||||||
try:
|
try:
|
||||||
audio = ID3(self.path)
|
audio = ID3(self.path)
|
||||||
except ID3NoHeaderError:
|
except ID3NoHeaderError:
|
||||||
audio = ID3()
|
audio = ID3()
|
||||||
|
|
||||||
logger.debug("Tagging file with %s container", self.container)
|
|
||||||
else:
|
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
|
# automatically generate key, value pairs based on container
|
||||||
tags = self.meta.tags(self.container)
|
tags = self.meta.tags(self.container)
|
||||||
|
@ -467,7 +476,7 @@ class Track:
|
||||||
if embed_cover and cover is None:
|
if embed_cover and cover is None:
|
||||||
assert hasattr(self, "cover_path")
|
assert hasattr(self, "cover_path")
|
||||||
cover = Tracklist.get_cover_obj(
|
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):
|
if isinstance(audio, FLAC):
|
||||||
|
@ -547,6 +556,8 @@ class Track:
|
||||||
if not kwargs.get("stay_temp", False):
|
if not kwargs.get("stay_temp", False):
|
||||||
self.move(self.final_path)
|
self.move(self.final_path)
|
||||||
|
|
||||||
|
self.converted = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def title(self) -> str:
|
def title(self) -> str:
|
||||||
"""The title of the track.
|
"""The title of the track.
|
||||||
|
@ -848,7 +859,7 @@ class Tracklist(list):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_cover_obj(
|
def get_cover_obj(
|
||||||
cover_path: str, quality: int, source: str
|
cover_path: str, container: str, source: str
|
||||||
) -> Union[Picture, APIC]:
|
) -> Union[Picture, APIC]:
|
||||||
"""Given the path to an image and a quality id, return an initialized
|
"""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.
|
cover object that can be used for every track in the album.
|
||||||
|
@ -869,12 +880,14 @@ class Tracklist(list):
|
||||||
|
|
||||||
return cover_obj
|
return cover_obj
|
||||||
|
|
||||||
if quality > 1:
|
if container == 'FLAC':
|
||||||
cover = Picture
|
cover = Picture
|
||||||
elif source == "tidal":
|
elif container == 'MP3':
|
||||||
|
cover = APIC
|
||||||
|
elif container in ('AAC', 'ALAC', 'MP4'):
|
||||||
cover = MP4Cover
|
cover = MP4Cover
|
||||||
else:
|
else:
|
||||||
cover = APIC
|
raise Exception(container)
|
||||||
|
|
||||||
if cover is Picture:
|
if cover is Picture:
|
||||||
size_ = os.path.getsize(cover_path)
|
size_ = os.path.getsize(cover_path)
|
||||||
|
@ -891,8 +904,6 @@ class Tracklist(list):
|
||||||
with open(cover_path, "rb") as img:
|
with open(cover_path, "rb") as img:
|
||||||
return cover(img.read(), imageformat=MP4Cover.FORMAT_JPEG)
|
return cover(img.read(), imageformat=MP4Cover.FORMAT_JPEG)
|
||||||
|
|
||||||
raise InvalidQuality(f"Quality {quality} not allowed")
|
|
||||||
|
|
||||||
def download_message(self) -> str:
|
def download_message(self) -> str:
|
||||||
"""The message to display after calling `Tracklist.download`.
|
"""The message to display after calling `Tracklist.download`.
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,9 @@ def filter_discography(ctx, **kwargs):
|
||||||
def search(ctx, **kwargs):
|
def search(ctx, **kwargs):
|
||||||
"""Search and download media in interactive mode.
|
"""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:
|
Example usage:
|
||||||
|
|
||||||
$ rip search 'fleetwood mac rumours'
|
$ rip search 'fleetwood mac rumours'
|
||||||
|
|
|
@ -186,6 +186,8 @@ class MusicDL(list):
|
||||||
item.download(**arguments)
|
item.download(**arguments)
|
||||||
if isinstance(item, Track):
|
if isinstance(item, Track):
|
||||||
item.tag()
|
item.tag()
|
||||||
|
if arguments['conversion']['enabled']:
|
||||||
|
item.convert(**arguments['conversion'])
|
||||||
|
|
||||||
if self.db != [] and hasattr(item, "id"):
|
if self.db != [] and hasattr(item, "id"):
|
||||||
self.db.add(item.id)
|
self.db.add(item.id)
|
||||||
|
|
|
@ -18,7 +18,7 @@ from .constants import ALBUM_KEYS, FLAC_MAX_BLOCKSIZE, FOLDER_FORMAT
|
||||||
from .db import MusicDB
|
from .db import MusicDB
|
||||||
from .exceptions import InvalidSourceError, NonStreamable
|
from .exceptions import InvalidSourceError, NonStreamable
|
||||||
from .metadata import TrackMetadata
|
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__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -132,8 +132,9 @@ class Album(Tracklist):
|
||||||
|
|
||||||
embed_cover = kwargs.get("embed_cover", True) # embed by default
|
embed_cover = kwargs.get("embed_cover", True) # embed by default
|
||||||
if self.client.source != "deezer" and embed_cover:
|
if self.client.source != "deezer" and embed_cover:
|
||||||
|
# container generated when formatting folder name
|
||||||
self.cover_obj = self.get_cover_obj(
|
self.cover_obj = self.get_cover_obj(
|
||||||
cover_path, self.quality, self.client.source
|
cover_path, self.container, self.client.source
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.cover_obj = None
|
self.cover_obj = None
|
||||||
|
@ -220,14 +221,11 @@ class Album(Tracklist):
|
||||||
return fmt
|
return fmt
|
||||||
|
|
||||||
def _get_formatted_folder(self, parent_folder: str, quality: int) -> str:
|
def _get_formatted_folder(self, parent_folder: str, quality: int) -> str:
|
||||||
if quality >= 2:
|
# necessary to format the folder
|
||||||
self.container = "FLAC"
|
self.container = get_container(quality, self.client.source)
|
||||||
else:
|
if self.container in ('AAC', 'MP3'):
|
||||||
|
# lossy codecs don't have these metrics
|
||||||
self.bit_depth = self.sampling_rate = None
|
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())
|
formatted_folder = clean_format(self.folder_format, self._get_formatter())
|
||||||
|
|
||||||
|
|
|
@ -277,3 +277,24 @@ def extract_interpreter_url(url: str) -> str:
|
||||||
r = session.get(url)
|
r = session.get(url)
|
||||||
artist_id = re.search(r"getSimilarArtist\(\s*'(\w+)'", r.text).group(1)
|
artist_id = re.search(r"getSimilarArtist\(\s*'(\w+)'", r.text).group(1)
|
||||||
return artist_id
|
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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue