Skip to content

Commit fe580b8

Browse files
authored
Publish 3.9.1
2 parents 8474fee + 0f71cdb commit fe580b8

28 files changed

+45039
-28078
lines changed

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Dockerfile
2+
3+
# Ignore .git folder
4+
.git

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM python:3-alpine
2+
3+
# Install ffmpeg and g++
4+
RUN apk add --no-cache ffmpeg g++
5+
6+
# Create project directory
7+
WORKDIR /app
8+
9+
# Add source code files to WORKDIR
10+
ADD . .
11+
12+
# Upgrade pip
13+
RUN python -m pip install --upgrade --no-cache-dir pip
14+
15+
# Install spotdl
16+
RUN pip install --no-cache-dir .
17+
18+
# Create music directory
19+
RUN mkdir /music
20+
WORKDIR /music
21+
22+
# Entrypoint command
23+
ENTRYPOINT [ "spotdl" ]

README.md

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,28 +38,28 @@ spotDL is being redesigned! This means we are currently not accepting new featur
3838

3939
## Prerequisites
4040

41-
- Python 3.6.1 or above (added to PATH)
42-
- FFmpeg 4.2 or above (added to PATH)
41+
- Python 3.6.1 or above (added to PATH)
42+
- FFmpeg 4.2 or above (added to PATH)
4343

