Skip to content

Commit d1ae081

Browse files
authored
Merge branch 'main' into liked_songs
2 parents 3e105db + ac4d873 commit d1ae081

File tree

8 files changed

+25
-17
lines changed

8 files changed

+25
-17
lines changed

README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
<div align="center">
22

3-
<img src="assets/logo.png" alt="logo" width="200" height="auto" />
4-
<h1>spotify2mp3</h1>
5-
3+
<img src="assets/logo.png" alt="logo" width="250" height="auto" />
64
<p>
75
Simple, free, and unlimited Spotify MP3 downloads
86
</p>

apis/youtube.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,26 @@ def search(self, search_query, max_length, min_view_count, search_count = 1):
5151

5252
def download(self, url, audio_bitrate):
5353
youtube_video = pytubeYouTube(url)
54+
5455
if youtube_video.age_restricted:
5556
youtube_video.bypass_age_gate()
56-
youtube_video_streams = youtube_video.streams.filter(only_audio=True, file_extension='mp4')
57+
youtube_video_streams = youtube_video.streams.filter(only_audio=True)
5758

5859
correctIndex = 0
5960

6061
selected_bitrate_normalised = audio_bitrate / 1000
6162

63+
#select the best audio quality
64+
finalKbps = 0
65+
correctIndex = 0
6266
for i,vid in enumerate(youtube_video_streams):
6367
currKbps = int(re.sub("[^0-9]", "", vid.abr))
64-
if currKbps < selected_bitrate_normalised:
68+
if currKbps <= selected_bitrate_normalised:
6569
correctIndex = i
70+
finalKbps = currKbps
6671

6772
video_stream = youtube_video_streams[correctIndex]
6873

6974
yt_tmp_out = video_stream.download(output_path="./temp/")
7075

71-
return yt_tmp_out
76+
return yt_tmp_out, finalKbps

assets/logo.png

15.8 KB
Loading

const.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from enum import Enum
22
import sys
33
import string
4+
import os
45

56
def supports_24bit_color():
67
"""Determine if the terminal supports 24-bit color."""

