Basic Setup

# Load Package
library(spotifyr)

# Get credentials and make available to package
# Requires SPOTIFY_CLIENT and SPOTIFY_SECRET to be set as environment variables
# Get Client ID and Secret here: https://developer.spotify.com/
set_tokens()

Basic Usage

Artist information

electric_wizard_uri <- '4htjQW3lgIwL6fEJlTOez4'
artist <- get_artist(electric_wizard_uri)
str(artist)
## List of 10
##  $ external_urls:List of 1
##   ..$ spotify: chr "https://open.spotify.com/artist/4htjQW3lgIwL6fEJlTOez4"
##  $ followers    :List of 2
##   ..$ href : NULL
##   ..$ total: int 80926
##  $ genres       :List of 11
##   ..$ : chr "doom metal"
##   ..$ : chr "drone"
##   ..$ : chr "drone metal"
##   ..$ : chr "neo-psychedelic"
##   ..$ : chr "post-doom metal"
##   ..$ : chr "post-metal"
##   ..$ : chr "psychedelic doom"
##   ..$ : chr "sludge metal"
##   ..$ : chr "space rock"
##   ..$ : chr "stoner metal"
##   ..$ : chr "stoner rock"
##  $ href         : chr "https://api.spotify.com/v1/artists/4htjQW3lgIwL6fEJlTOez4"
##  $ id           : chr "4htjQW3lgIwL6fEJlTOez4"
##  $ images       :List of 4
##   ..$ :List of 3
##   .. ..$ height: int 664
##   .. ..$ url   : chr "https://i.scdn.co/image/bee61096977bc59279c1a3145f4e32df6a5d7b96"
##   .. ..$ width : int 1000
##   ..$ :List of 3
##   .. ..$ height: int 425
##   .. ..$ url   : chr "https://i.scdn.co/image/4907f291560d0f65bd50c66753018e3e2f8a019d"
##   .. ..$ width : int 640
##   ..$ :List of 3
##   .. ..$ height: int 133
##   .. ..$ url   : chr "https://i.scdn.co/image/831382bf608ab0cb6c79e523128fa1f166aa7974"
##   .. ..$ width : int 200
##   ..$ :List of 3
##   .. ..$ height: int 43
##   .. ..$ url   : chr "https://i.scdn.co/image/7b69950d45dc6e477520438db59c6194d037e547"
##   .. ..$ width : int 64
##  $ name         : chr "Electric Wizard"
##  $ popularity   : int 51
##  $ type         : chr "artist"
##  $ uri          : chr "spotify:artist:4htjQW3lgIwL6fEJlTOez4"

Album metadata

monnos_id <- '6mwaHNgIMNdUPlcgymNUbn'
album <- get_album(monnos_id)
names(album)
##  [1] "album_type"             "artists"               
##  [3] "available_markets"      "copyrights"            
##  [5] "external_ids"           "external_urls"         
##  [7] "genres"                 "href"                  
##  [9] "id"                     "images"                
## [11] "label"                  "name"                  
## [13] "popularity"             "release_date"          
## [15] "release_date_precision" "tracks"                
## [17] "type"                   "uri"
album %>% extract(c('name', 'label', 'popularity', 'release_date')) %>% data.frame
##     name             label popularity release_date
## 1 Monnos Black Bow Records         35   2016-01-01

Embed Album Art in RMarkdown!

![](`r album$images[[1]]$url`)

Get Song Metadata

war_pigs_uri <- '2rd9ETlulTbz6BYZcdvIE1'
track <- get_track(war_pigs_uri)
names(track)
##  [1] "album"             "artists"           "available_markets"
##  [4] "disc_number"       "duration_ms"       "explicit"         
##  [7] "external_ids"      "external_urls"     "href"             
## [10] "id"                "name"              "popularity"       
## [13] "preview_url"       "track_number"      "type"             
## [16] "uri"
track$name
## [1] "War Pigs/Luke's Wall - Remastered Version"
track$artist[[1]]$name
## [1] "Black Sabbath"
track$album$name
## [1] "Paranoid (Remastered Edition)"
# Cool stuff, not sure what to do with it
audio_analysis <- get_track_audio_analysis(war_pigs_uri)
names(audio_analysis)
## [1] "meta"     "track"    "bars"     "beats"    "tatums"   "sections"
## [7] "segments"
# Higher level metrics on songs
audio_features <- get_track_audio_features(war_pigs_uri)
names(audio_features)
##  [1] "danceability"     "energy"           "key"             
##  [4] "loudness"         "mode"             "speechiness"     
##  [7] "acousticness"     "instrumentalness" "liveness"        
## [10] "valence"          "tempo"            "type"            
## [13] "id"               "uri"              "track_href"      
## [16] "analysis_url"     "duration_ms"      "time_signature"
str(audio_features)
## List of 18
##  $ danceability    : num 0.332
##  $ energy          : num 0.623
##  $ key             : int 9
##  $ loudness        : num -12.4
##  $ mode            : int 0
##  $ speechiness     : num 0.0803
##  $ acousticness    : num 0.222
##  $ instrumentalness: num 0.000883
##  $ liveness        : num 0.278
##  $ valence         : num 0.423
##  $ tempo           : num 183
##  $ type            : chr "audio_features"
##  $ id              : chr "2rd9ETlulTbz6BYZcdvIE1"
##  $ uri             : chr "spotify:track:2rd9ETlulTbz6BYZcdvIE1"
##  $ track_href      : chr "https://api.spotify.com/v1/tracks/2rd9ETlulTbz6BYZcdvIE1"
##  $ analysis_url    : chr "https://api.spotify.com/v1/audio-analysis/2rd9ETlulTbz6BYZcdvIE1"
##  $ duration_ms     : int 474360
##  $ time_signature  : int 4
audio_features %>% 
  extract(c('danceability', 'energy', 'loudness', 'tempo')) %>% 
  data.frame