4444
> **_YouTube Music must be available in your country for spotDL to work. This is because we use YouTube Music to filter search results. You can check if YouTube Music is available in your country, by visiting [YouTube Music](https://music.youtube.com)._**
4545
4646
## Installation
4747

4848
### Installing FFmpeg
4949

50-
- [Windows Tutorial](https://windowsloop.com/install-ffmpeg-windows-10/)
51-
- OSX - `brew install ffmpeg`
52-
- Linux - `sudo apt install ffmpeg`
50+
- [Windows Tutorial](https://windowsloop.com/install-ffmpeg-windows-10/)
51+
- OSX - `brew install ffmpeg`
52+
- Linux - `sudo apt install ffmpeg`
5353

5454
### Installing spotDL
5555

56-
- Recommended Stable Version:
56+
- Recommended Stable Version:
5757

5858
```bash
5959
pip install spotdl
6060
```
6161

62-
- Dev Version: **(NOT STABLE)**
62+
- Dev Version: **(NOT STABLE)**
6363

6464
```bash
6565
pip install https://codeload.github.com/spotDL/spotify-downloader/zip/dev
@@ -81,7 +81,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
8181

8282
## Usage
8383

84-
- #### To download a song, run
84+
- #### To download a song, run
8585

8686
```bash
8787
spotdl [trackUrl]
@@ -93,7 +93,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
9393
spotdl https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b
9494
```
9595

96-
- #### To download an album, run
96+
- #### To download an album, run
9797

9898
```bash
9999
spotdl [albumUrl]
@@ -105,7 +105,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
105105
spotdl https://open.spotify.com/album/4yP0hdKOZPNshxUOjY0cZj
106106
```
107107

108-
- #### To download a playlist, run
108+
- #### To download a playlist, run
109109

110110
```bash
111111
spotdl [playlistUrl]
@@ -117,7 +117,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
117117
spotdl https://open.spotify.com/playlist/37i9dQZF1E8UXBoz02kGID
118118
```
119119

120-
- #### To download all songs from an artist run
120+
- #### To download all songs from an artist run
121121

122122
```bash
123123
spotdl [artistUrl]
@@ -129,7 +129,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
129129
spotdl https://open.spotify.com/artist/1fZAAHNWdSM5gqbi9o5iEA
130130
```
131131

132-
- #### To search for and download a song, run, **with quotation marks**
132+
- #### To search for and download a song, run, **with quotation marks**
133133

134134
```bash
135135
spotdl '[songQuery]'
@@ -143,7 +143,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
143143

144144
> _Note: This is not accurate and often causes errors._
145145

146-
- #### To resume a failed/incomplete download, run
146+
- #### To resume a failed/incomplete download, run
147147

148148
```bash
149149
spotdl [pathToTrackingFile]
@@ -157,7 +157,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
157157

158158
> _Note: `.spotdlTrackingFile`s are automatically created when a download starts and deleted on completion_
159159

160-
- #### You can queue up multiple download tasks by separating the arguments with spaces
160+
- #### You can queue up multiple download tasks by separating the arguments with spaces
161161

162162
```bash
163163
spotdl [songQuery1] [albumUrl] [songQuery2] ... (order does not matter)
@@ -171,7 +171,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
171171

172172
> _Note: spotDL downloads up to 4 songs in parallel, so for a faster experience, download albums and playlist, rather than tracks._
173173

174-
- #### To download youtube video with metadata from spotify run:
174+
- #### To download youtube video with metadata from spotify, run
175175

176176
```bash
177177
spotdl "YouTubeURL|SpotifyURL"
@@ -185,7 +185,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
185185

186186
> Note: Urls have to be separated with `|` and quoted properly ex. "YouTubeURL|SpotifyUrl"
187187

188-
- #### To download songs with different output format run
188+
- #### To download songs with different output format run
189189

190190
```bash
191191
spotdl [songUrl] --output-format mp3/m4a/flac/opus/ogg/wav
@@ -197,7 +197,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
197197
spotdl [songUrl] --output-format opus
198198
```
199199

200-
- #### To use ffmpeg binary that is not on PATH run
200+
- #### To use ffmpeg binary that is not on PATH run
201201

202202
```bash
203203
spotdl [songUrl] --ffmpeg path/to/your/ffmpeg.exe
@@ -209,7 +209,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
209209
spotdl [songUrl] --ffmpeg C:\ffmpeg\bin\ffmpeg.exe
210210
```
211211

212-
- #### To generate .m3u file for each playlist run
212+
- #### To generate .m3u file for each playlist run
213213

214214
```bash
215215
spotdl [playlistUrl] --m3u
@@ -221,7 +221,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
221221
spotdl https://open.spotify.com/playlist/37i9dQZF1E8UXBoz02kGID --m3u
222222
```
223223

224-
- #### To use youtube instead of youtube music run
224+
- #### To use youtube instead of youtube music run
225225

226226
```bash
227227
spotdl [songUrl] --use-youtube
@@ -233,7 +233,23 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
233233
spotdl https://open.spotify.com/track/4fzsfWzRhPawzqhX8Qt9F3 --use-youtube
234234
```
235235

236-
- #### To change number of threads used when downloading songs run
236+
- #### To manually choose a lyrics provider, run
237+
238+
```bash
239+
spotdl [songUrl] --lyrics-provider lyrics_provider
240+
```
241+
242+
available lyrics providers:
243+
- genius
244+
- musixmatch
245+
246+
example:
247+
248+
```bash
249+
spotdl https://open.spotify.com/track/4fzsfWzRhPawzqhX8Qt9F3 --lyrics-provider genius
250+
```
251+
252+
- #### To change number of threads used when downloading songs run
237253

238254
```bash
239255
spotdl [songUrl] --dt [number]
@@ -245,7 +261,7 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
245261
spotdl https://open.spotify.com/track/4fzsfWzRhPawzqhX8Qt9F3 --dt 8
246262
```
247263

248-
- #### To change number of threads used when searching for songs run
264+
- #### To change number of threads used when searching for songs run
249265

250266
```bash
251267
spotdl [songUrl] --st [number]
@@ -257,19 +273,20 @@ There is an Arch User Repository (AUR) package for [spotDL](https://aur.archlinu
257273
spotdl https://open.spotify.com/track/4fzsfWzRhPawzqhX8Qt9F3 --st 8
258274
```
259275

260-
- #### To ignore your ffmpeg version run
276+
- #### To ignore your ffmpeg version run
261277

262278
```bash
263279
spotdl [songUrl] --ignore-ffmpeg-version
264280
```
265281

266-
- #### To use path template
282+
- #### To use path template
267283

268284
```bash
269285
spotdl [songUrl] --path-template 'template'
270286
```
271287

272288
example:
289+
273290
```bash
274291
spotdl https://open.spotify.com/track/0VjIjW4GlUZAMYd2vXMi3b --path-template '{artist}/{album}/{title} - {artist}.{ext}'
275292
```

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[metadata]
2-
version = 3.9.0
2+
version = 3.9.1
33

44
name = spotdl
55
url = https://github.com/spotDL/spotify-downloader

spotdl/console/__init__.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import sys
3+
from pathlib import Path
34
import signal
4-
import pkg_resources
55

66
from spotdl.download import ffmpeg, DownloadManager
77
from spotdl.parsers import parse_arguments, parse_query
@@ -14,23 +14,20 @@ def console_entry_point():
1414
Its super simple, rudimentary even but, it's dead simple & it works.
1515
"""
1616

17-
# If -v parameter is specified print version and exit
18-
if len(sys.argv) >= 2 and sys.argv[1] in ["-v", "--version"]:
19-
version = pkg_resources.require("spotdl")[0].version
20-
print(version)
21-
sys.exit(0)
22-
23-
# Parser arguments
17+
# Parse arguments
2418
arguments = parse_arguments()
2519

2620
# Convert arguments to dict
2721
args_dict = vars(arguments)
2822

23+
if arguments.ffmpeg:
24+
args_dict["ffmpeg"] = str(Path(arguments.ffmpeg).absolute())
25+
else:
26+
args_dict["ffmpeg"] = "ffmpeg"
27+
2928
# Check if ffmpeg has correct version, if not exit
3029
if (
31-
ffmpeg.has_correct_version(
32-
arguments.ignore_ffmpeg_version, arguments.ffmpeg or "ffmpeg"
33-
)
30+
ffmpeg.has_correct_version(arguments.ignore_ffmpeg_version, args_dict["ffmpeg"])
3431
is False
3532
):
3633
sys.exit(1)
@@ -85,6 +82,7 @@ def graceful_exit(signal, frame):
8582
arguments.generate_m3u,
8683
arguments.lyrics_provider,
8784
arguments.search_threads,
85+
arguments.path_template,
8886
)
8987

9088
# Start downloading

spotdl/download/downloader.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,6 @@ async def download_song(self, song_object: SongObject) -> None:
163163
song_object, self.arguments["output_format"]
164164
)
165165

166-
converted_file_path.parent.mkdir(parents=True, exist_ok=True)
167-
168166
# if a song is already downloaded skip it
169167
if converted_file_path.is_file():
170168
if self.display_manager:
@@ -176,10 +174,12 @@ async def download_song(self, song_object: SongObject) -> None:
176174
# ! it here as a continent way to avoid executing the rest of the function.
177175
return None
178176

177+
converted_file_path.parent.mkdir(parents=True, exist_ok=True)
178+
179179
if self.arguments["output_format"] == "m4a":
180-
ytdl_format = "bestaudio[ext=m4a]"
180+
ytdl_format = "bestaudio[ext=m4a]/bestaudio/best"
181181
elif self.arguments["output_format"] == "opus":
182-
ytdl_format = "bestaudio[ext=webm]"
182+
ytdl_format = "bestaudio[ext=webm]/bestaudio/best"
183183
else:
184184
ytdl_format = "bestaudio"
185185

@@ -199,7 +199,7 @@ async def download_song(self, song_object: SongObject) -> None:
199199

200200
try:
201201
downloaded_file_path_string = await self._perform_audio_download_async(
202-
converted_file_path.name.split(".")[0],
202+
converted_file_path.name.rsplit(".", 1)[0],
203203
temp_folder,
204204
audio_handler,
205205
song_object.youtube_link,
@@ -220,16 +220,19 @@ async def download_song(self, song_object: SongObject) -> None:
220220

221221
downloaded_file_path = Path(downloaded_file_path_string)
222222

223-
if self.arguments["output_format"] != "m4a":
223+
if (
224+
downloaded_file_path.suffix == ".m4a"
225+
and self.arguments["output_format"] == "m4a"
226+
):
227+
downloaded_file_path.rename(converted_file_path)
228+
ffmpeg_success = True
229+
else:
224230
ffmpeg_success = await ffmpeg.convert(
225231
downloaded_file_path=downloaded_file_path,
226232
converted_file_path=converted_file_path,
227233
output_format=self.arguments["output_format"],
228234
ffmpeg_path=self.arguments["ffmpeg"],
229235
)
230-
else:
231-
downloaded_file_path.rename(converted_file_path)
232-
ffmpeg_success = True
233236

234237
if display_progress_tracker:
235238
display_progress_tracker.notify_conversion_completion()

spotdl/download/embed_metadata.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import base64
2+
from pathlib import Path
23

34
from urllib.request import urlopen
45
from mutagen.oggopus import OggOpus

spotdl/download/ffmpeg.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@ def has_correct_version(
2828

2929
# fallback to copyright date check
3030
if result is not None:
31-
version = result.group(0).replace("ffmpeg version ", "")
31+
version_str = result.group(0)
3232

3333
# remove all non numeric characters from string example: n4.3
34-
version = re.sub(r"[a-zA-Z]", "", version)
34+
version_str = re.sub(r"[a-zA-Z]", "", version_str)
35+
version = float(version_str)
3536

36-
if float(version) < 4.2:
37+
if version < 4.2:
3738
print(
3839
f"Your FFmpeg installation is too old ({version}), please update to 4.2+\n",
3940
file=sys.stderr,
@@ -43,12 +44,10 @@ def has_correct_version(
4344
return True
4445
else:
4546
# fallback to copyright date check
46-
date_result = re.search(r"Copyright \(c\) \d\d\d\d\-\d\d\d\d", output)
47+
date_result = re.search(r"Copyright \(c\) \d\d\d\d\-202\d", output)
4748

4849
if date_result is not None:
49-
date = date_result.group(0)
50-
if "2021" in date or "2020" in date:
51-
return True
50+
return True
5251

5352
print("Your FFmpeg version couldn't be detected", file=sys.stderr)
5453
return False
@@ -62,14 +61,16 @@ async def convert(
6261
# ! sampled length of songs matches the actual length (i.e. a 5 min song won't display
6362
# ! as 47 seconds long in your music player, yeah that was an issue earlier.)
6463

65-
downloaded_file_path = str(downloaded_file_path)
66-
converted_file_path = str(converted_file_path)
64+
downloaded_file_path = str(downloaded_file_path.absolute())
65+
converted_file_path = str(converted_file_path.absolute())
6766

6867
formats = {
6968
"mp3": ["-codec:a", "libmp3lame"],
7069
"flac": ["-codec:a", "flac"],
7170
"ogg": ["-codec:a", "libvorbis"],
72-
"opus": ["-vn", "-c:a", "copy"],
71+
"opus": ["-vn", "-c:a", "copy"]
72+
if downloaded_file_path.endswith(".opus")
73+
else ["-c:a", "libopus"],
7374
"m4a": ["-codec:a", "aac", "-vn"],
7475
"wav": [],
7576
}

0 commit comments

Comments
 (0)