Moodtape: Web Application Using Spotify API to Create Mood-Generated Playlists

In life, we experience a vast range of emotions. Through all the art forms, music is the universal language that allows us to cope, understand, and celebrate these emotions in beautiful ways that words simply cannot. If there was a way to generate a set of songs that was perfectly synchronized with your mood, it would make the process of finding music to compliment your current emotions more seamless. Imagine an algorithm to generate music therapy, music celebration, or anything in between.

Spotify has become the foremost product that people use to listen to music. There are two benefits to using Spotify for applications. First, it stores all of a user’s listening history and this wide-spanning amount of data allows for the opportunity to generate playlists that takes a user’s music preferences into account. Second, it has an expansive bank of music available so there is no worry of not having enough music for the user.

I decided to build a web app using Spotify API. This app would use an algorithm to create mood-generated playlists based on a user’s mood and music listening history!

It was awesome to flesh out my full stack skills, building out the back-end algorithm with Python using data from Spotify API, along with creating a front-end with HTML/CSS/JS using the Flask Web Framework. I’m really proud to have programmed something that genuinely creates value in my life.

There were six steps to this process:

Step 1. Authenticating and Using Spotipy

Algorithm for using and authenticating Spotipy

I used Spotipy, a python framework for pulling data from Spotify API. This involved setting the arguments a user would input — username and mood from 0.0 to 1.0, where 0.0 is a very negative mood state and 1.0 is a very positive mood state. This creates a token that can be used to create a Spotipy object, which allows me to pull the data I need from Spotify API. The specific data I want is stated in the scope object; in this case, I want to know a user’s library, their top and followed artists, and be able to create/modify playlists. Once this token is authorized once, it is cached and the data can be accessed without issue every time the program is run.

Connecting my Spotify account with the Moodtape app

In addition, a few authorization codes are needed which are given by actually registering a Spotify app on the Spotify developers page. I registered Moodtape as an official Spotify app, which allowed me to connect an account with the app.

Now, time to start pulling some data!

Step 2. Creating a list of your favorite artists

Algorithm for getting a user’s favorite artists

Next, I decided to get a user’s favorite artists. The reason behind this was because I envisioned this app as less a path to discover new music, but more to center around a user’s favorite type of music. By getting favorite artists, however, it allows the program to create playlists that have both familiar and unfamiliar songs to the user. The possibility of a user knowing every single popular song by all their favorite artists is quite low.

To get a range of favorite artists, I used two features of the Spotify API: Get a User’s Top Artists, and Get a User’s Followed Artists. For the former, I implemented all three time ranges that the API allows for: short-term (4 weeks), medium-term (6 months), long-term (complete history). This allowed the program to gather a diverse set of artists — a user’s all-time favorite artists along with artists they have been listening to a lot recently. In addition, I got the user’s followed artists to round out any artists that a user has consciously decided to follow on Spotify. In total, this algorithm would get us anywhere between 50–200 artists.

In gathering this data, I took note of two attributes: name and URI. Getting the actual name of an artist was necessary so that no artist was added twice to the list. The URI (Uniform Resource Indicator) immediately connects to the associated data on the Spotify application without having to go to any webpage as an intermediary. Getting the URI will be necessary for all successive steps.

Step 3. For each of the artists, get all tracks for each artist.

Algorithm for getting the top tracks

Now that we had a user’s favorite artists, we could get those artists’ top 10 tracks. To get these songs, I used the Spotify API: Get an Artist’s Top Tracks. These tracks will constitute a database that can be used to generate a specific playlist, roughly 500–2000 tracks. This database would in theory be the “cream of the crop” songs for the user, as it contains the top-streamed tracks of a user’s top artists.

My first implementation actually involved getting all of an artist’s tracks instead of just their top tracks. While this strategy allowed for a larger database, that strategy ran into a couple issues. First, it had both performance and memory issues as this would try to aggregate tens of thousands songs all together. Second, because this database included all songs, it would include some unwanted tracks such as live performances, commentaries, and re-issued versions of songs.

Getting the top tracks cut through the noise and pulled the tracks that would lead to a highly enjoyable listening experience for the user.

Step 4. From top tracks, select tracks that are within a certain mood.

Algorithm for getting selected tracks

Now we are at the fun part! The program shuffles the database of songs created and depending on the inputted mood, the program decides which songs should be added to selected set of tracks. These tracks are the ones deemed suitable to be in the playlist based on the mood.

I used Spotify API: Get Audio Features for Several Tracks to get the attributes for each track. I focused on three attributes of a track when determining if it should be added to a track: valence, danceability, and energy. The definitions are as follows, according to the official Spotify API documentation:

Valence is a measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track. Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low valence sound more negative (e.g. sad, depressed, angry).

Danceability describes how suitable a track is for dancing based on a combination of musical elements including tempo, rhythm stability, beat strength, and overall regularity. A value of 0.0 is least danceable and 1.0 is most danceable.

Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and activity. Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy, while a Bach prelude scores low on the scale. Perceptual features contributing to this attribute include dynamic range, perceived loudness, timbre, onset rate, and general entropy.

Valence was the primary attribute I focused on, as this directly correlates with the mood of a track. Based on the mood inputted, the program only adds tracks within a narrow range of that valence. In fact, I was originally just going to use this attribute. However, once I started testing the app, I would find that the playlists on the lower range of mood (0.0–0.49) were not as accurate as I’d hope.

For example, “Bad and Boujee” by Migos (a hugely popular party song) would show up on the 0.13 playlists — a lower mood playlist. My hypothesis is that it is easier to gage positiveness in music than the inverse. Positive tracks tend to converge in a happy, dance-orientated, or euphoric sound. Conversely, negative tracks can come in a lot of different sounds — sad, angry, or edgy. “Bad and Boujee” has a great deal of minor chords and haunting production, which could make it into the low-mood playlists despite it being a party track.

To mend this, I incorporated danceability and energy as two secondary attributes. If tracks were on the lower range, I made sure they were also on the lower range of these attributes; the vice-versa was true for the higher range. Incorporating these three attributes in conjunction significantly accounted for many outliers. What resulted were selected tracks that genuinely correlated with the given mood input.

Step 5. From these tracks, create a playlist for the user.

Algorithm for creating the “moodtape”

Finally, we can create our playlist! This step was relatively straightforward. I used Spotify API: Create a Playlist and Add Tracks to a Playlist to directly generate a playlist for a user.

I decided to make the playlist 30 tracks long, as this seemed like a ideal amount of time someone would want to listen to songs of a certain mood (90–120 mins). The program simply pulls the first 30 tracks of the selected tracks gathered from the previous step. Shuffling the database of songs in the previous step ensures we get a new playlist every time the program is run.

Running the program in terminal!

After running the program, there is a brand spanking new playlist in your Spotify account!

The “Moodtapes” in Action!

These are 4 playlists — 0.07, 0.38, 0.64, 0.92 — the program created with my account. My music tastes lean towards hip-hop, RnB, alt-rock, and alt-pop.

Playlist for mood of 0.07
Playlist for mood of 0.38
Playlist for mood of 0.64
Playlist for mood of 0.92

Step 6: Building out the UI/UX

Moodtape UI/UX + Back-End in Conjunction

Once the back-end was finished, I decided to build out a workable User Interface so that this program could function as a Web Application. To do this, I used the Flask microframework that makes it possible to make web apps using a Python back-end. The front-end was built with HTML, CSS, and Javascript. I went with a minimalistic UI/UX as I felt there was no need for too much overhead in the playlist-making process. I added some internal CSS to center the text, make the input section visually appealing, and match the color scheme with Spotify’s branding. In addition, I added a Javascript function to display a loading image while the playlist is being generated, to keep the User Experience smooth and seamless.

In terms of the flow of the application, there were two HTML files that held the input page and the playlist-link page. A user submits their mood on the input page which tells the back-end to start generating a playlist. Once this is done, the back-end returns a playlist URI. The app then switches to the playlist-link page, where this URI is associated with a button; when a user clicks the button, it jumps directly to the Spotify App with your new playlist!

Moving Forward

As I continue to work on this project, I’d like to continue to fine-tune the algorithm. I’m happy with how it can create playlists based off a certain mood range, bringing in songs by a user’s favorite artists. The playlists contain a solid mix of tracks I love and new tracks I end up really enjoying. In fact, I’ve begun to use it to generate playlists myself and actually listen to them in my day-to-day! That being said, it’s still not perfect; there tends to be 3–5 outliers for every 30-song playlist. I plan to bring in more features (tempo, loudness, etc.) and figure out more precise calculations to make the algorithm more air-tight and get rid of outliers.

The better the algorithm, the better the moodtape!

Software Engineer passionate about the intersection of technology and mental healthcare. In my free time, I like to write about art.