##   danceability energy loudness  tempo
## 1        0.332  0.623  -12.365 182.63

User specific endpoints

Player Endpoints

# Set up Authorization
set_tokens()
user_auth()

user_id <- 'rweyant'

# Preselect some songs
boris_uri <- 'spotify:track:7HGOZac4VHXnWXWuvMniTv'
otc_uri <- 'spotify:track:4ZfeuBsnsdiXAemBFF0AmB'
nmh_uri <- 'spotify:track:17Nowmq4iF2rkbd1rAe1Vt'
tmg_uri <- 'spotify:track:2M1Qc1mGSI1IYtmJzQtfPq'
e1_uri <- 'spotify:track:77cgc07OFLOPohnhfspILp'
e2_uri <- 'spotify:track:33Lsj7uS17z8DFcUyvAFMf'

# Create a playlist
playlist <- create_playlist(user_id = user_id, name = 'robs-faves')
playlist_id <- playlist$id

# Add some songs
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = boris_uri)
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = otc_uri)
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = nmh_uri)
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = tmg_uri)
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = e2_uri)
add_tracks_to_playlist(user_id = user_id, playlist_id = playlist_id, uris = e1_uri)

# Start Playing
start_user_playback()

# Check Status
get_user_playback()

# Show track data for current song
get_currently_playing_track()

# Stop the music
pause_user_playback()

# Advance one song in the playlist
skip_user_playback_next()

# Go back one song in the playlist
skip_user_playback_previous()

# jump to a specific place in the currently playing song
seek_user_playback(position_ms = 10000)

Rob’s Top Artists

user_auth()
get_saved_tracks()
# Load data that was retrieved and processed through multiple API calls
saved_tracks <- readRDS('audio-features.rds')

# Preprocessing
top_artists <- saved_tracks %>% 
  group_by(artist) %>% 
  summarize(n = n()) %>% 
  ungroup %>% 
  mutate(pct_rank = percent_rank(n)) %>% 
  arrange(pct_rank %>% desc) %>% 
  mutate(artist = factor(artist, levels = artist))

ggplot(top_artists %>% filter(pct_rank > 0.8)) + 
  geom_bar(aes(x = artist, y = n), stat = 'identity') +
  theme_bw(base_size = 24) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + 
  ggtitle('Artists with Most Saved Tracks in Rob\'s Library')

Rob’s Top Genres

user_auth()
get_user_top('artists')
# Load data that was retrieved and processed through multiple API calls
artists_df <- readRDS('top-artists.rds')
top_genres <- artists_df %>% 
  group_by(genres) %>% 
  summarize(n = n(),
            pct = n / n_distinct(artists_df$name)) %>% 
  ungroup %>% 
  mutate(pct_rank = percent_rank(n)) %>% 
  arrange(pct_rank %>% desc) %>% 
  mutate(genres = factor(genres, levels = genres))

ggplot(top_genres %>% filter(pct_rank > 0.8)) + 
  geom_bar(aes(x = genres, y = pct), stat = 'identity') +
  theme_bw(base_size = 24) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5)) + 
  scale_y_continuous('Percent of Top Artists (n = 360)') +
  ggtitle('Genres of the Top Artists Saved in Rob\'s Library')

Characteristics of Rob’s Saved Tracks

Genre Characteristics

ggplot(genre_characteristics %>% filter(pct_rank > 0.8), 
       aes(x = avg_tempo, y = avg_duration, color = genres, shape = top_level_genre)) +
  geom_point(size = 5) + 
  theme_bw(base_size = 18) + 
  scale_x_continuous('Average Tempo') +
  scale_y_continuous('Average Duration') +
  ggtitle('Duration vs. Tempo')

ggplot(genre_characteristics, 
       aes(x = top_level_genre, y = avg_danceability)) +
  geom_boxplot(size = 1.5) +
  theme_bw(base_size = 22) + 
  scale_x_discrete('Genre') +
  scale_y_continuous('Average Danceability') +
  ggtitle('Danceability')

ggplot(genre_characteristics, 
       aes(x = top_level_genre, y = avg_popularity)) +
  geom_boxplot(size = 1.5) +
  theme_bw(base_size = 22) + 
  scale_x_discrete('Genre') +
  scale_y_continuous('Average Popularity') +
  ggtitle('Popularity')