mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-19 01:35:24 -04:00
Misc enhancements
This commit is contained in:
parent
02eb2cdc9a
commit
1253d20173
4 changed files with 42 additions and 11 deletions
|
@ -241,6 +241,9 @@ class QobuzClient(Client):
|
|||
epoint = f"{media_type}/get"
|
||||
|
||||
response, status_code = self._api_request(epoint, params)
|
||||
if status_code != 200:
|
||||
raise Exception(f'Error fetching metadata. "{response["message"]}"')
|
||||
|
||||
return response
|
||||
|
||||
def _api_search(self, query, media_type, limit=500) -> Generator:
|
||||
|
@ -410,6 +413,8 @@ class TidalClient(Client):
|
|||
source = "tidal"
|
||||
max_quality = 3
|
||||
|
||||
# ----------- Public Methods --------------
|
||||
|
||||
def __init__(self):
|
||||
self.logged_in = False
|
||||
|
||||
|
@ -461,7 +466,10 @@ class TidalClient(Client):
|
|||
}
|
||||
return self._api_request(f"search/{media_type}s", params=params)
|
||||
|
||||
def get_file_url(self, track_id, quality: int = 3):
|
||||
def get_file_url(self, track_id, quality: int = 3, video=False):
|
||||
if video:
|
||||
return self._get_video_stream_url(track_id)
|
||||
|
||||
params = {
|
||||
"audioquality": get_quality(min(quality, TIDAL_MAX_Q), self.source),
|
||||
"playbackmode": "STREAM",
|
||||
|
@ -492,6 +500,8 @@ class TidalClient(Client):
|
|||
)
|
||||
}
|
||||
|
||||
# ------------ Utilities to login -------------
|
||||
|
||||
def _login_new_user(self, launch=True):
|
||||
login_link = f"https://{self._get_device_code()}"
|
||||
|
||||
|
@ -613,6 +623,15 @@ class TidalClient(Client):
|
|||
self.access_token = token
|
||||
self._update_authorization()
|
||||
|
||||
def _update_authorization(self):
|
||||
self.session.headers.update(self.authorization)
|
||||
|
||||
@property
|
||||
def authorization(self):
|
||||
return {"authorization": f"Bearer {self.access_token}"}
|
||||
|
||||
# ------------- Fetch data ------------------
|
||||
|
||||
def _api_get(self, item_id: str, media_type: str) -> dict:
|
||||
url = f"{media_type}s/{item_id}"
|
||||
item = self._api_request(url)
|
||||
|
@ -644,13 +663,22 @@ class TidalClient(Client):
|
|||
r = self.session.get(f"{TIDAL_BASE}/{path}", params=params).json()
|
||||
return r
|
||||
|
||||
def _get_video_stream_url(self, video_id) -> str:
|
||||
params = {
|
||||
"videoquality": "HIGH",
|
||||
"playbackmode": "STREAM",
|
||||
"assetpresentation": "FULL",
|
||||
}
|
||||
resp = self._api_request(
|
||||
f"videos/{video_id}/playbackinfopostpaywall", params=params
|
||||
)
|
||||
manifest = json.loads(base64.b64decode(resp['manifest']).decode("utf-8"))
|
||||
return manifest['urls'][0]
|
||||
|
||||
def _api_post(self, url, data, auth=None):
|
||||
r = self.session.post(url, data=data, auth=auth, verify=False).json()
|
||||
return r
|
||||
|
||||
def _update_authorization(self):
|
||||
self.session.headers.update({"authorization": f"Bearer {self.access_token}"})
|
||||
|
||||
|
||||
class SoundCloudClient(Client):
|
||||
source = "soundcloud"
|
||||
|
|
|
@ -158,7 +158,8 @@ TIDAL_Q_MAP = {
|
|||
|
||||
DEEZER_MAX_Q = 6
|
||||
AVAILABLE_QUALITY_IDS = (0, 1, 2, 3, 4)
|
||||
MEDIA_TYPES = ("track", "album", "artist", "label", "playlist")
|
||||
# video only for tidal
|
||||
MEDIA_TYPES = {"track", "album", "artist", "label", "playlist", "video"}
|
||||
|
||||
# used to homogenize cover size keys
|
||||
COVER_SIZES = ("thumbnail", "small", "large", "original")
|
||||
|
|
|
@ -10,6 +10,7 @@ import re
|
|||
import shutil
|
||||
import subprocess
|
||||
from tempfile import gettempdir
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, Generator, Iterable, Union
|
||||
|
||||
import click
|
||||
|
@ -812,7 +813,7 @@ class Album(Tracklist):
|
|||
return Playlist.from_api(resp, client)
|
||||
|
||||
info = cls._parse_get_resp(resp, client)
|
||||
return cls(client, **info)
|
||||
return cls(client, **info.asdict())
|
||||
|
||||
def _prepare_download(self, **kwargs):
|
||||
self.folder_format = kwargs.get("folder_format", FOLDER_FORMAT)
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
import logging
|
||||
import re
|
||||
from typing import Generator, Hashable, Optional, Tuple, Union
|
||||
from collections import OrderedDict
|
||||
|
||||
from .constants import (
|
||||
COPYRIGHT,
|
||||
|
@ -136,7 +137,7 @@ class TrackMetadata:
|
|||
|
||||
# Non-embedded information
|
||||
self.version = resp.get("version")
|
||||
self.cover_urls = resp.get("image")
|
||||
self.cover_urls = OrderedDict(resp.get("image"))
|
||||
self.cover_urls["original"] = self.cover_urls["large"].replace("600", "org")
|
||||
self.streamable = resp.get("streamable", False)
|
||||
self.bit_depth = resp.get("maximum_bit_depth")
|
||||
|
@ -162,10 +163,10 @@ class TrackMetadata:
|
|||
self.explicit = resp.get("explicit", False)
|
||||
# 80, 160, 320, 640, 1280
|
||||
uuid = resp.get("cover")
|
||||
self.cover_urls = {
|
||||
self.cover_urls = OrderedDict({
|
||||
sk: tidal_cover_url(uuid, size)
|
||||
for sk, size in zip(COVER_SIZES, (160, 320, 640, 1280))
|
||||
}
|
||||
})
|
||||
self.streamable = resp.get("allowStreaming", False)
|
||||
self.quality = TIDAL_Q_MAP[resp["audioQuality"]]
|
||||
|
||||
|
@ -185,13 +186,13 @@ class TrackMetadata:
|
|||
self.explicit = bool(resp.get("parental_warning"))
|
||||
self.quality = 2
|
||||
self.bit_depth = 16
|
||||
self.cover_urls = {
|
||||
self.cover_urls = OrderedDict({
|
||||
sk: resp.get(rk) # size key, resp key
|
||||
for sk, rk in zip(
|
||||
COVER_SIZES,
|
||||
("cover", "cover_medium", "cover_large", "cover_xl"),
|
||||
)
|
||||
}
|
||||
})
|
||||
self.sampling_rate = 44100
|
||||
self.streamable = True
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue