Two years ago, I visited the Tate in London to view the Robert Rauschenberg retrospective and by the end of it I was in tears. A retrospective gives you a linear perspective on the successes and failures of any artist and it was clear by the end that Bob had so much more to say. I was especially touched by how he revisited some of his initial concepts in his final compositions. He knew what he loved. Robert died at the age of 82.
I remember hearing Black Hole Sun for the first time like it was yesterday. I was stunned. Chris Cornell. That voice. Fucking hell. I was hooked and Soundgarden was a welcome addition to my sister and I’s early 90’s alternative repertoire. I followed Chris’ career from Soundgarden to Audioslave and consumed his solo efforts as well. I was numb when I heard of Chris’ death last year. Every year it feels like we’re losing more friends, family, and inspirations to the plague of depression. For someone who loves art and music, losing someone like Chris at such a young age is a sobering reality of the fragility of life and art. Both can come to a halt in an instance.
If you or someone you know is considering suicide, please call the National Suicide Prevention Hotline: 1–800–273–8255.
Since Chris’ passing, he has been celebrated in many ways. Recently, a bronze statue of Chris was unveiled in his hometown of Seattle and there will be a Tribute Concert in Los Angeles next year. In addition, a massive retrospective of his career has become available covering work from Temple of the Dog, Soundgarden, Audioslave, and solo efforts.
I was tasked with coming up with a simple idea that could pay respect to Chris’ life as an artist while revisiting intimate connections between he and his fans. Chris was a rock legend and being part of multiple projects means he toured a lot. There is nothing quite as intimate as the relationship a fan and artist forge via a live performance. His gigography serves as a sort of physical memory of where he walked among us through the years. I shared these thoughts with my cohort Harold Gutierrez and asked him to come up with a single sentence on what we should build. Harold sent back the following:
Find the setlist from Chris Cornell shows you attended and create a playlist in your Spotify or Apple Music library.
I loved it. The setlist, an arrangement of songs chosen by the artist for your night, is a perfect memory fragment to remind us of that moment spent together. Let’s convert it to a modern format you can take around and make it easy to do so. Check it out here and read on to find out how we tackled it.
Setlists and Songs
If you read my post about rewinding the Foo Fighters tour history, you’ll know that setlist.fm is the best source for setlists on the web and it comes with an API platform. Unlike the Foo Fighters project, we need to pull concerts and setlists from each of Chris’ groups and his solo efforts. I counted over 1500 shows. 😮 Now, not all of these shows actually have a setlist so we decided to link back to setlist.fm for these in case our fans can help provide the setlist information. I would certainly suggest embracing this community for your band.
Each of these setlists come with a grouping of tracks and covers but they aren’t connected to either of the streaming services we want to incorporate. In order to do this, we decided to first manually build out a list of related Spotify tracks in a spreadsheet and then figure out the best way to locate the related Apple Music song. Luckily for us, Spotify and Apple Music share one track identifier: the ISRC code. I shared the process of cross identifying these tracks using ISRC in an earlier post. These were then combined in the same spreadsheet to create our final song dataset. In the end, a single song object looked like this:
title: "Black Hole Sun",
I then decided to greatly reduce the concert data so that it only included the properties we required for our view, including turning the setlist into an array of ids from our custom song dataset.
"artist": "Temple of the Dog",
"venue": "Paramount Theatre",
We included the latitude and longitude of each concert location as part of this dataset so we could use the Mapbox geocoding functionality to allow users to search by any location name and receive results within a specified radius. In short, Mapbox will return a latitude and longitude for a location you provide and you can use that pair of coordinates to filter your set by distance between the searched location and all of your concerts. Turfjs comes in handy for this and it is a lot faster than you think.
The graphic design for the retrospective release does an incredible job of building out a visual direction which can span all of Chris’ career. Chris himself is shown at various stages of his life thanks to an incredible set of photography. This is coupled with imagery of the two places Chris roamed most: in cities and outdoors. Finally, the texture of watercolor is utilized to meld these various elements in a cohesive and colorful offering. It certainly is a celebration of his life. Since our application is very text heavy, I chose to hold back on overusing too much of this content at the expense of user experience. I did, however, build a simple artwork generator which would produce a random piece of artwork each time you visited a show page. This was achieved using the watercolor textures and HTML5 canvas very easily.
First, I laid out all the backgrounds on a sprite sheet and prepared the logo in the same square dimensions. Then, in the code, I initialized a canvas and grabbed the context. I tend randomly generated a number between 1 and 6 to help decide which background to use. That number was then used to position the sprite sheet onto the canvas. Once the watercolor texture was added, the logo was applied on top. Finally, we setup the font styles and printed the date on each side of the canvas (rotating accordingly.)
// initialize canvas
let canvas = document.createElement('canvas')canvas.height = 540
canvas.width = 540let context = canvas.getContext('2d')// generate random number
let i = Math.floor(Math.random() * 6)// draw background with random position
context.drawImage(background, -540 * i, 0, 540 * 6, 540)// draw logo on top
context.drawImage(logo, 0, 0, 540, 540)// setup text style
context.font = "24px 'Saas', Helvetica"
context.textBaseline = "middle"
context.textAlign = "center"// rotate canvas and draw text
context.rotate(-90 * Math.PI/180)
context.fillText("Oct 28 2011", 0, 0)// reset transform
context.setTransform(1, 0, 0, 1, 0, 0)// rotate canvas once again and draw text
context.translate(540 - 36, 280)
context.rotate(90 * Math.PI/180)
context.fillText("Oct 28 2011", 0, 0)
Spotify will allow you to update the artwork of a playlist via an API call but Apple Music requires the user to do so manually.
Creating a Playlist
I covered playlist creation a bit on my Khruangbin project but this would be the first time I would attempt to generate playlists for both Spotify and Apple Music in one app. My goal was to simply create a similar user experience for both networks so that I didn’t need to create two sets of views. Once the user located their setlist, they could click “Save Playlist,” login with their streaming provider, and we would automatically save their playlist. Easy and expected.
Apple’s MusicKit JS comes with authentication baked in and you can actually wrap an authenticated function (like creating a playlist) right in a successful authorization. Spotify gives you the tools to do the same and I covered using their Implicit Grant Flow to create a popup authentication flow similar to Apple Music. Once you have a user token for the required service, you simply call the relevant API endpoints.
For Spotify, it takes three calls to create a new playlist. We also include a 4th call to update the artwork from the canvas.
Apple Music can create a playlist and add tracks to it within a single call.
I created two very simple Vue.js components for each of these flows and could certainly see how they could be combined into one easily. This is due to the incredible work both streaming services have put into making their JS libraries simple.
Designing the App
As an added bonus, I wanted to share the actual Figma prototype I created to help us through the design approval process. Figma’s prototyping capabilities are incredible for quickly wiring together a set of screens. On the first round of approvals, the client asked for a link to the retrospective release and I did one better by including an overlay screen which included a shot of the product and links to both the physical and digital offerings. At the time, I used Figma’s navigate function to emulate an overlay but Figma has since launched Overlays to do exactly that. Incredible.
My design process is fiercely simple. I retreat back to Harold’s original one sentence explanation of our app often and make sure nothing is getting in the way of achieving that. The frontpage description quickly lets users know what the app is all about and they are one click away from searching for their concert. Upon finding their concert, they are directed to a preview of the setlist and an option to the save it as a playlist. If they are a member of either service (and remember their password,) they can easily do that.
Explanation > Search > Preview > Save
That’s it. 👌🏻
Thank you to the fans who have already saved over 2000 playlists. Thank you to Harold and the rest of his team at Universal for the opportunity to build this project and all the help involved with making it a reality. Thanks to Chris’ management and estate for embracing the concept. Finally, thank you to Chris Cornell for sharing his music with us. He is missed.