mirror of
https://github.com/Wojtek242/qobuz-dl.git
synced 2024-12-22 15:24:40 +01:00
New feature and error handling with downloads
Playlist m3u for playlist download [Enhancement]. Close #31 Fix #32 Update README.md
This commit is contained in:
parent
53eb898b0a
commit
2cd31e5a8a
@ -9,6 +9,7 @@ Search, discover and download Lossless and Hi-Res music from [Qobuz](https://www
|
||||
* Download music from last.fm playlists (Spotify, Apple Music and Youtube playlists are also supported through this method)
|
||||
* Queue support on **interactive** mode
|
||||
* Support for albums with multiple discs
|
||||
* Support for M3U playlists
|
||||
* Downloads URLs from text file
|
||||
* And more
|
||||
|
||||
@ -67,7 +68,7 @@ qobuz-dl dl https://play.qobuz.com/artist/2528676 --albums-only
|
||||
```
|
||||
|
||||
#### Last.fm playlists
|
||||
Last.fm has a new feature for creating playlists: you can create your own based on the music you listen to or you can import one from popular streaming services like Spotify, Apple Music and Youtube. Visit: `https://www.last.fm/user/<your profile>/playlists` (e.g. https://www.last.fm/user/vitiko98/playlists) to get started.
|
||||
> Last.fm has a new feature for creating playlists: you can create your own based on the music you listen to or you can import one from popular streaming services like Spotify, Apple Music and Youtube. Visit: `https://www.last.fm/user/<your profile>/playlists` (e.g. https://www.last.fm/user/vitiko98/playlists) to get started.
|
||||
|
||||
Download a last.fm playlist in the maximum quality
|
||||
```
|
||||
@ -157,7 +158,7 @@ qobuz.handle_url("https://play.qobuz.com/album/va4j3hdlwaubc")
|
||||
Attributes, methods and parameters have been named as self-explanatory as possible.
|
||||
|
||||
## A note about Qo-DL
|
||||
`qobuz-dl` is inspired in the discontinued Qo-DL-Reborn. This program uses two modules from Qo-DL: `qopy` and `spoofer`, both written by Sorrow446 and DashLt.
|
||||
`qobuz-dl` is inspired in the discontinued Qo-DL-Reborn. This tool uses two modules from Qo-DL: `qopy` and `spoofer`, both written by Sorrow446 and DashLt.
|
||||
## Disclaimer
|
||||
* This tool was written for educational purposes. I will not be responsible if you use this program in bad faith. By using it, you are accepting the [Qobuz API Terms of Use](https://static.qobuz.com/apps/api/QobuzAPI-TermsofUse.pdf).
|
||||
* `qobuz-dl` is not affiliated with Qobuz
|
||||
|
@ -53,6 +53,7 @@ class QobuzDL:
|
||||
interactive_limit=20,
|
||||
ignore_singles_eps=False,
|
||||
no_m3u_for_playlists=False,
|
||||
raise_request_exceptions=False,
|
||||
):
|
||||
self.directory = self.create_dir(directory)
|
||||
self.quality = quality
|
||||
@ -353,7 +354,7 @@ class QobuzDL:
|
||||
|
||||
pl_title = sanitize_filename(soup.select_one("h1").text)
|
||||
pl_directory = os.path.join(self.directory, pl_title)
|
||||
print("Downloading playlist: " + pl_title)
|
||||
print("Downloading playlist: {} ({} tracks)".format(pl_title, len(track_list)))
|
||||
|
||||
for i in track_list:
|
||||
track_id = self.get_id(self.search_by_type(i, "track", 1, lucky=True)[0])
|
||||
@ -365,30 +366,44 @@ class QobuzDL:
|
||||
def make_m3u(self, pl_directory):
|
||||
if self.no_m3u_for_playlists:
|
||||
return
|
||||
|
||||
track_list = ["#EXTM3U"]
|
||||
pl_name = os.path.basename(os.path.normpath(pl_directory)) + ".m3u"
|
||||
rel_folder = os.path.basename(os.path.normpath(pl_directory))
|
||||
pl_name = rel_folder + ".m3u"
|
||||
for local, dirs, files in os.walk(pl_directory):
|
||||
dirs.sort()
|
||||
audio_rel_files = [
|
||||
# os.path.abspath(os.path.join(local, file_))
|
||||
# os.path.join(rel_folder, os.path.basename(os.path.normpath(local)), file_)
|
||||
os.path.join(os.path.basename(os.path.normpath(local)), file_)
|
||||
for file_ in files
|
||||
if os.path.splitext(file_)[-1] in EXTENSIONS
|
||||
]
|
||||
audio_files = [
|
||||
os.path.abspath(os.path.join(local, file_))
|
||||
for file_ in files
|
||||
if os.path.splitext(file_)[-1] in EXTENSIONS
|
||||
]
|
||||
if not audio_files:
|
||||
if not audio_files or len(audio_files) != len(audio_rel_files):
|
||||
continue
|
||||
for audio in audio_files:
|
||||
|
||||
for audio_rel_file, audio_file in zip(audio_rel_files, audio_files):
|
||||
try:
|
||||
pl_item = EasyMP3(audio) if ".mp3" in audio else FLAC(audio)
|
||||
pl_item = (
|
||||
EasyMP3(audio_file)
|
||||
if ".mp3" in audio_file
|
||||
else FLAC(audio_file)
|
||||
)
|
||||
title = pl_item["TITLE"][0]
|
||||
artist = pl_item["ARTIST"][0]
|
||||
length = int(pl_item.info.length)
|
||||
index = "#EXTINF:{}, {} - {}\n{}".format(
|
||||
length, artist, title, audio
|
||||
length, artist, title, audio_rel_file
|
||||
)
|
||||
except: # noqa
|
||||
continue
|
||||
track_list.append(index)
|
||||
|
||||
if len(track_list) > 1:
|
||||
with open(os.path.join(self.directory, pl_name), "w") as pl:
|
||||
with open(os.path.join(pl_directory, pl_name), "w") as pl:
|
||||
pl.write("\n\n".join(track_list))
|
||||
|
@ -46,7 +46,7 @@ def get_format(client, item_dict, quality, is_track_id=False):
|
||||
):
|
||||
return "FLAC"
|
||||
return "Hi-Res"
|
||||
except KeyError:
|
||||
except (KeyError, requests.exceptions.HTTPError):
|
||||
return "Unknown"
|
||||
|
||||
|
||||
@ -196,7 +196,11 @@ def download_id_by_type(
|
||||
media_numbers = [track["media_number"] for track in meta["tracks"]["items"]]
|
||||
is_multiple = True if len([*{*media_numbers}]) > 1 else False
|
||||
for i in meta["tracks"]["items"]:
|
||||
parse = client.get_track_url(i["id"], quality)
|
||||
try:
|
||||
parse = client.get_track_url(i["id"], quality)
|
||||
except requests.exceptions.HTTPError:
|
||||
print("Nothing found")
|
||||
continue
|
||||
if "sample" not in parse and parse["sampling_rate"]:
|
||||
is_mp3 = True if int(quality) == 5 else False
|
||||
download_and_tag(
|
||||
@ -214,7 +218,11 @@ def download_id_by_type(
|
||||
print("Demo. Skipping")
|
||||
count = count + 1
|
||||
else:
|
||||
parse = client.get_track_url(item_id, quality)
|
||||
try:
|
||||
parse = client.get_track_url(item_id, quality)
|
||||
except requests.exceptions.HTTPError:
|
||||
print("Nothing found")
|
||||
return
|
||||
|
||||
if "sample" not in parse and parse["sampling_rate"]:
|
||||
meta = client.get_track_meta(item_id)
|
||||
|
Loading…
Reference in New Issue
Block a user