##Spotify API
# =============================================
# Paquete para hacer consultas
# Función: POST --> para obtener el token
# Función GET --> para hacer consultas (buscar artista, canciones, etc)
library(httr)
library(ggplot2)
# Copiar y pegar el id y el secret de la APP creada en Spotify
my_client_id <- "01b3592ab4984061ba478e309a304114"
my_client_secret <- "d0ef37d14c23433c8d33f749670ac157"
———– Obtener token - autenticación () ———–
# Obtener bearer token
r0 <- POST(
"https://accounts.spotify.com/api/token",
config = authenticate(user = my_client_id,
password = my_client_secret),
body = list(grant_type = "client_credentials"),
encode = "form"
)
token <- content(r0)
bearer_token <- paste(token$token_type, token$access_token)
url_base <- "https://api.spotify.com/v1"
———– Obtener el ID de un artista ———–
artista <- "Shakira"
get_artist_id <- function(artista, bearer_token){
# Función para obtener el id de un artista a partir de su nombre
# Parámetros:
# - artista: nombre del artista a buscar (cadena de caracteres)
# Salida: id de Spotify asociado al artista
# Preparación de la consulta
artista_limpio <- gsub(" ", "_", artista)
query <- paste0(url_base, "/search?q=", artista_limpio, "&type=artist")
# Consulta (query) y respuesta (response)
response <- GET(query, config = add_headers(Authorization = bearer_token))
resultado <- content(response) # El resultado está cotenido en la respuesta
#print(result)
# Obtenemos el data.frame con los nombres y los ids de los artistas que
# coinciden con la búsqueda
df <- data.frame(id = sapply(resultado[[1]]$items, "[[", "id"),
nombre = sapply(resultado[[1]]$items, "[[", "name"))
# print(df)
# Seleccionamos los que nos interesan
id <- df$id[tolower(df$nombre) == tolower(artista)][1]
if(is.null(id) | nrow(df) == 0){
warning("No se han encontrado coincidencias\n")
}
return(id)
}
# Pruebas para las que debe funcionar get_artist_id
artista_id <- get_artist_id(artista, bearer_token);artista_id
## [1] "0EmeFodog0BfCgMzAIvKQp"
———– Obtener el ID de un artista ———–
#Mirar en la API como se ve la consulta para los albumes del artista
get_albums<-function(artista_id, bearer_token){
if(!is.null(artista_id)){
url_base<-"https://api.spotify.com/v1"
query<-paste0(url_base,
"/artists/",
artista_id,
"/albums?include_groups=album&limit=50")
# Consulta query y respuesta (response)
respuesta <- GET(query, config = add_headers(Authorization = bearer_token))
resultado <- content(respuesta) # El resultado está cotenido en la respuesta
resultado$items
# Obtenemos el data.frame con los nombres y los ids de los albumen del artista:
df <- data.frame(id = sapply(resultado$items, "[[", "id"),
nombre = sapply(resultado$items, "[[", "name"))
while (!is.null(resultado$`next`)) {
Sys.sleep(3)
respuesta<-GET(resultado$`next`,
config = add_headers(Authorization = bearer_token))
resultado<-content(respuesta) # el resultado esta contenido en la respuesta
df<-rbind(df,
data.frame(id = sapply(resultado$items, "[[", "id"),
nombre = sapply(resultado$items, "[[", "name")))
}
return(df)
}
}
#Pruebas para las que debe funcionar df_albums
df_albums <- get_albums(get_artist_id(artista, bearer_token), bearer_token);df_albums
## id nombre
## 1 6WaruQqgJzSlSzZz2YdUku Laundry Service: Washed and Dried (Expanded Edition)
## 2 5EdGgMlsJ7bv8IUqkaaPZN Shakira In Concert: El Dorado World Tour
## 3 6bUxh58rYTL67FS8dyTKMN El Dorado
## 4 4nXeW6UwZGBnv6zops27k4 Shakira. (Expanded Edition)
## 5 5meb7aKE722LA66ssBhvfM Shakira. (Expanded Edition) [Spanish Version]
## 6 0qE6Dd97eQiywwpbrhb5fX Live From Paris
## 7 3gR578qnw47M30LVBTjrlW Sale el Sol
## 8 5GuMQnx4X4mfHEcYQe7ql9 Loba
## 9 5u0OuxRnf3FzvZR07xAxL2 She Wolf (Expanded Edition)
## 10 5ppnlEoj4HdRRdRihnY3jU Oral Fixation, Vol. 2 (Expanded Edition)
## 11 3zHPYwiMJqa3hTBgk695Ae Fijación Oral, Vol. 1
## 12 5f5LXKRiPDf23T5QM2MEmX Live & Off The Record
## 13 4DyMK9x2gnmRkRa16zHaEV Laundry Service
## 14 62F8unRY46ZDR2EE5ag5Z5 Servicio De Lavandería
## 15 3yQQUyIA3vRIRnB4rqtThe Shakira MTV Unplugged
## 16 5hcKSTqKOLuzJgYIQileAe Donde Estan Los Ladrones
## 17 2G7F89aCUNtwnj3vYKNMfF The Remixes
## 18 3HLngzP9wVd8p3SMDQgyd9 Pies Descalzos
———– Canciones por album ———–
get_tracks <- function(artista, bearer_token){
lista_albums <- paste(df_albums$id, collapse = ",")
url_base<-"https://api.spotify.com/v1"
query<-paste0(url_base,
"/albums?ids=",
lista_albums)
#Consulta (query) y respuesta (response)
respuesta <- GET(query, config = add_headers(Authorization = bearer_token))
resultado <- content(respuesta) #El resultado está contenido en la respuesta
#Filtrar el resultado
lista_tracks <- lapply(resultado[[1]], "[[", "tracks")
lista_items <- sapply(lista_tracks, "[[", "items")
lista_nombres <- lapply(lista_items, sapply, "[[", "name")
nombres <- do.call(c, lista_nombres)
#Obtener el data frame de tracks
df_tracks <- c()
for (album in resultado$albums) {
for (track in album$tracks$items) {
df_tracks <- rbind(df_tracks,
data.frame(id = track$id,
name = track$name))
}
}
return(df_tracks)
}
#Pruebas del funcionamiento de get_tracks
df_canciones <- get_tracks(artista, bearer_token)
———– Energia por cancion ———–
get_features <- function(track_id, bearer_token){
query <- paste0(url_base,
"/audio-features/",
track_id)
respuesta <- GET(query, config = add_headers(Authorization = bearer_token))
resultado <- content(respuesta)
audio_features <- data.frame(id = track_id,
energia = resultado$energy,
valencia = resultado$valence)
return(audio_features)
}
lista_canciones <- df_canciones$id
df_features <- do.call(rbind, lapply(lista_canciones, get_features, bearer_token = bearer_token))
———–Grafica———————
plot_features <- function(df_features){
ggplot(df_features, aes(x = valencia, y = energia, color = id)) +
geom_point(show.legend = FALSE) +
labs(title = "Energia y valencia",
x = "Valencia",
y = "Energia") +
annotate("text", x = 0, y = 1, label = "Turbulent/Angry", hjust = 0, vjust = 1) +
annotate("text", x = 1, y = 1, label = "Happy/Joyful", hjust = 1, vjust = 1) +
annotate("text", x = 0, y = 0, label = "Sad/Depressing", hjust = 0, vjust = 0) +
annotate("text", x = 1, y = 0, label = "Chill/Peaceful", hjust = 1, vjust = 0) +
theme(axis.text = element_text(face = "bold")) +
geom_hline(yintercept = 0.5, size = 0.5) +
geom_vline(xintercept = 0.5, size = 0.5) +
coord_cartesian(xlim = c(-0,1), ylim = c(-0, 1))
}
———– USO ———–
grafica_artista <- function(artista, bearer_token){
artista_id <- get_artist_id(artista, bearer_token)
df_albums <- get_albums(artista_id, bearer_token)
df_canciones <- get_tracks(df_albums, bearer_token)
df_features <- do.call(rbind, lapply(df_canciones$id, get_features, bearer_token = bearer_token))
ggplot_obj <- plot_features(df_features)
# Mostrar la gráfica
print(ggplot_obj)
}
artista <- "Shakira"
bearer_token <- bearer_token
grafica_artista(artista, bearer_token)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.