downloader.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ def __init__(self, spotify: Spotify, youtube: YouTube, audio_quality=1000000, ma
2626
self.min_view_count = min_view_count
2727

2828
def download_album(self, playlist_url):
29+
30+
skipped_songs = 0
2931

3032
print(f"\n{colours.OKBLUE}[!] Retrieving spotify album")
3133

@@ -38,6 +40,7 @@ def download_album(self, playlist_url):
3840
tracks = album.get_tracks()
3941

4042
print(f"\n{colours.OKBLUE}[!] Found {len(tracks)} tracks in album.")
43+
4144
time.sleep(3)
4245

4346
output_path = "downloads/albums/" + album.get_title(True) + "/"
@@ -46,6 +49,7 @@ def download_album(self, playlist_url):
4649
return True
4750

4851
except SpotifyAlbumNotFound as e:
52+
4953
print(f"\n{colours.FAIL}Error: {colours.ENDC}{colours.WARNING}It's probably that this album does not exist {colours.ENDC} (e: {e}).{colours.ENDC}\n")
5054
sys.exit(1)
5155

@@ -120,13 +124,13 @@ def download_tracks(self, output_path, tracks):
120124

121125
except ConfigVideoMaxLength as e:
122126

123-
print(f" - {colours.WARNING}[!] Skipped a song - {e}, {colours.ENDC}(use the command line to increase this).{colours.ENDC}\n")
127+
print(f"\n{colours.WARNING}[!] Skipped a song - The found song was longer than the configured max song length, {colours.ENDC}(use the cli to increase this).{colours.ENDC}\n")
124128

125129
skipped_tracks.append((track, e))
126130

127131
except ConfigVideoLowViewCount as e:
128132

129-
print(f" - {colours.WARNING}[!] Skipped a song - {e}, {colours.ENDC}(use the command line to increase this).\n")
133+
print(f"\n{colours.WARNING}[!] Skipped a song - The found song had less views than the minimum view count, {colours.ENDC}(use the cli to increase this).\n")
130134

131135
skipped_tracks.append((track, e))
132136

@@ -182,13 +186,13 @@ def download_track(self, track_url = None, track = None, idx = 0, idx_max = 0, o
182186

183187
print(f"{colours.ENDC} - Downloading, please wait{colours.ENDC}")
184188

185-
video_downloaded_path = self.youtube_client.download(youtube_link, self.audio_quality)
189+
video_downloaded_path, self.audio_quality = self.youtube_client.download(youtube_link, self.audio_quality)
186190

187191
# consider updating searchable name to something nicer for the end user
188192

189193
print(f"{colours.ENDC} - Converting the song and adding metadata{colours.ENDC}")
190194

191-
resave_audio_clip_with_metadata(video_downloaded_path, track.get_metadata(), track_path)
195+
resave_audio_clip_with_metadata(video_downloaded_path, track.get_metadata(), output_path + track.get_title(True) + ".mp3", self.audio_quality)
192196

193197
print(f"{colours.ENDC} - Done!")
194198

@@ -204,14 +208,14 @@ def download_track(self, track_url = None, track = None, idx = 0, idx_max = 0, o
204208

205209
except ConfigVideoMaxLength as e:
206210
if(not as_sub_function):
207-
print(f"\n{colours.FAIL}Error: {colours.ENDC}The found song was longer than the configured max song length (use the command line to increase this) {colours.ENDC} (e: {e}).{colours.ENDC}\n")
211+
print(f"\n{colours.FAIL}Error: {colours.ENDC}The found song was longer than the configured max song length (use the cli to increase this) {colours.ENDC} (e: {e}).{colours.ENDC}\n")
208212
return False
209213
else:
210214
raise e
211215

212216
except ConfigVideoLowViewCount as e:
213217
if(not as_sub_function):
214-
print(f"\n{colours.FAIL}Error: {colours.ENDC}The found song had less views than the minimum view count (use the command line to increase this){colours.ENDC} (e: {e}).{colours.ENDC}\n")
218+
print(f"\n{colours.FAIL}Error: {colours.ENDC}The found song had less views than the minimum view count (use the cli to increase this){colours.ENDC} (e: {e}).{colours.ENDC}\n")
215219
return False
216220
else:
217221
raise e

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ packaging==21.3
1616
Pillow==9.1.1
1717
proglog==0.1.10
1818
pyparsing==3.0.9
19-
pytube
19+
pytube==15.0.0
2020
requests==2.27.1
2121
soupsieve==2.3.2.post1
2222
toml==0.10.2

spotify2mp3.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def get_bitrate_from_quality(quality):
2222
elif quality == "medium":
2323
return 80000
2424
elif quality == "high":
25-
return 160000
25+
return 256000
2626
else:
2727
return int(quality)
2828

@@ -32,7 +32,7 @@ def validate_quality(quality):
3232
return quality
3333
try:
3434
bitrate = int(quality)
35-
if 64 <= bitrate <= 320000: # Typical YouTube bitrate ranges
35+
if 48000 <= bitrate <= 256000: # Typical YouTube bitrate ranges
3636
return quality
3737
else:
3838
raise argparse.ArgumentTypeError(f"Bitrate outside of typical YouTube range (64 kbps to 320 kbps): {quality}")

utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ def random_string(length=10):
3535
letters = string.ascii_letters # This includes both lowercase and uppercase letters.
3636
return ''.join(random.choice(letters) for i in range(length))
3737

38-
def resave_audio_clip_with_metadata(audio_input_path, song_metadata, song_output_path):
38+
def resave_audio_clip_with_metadata(audio_input_path, song_metadata, song_output_path, audio_quality):
3939

4040
temporary_audio_path = "./temp/" + random_string(20) + ".mp3"
4141

4242
clip = AudioFileClip(audio_input_path)
43-
clip.write_audiofile(temporary_audio_path, logger=None)
43+
clip.write_audiofile(temporary_audio_path, logger=None, bitrate=f'{audio_quality}k')
4444

4545
audiofile = eyed3.load(temporary_audio_path)
4646

0 commit comments

Comments
 (0)