Zack Scholl

zack.scholl@gmail.com

Download songs from a Spotify playlist

 / 

Download Spotify playlists into mp3 files using YouTube and a simple command-line program written in Go.

I listen to a lot of Spotify and make a lot of playlists. I’d like to listen to them offline, for personal use only - so I could put them on my old-fashioned mp3 player. I decided to try out a couple of “Spotify downloaders” but in the end I decided to make my own.

Disclaimer: Downloading copyright songs may be illegal in your country. This tool is for educational purposes only and was created only to show how Spotify’s API can be used to download music from YouTube. Please support the artists by buying their music.

A search for “Spotify Download” gives about 250 results, some which are quiet popular. I tried the two most popular - one written in Python and one written in Node. Both of them resulted in errors despite my system being new and despite having all of my dependencies up-to-date. Maybe it’s a Windows thing?

First I tried a Spotify downloader written in Python, spotdl (run using Python 3.7.1 on Windows 10). It resulted in over 300 lines of errors. Something about Could not find JS function 'encodeURIComponent'. It turned out to be a youtube-dl problem, which I then upgraded to the new current version. I tried it again and immediately had problems with correct detection of songs. For instance a search for Ian William Craig - Arrive Arrive resolted in a video parodying Hitler.

But eventually I would also get a 403 error and then another NameError: name 'time' is not defined error. Turns out this was a bug fix to another bug fix that wasn’t pushed to PyPI yet. Ugh Python ecosystems.

Then, I tried a different Spotify downloader written in Node, spotify-playlist-downloader (run using Node 10.14.1 on Windows 10) which also resulted in an error immediately, something about Cannot read property 'csrftoken' of undefined.

Writing my own: spotifydownload

In the end, I simply wrote another. I decided to write it in Go, because there would be no dependenecies and anyone could run it without installing an ecosystem (e.g. Python and Node).

There are basically two components to this program: a module for getting songs (getsong) and a command-line utility for downloading the playlists (spotifydownload).

Getting the songs of YouTube is an important and tricky part. As I saw above, trying to get the song Arrive, Arrive by Ian William Craig resulted in downloading an audio clip from a Hitler parody. The song finding has to have a very high positive rate and a low false positive rate.

To get the songs then, first I have to make sure that the title of the song and the name of the artist are spelled right. Spelling is important, because YouTube will try to change the spelling if they think it is spelled wrong. For example, when searching for the song Eva by Haerts, the name of the band Haerts seems to be mispelled even though it it isn’t. A search for this song shows YouTube automatically corrects it:

YouTube incorrectly correcting “Haerts”

In this situation, you would actually need to load the page from the “Search instead for eva haerts”. Following this link gives the correct results as you would have expected.

Once possible videos are found, then you have to find the best one which best matches the song, as to avoid Hitler parodies or other random videos. A good way I found to do this was to look for auto-generated videos where have the keywords “auto-generated” or “Provided to YouTube”. This avoids getting songs that are simply “live” versions of other songs.

Music videos provided to YouTube

Another important aspect is to skip getting songs that are unable to find the right video. The right video is defined strictly - it is a video that must have the name of the artist in it somewhere, and it must have the title of the song somewhere.

The end result of this is github.com/schollz/getsong. There is a command-line version of this you can run with

$ go get github.com/schollz/getsong

You can use this to download individual songs. For instance, if you want to download Arrive, Arrive it will easily find the right YouTube video to download instead of a Hitler parody.

$ getsong 'Arrive, Arrive' 'Ian William Craig'
Downloading Ian William Craig - Arrive, Arrive (_GYMVk7Bu8o)...
 524289 / 524289 [=================================] 100.00% 668149/s 0s
...converting to mp3...
Downloaded 'Ian William Craig - Arrive, Arrive (_GYMVk7Bu8o).mp3'

Getting playlists (schollz/spotifydownload)

The next part is to get the playlists from Spotify and then download all of the songs in the playlist. This is actually very easy as Spotify provides a link to the playlist. Simply go to a playlist and right-click and you’ll see a dropdown menu that lists “Share Playlist link” as an option. Parsing this web link will give you a list of songs and artists that can then be downloaded one at a time using getsong.

I tried doing this other ways, like using a Bearer key, but that would only be useful for private playlists.

tinker / 

Books I read (2018)      FAAS