Since I started working out, the music proved to be a motivator. When I work I usually have a Mix of youtube in the background and I love how youtube adapts to my preferences, spotify also does a good job but not as accurate. So my “motivational” mix was on youtube. When I jog I don’t have too good of an internet connection and I spend my data on playing songs as videos because I don’t have those songs on spotify.

So I decided to move my songs between platforms using python. It’s a pretty easy job! First of all, I realize that a playlist is different from a mix. The latter is not easy to manipulate and the preferred way to get the songs is to use web scraping. I didn’t want that, so thanks to a guy who shows how to convert a mix into a playlist on reddit, you just add a random song in the mix (I did it with a random song that usually appears below the mix list), and after that a button magically appears at the top:

botom

We have a playlist, is easier now. Using the library pytube with four lines of code you have the song titles.

import pytube
playlist = pytube.Playlist("https://www.youtube.com/playlist?list=PLWYOEQl110tLJZ1ndhpbVsCRpdoF1Wj8T")
raw_songs = []
for song in playlist:
    raw_songs.append(pytube.YouTube(song).streams[0].title)

Obviously, the song titles needed some cleanup. By using some stop words we can eliminate words that can confuse the search in the Spotify app. We also transformed the list into a dict, where each title is the key and the artist is the value (because most likely the artist can appear several times with different songs).

words = raw_songs
stopwords = [' (Official Music Video)', ' [Official Music Video]',
' (Official 4K Video)', '(Official Video)',
' (from the series Arcane League of Legends)', ' (Performance Edit)',
' (Alternate Version)', '│ Subtitulado al español']
new_list = []
for word in words:
    new_word = word
    for stop in stopwords:
        if stop in new_word:
            new_word = new_word.replace(stop, '')
        else:
            new_word = new_word
    new_list.append(new_word.strip())

songs_dict = {}
for song in new_list:
    songs_dict[song.split("-")[1].strip()] = song.split("-")[0].strip()
songs_dict

It’s time to switch to Spotify, which has a wonderful API. You need to have a client id, the Spotify secret and the redirect url. If you don’t know how to get those values, Dan Arwady has a great video that explains it all.

youknow

Finally, using the spotipy library, it is easy to create a playlist with the previous dict:

import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from spotipy.oauth2 import SpotifyClientCredentials
from pprint import pprint

## params
SPOTIFY_CLIENT_ID = ""
SPOTIFY_SECRET = ""
REDIRECT_URL = ""

## api call
sp = spotipy.Spotify(
    auth_manager=SpotifyOAuth(
        scope="playlist-modify-private",
        redirect_uri=REDIRECT_URL,
        client_id=SPOTIFY_CLIENT_ID,
        client_secret=SPOTIFY_SECRET,
        cache_path="token.txt"
    )
)

## searching
spotify_song_uris = []
for key, value in songs_dict.items():
    spotify_result = sp.search(q=f"artist:{value} track:{key}", type="track")
    try:
        song_uri = spotify_result['tracks']['items'][0]['uri']
        spotify_song_uris.append(song_uri)
    except IndexError:
        print(f"{value} doesn't exist in Spotify. Skipped.")

In my case, four of the song titles that appear on youtube are not identifiable in Spotify, so I had to clean them up manually:

## fixing some song titles
new_list2 = new_list.copy()
new_list2[4] = 'Imagine Dragons - Enemy (with JID)'
new_list2[9] = 'DJ Snake, Justin Bieber - Let Me love You'
new_list2[12] = 'Eminem - Lose Yourself'
new_list2[13] = 'David Guetta, Sia - Titanium (feat. Sia)'
new_list2[16] = 'Sia - Elastic Heart'

## creating the dict again
songs_dict2 = {}
for song in new_list2:
    songs_dict2[song.split("-")[1].strip()] = song.split("-")[0].strip()
songs_dict2

When the search was performed again, all songs were identified:

spotify_song_uris = []
for key, value in songs_dict2.items():
    spotify_result = sp.search(q=f"artist:{value} track:{key}", type="track")
    try:
        song_uri = spotify_result['tracks']['items'][0]['uri']
        spotify_song_uris.append(song_uri)
    except IndexError:
        print(f"{value} doesn't exist in Spotify. Skipped.")

print(len(spotify_song_uris))

We add the songs to a playlist called: running_songs:

user_id = ''
my_playlist = sp.user_playlist_create(user=f"{user_id}",
                                      name="running_songs",
                                      public=False,
                                      description="songs to run")
sp.user_playlist_add_tracks(user=f"{user_id}",
                            playlist_id=my_playlist["id"],
                            tracks=spotify_song_uris)

If you look at your spotify playlist, you have a new one:

appsong

So, you can do the same with every mix you have. I’ve created a class with this code and a notebook on github in case you need it