Spotify Display: Daten per ESP 32 auslesen - Teil 1 - AZ-Delivery

Musik begleitet uns durch den Alltag und die Möglichkeit, aktuelle Wiedergabeinformationen wie Titel, Interpret und Album direkt auszulesen, eröffnet Möglichkeiten, um diese Daten auf einem Display darzustellen und somit eine kreative Dekoration für den Schreibtisch zu erhalten. Mit einem ESP32 und der Spotify-API lassen sich diese Daten einfach abrufen und vielseitig nutzen.
In diesem Blogbeitrag werden Sie die Grundlagen der API Requests an den Get Current Playing Track API Endpoint von Spotify kennenlernen.

Hardware:

Board mit ESP32-Chip; Zum Beispiel: Dev Kit C V2 oder Dev Kit C V4 USB-C

Software:

Falls Sie das erste Mal einen ESP32 in der Arduino IDE programmieren, kopieren Sie folgenden Link in der Arduino IDE unter: File->Preferences->Additional boards manager URLs :  https://dl.espressif.com/dl/package_esp32_index.json
und installieren Sie in der Boardverwaltung das ESP32 Paket.

Der Treiber(CP2102) für dieses Board ist bereits vom Betriebssystem installiert.

Die Spotify API bietet eine Vielzahl an API Endpoints, um Informationen abzurufen, oder Benutzerinteraktionen umzusetzen. Um die Daten wie Titel, Künstler, Album und Fortschritt abzurufen, ist die Get Current Playing Track API passend.

1 Erstellen einer Spotify App

Um die Spotify API nutzen zu können, müssen Sie sich mit ihrem Spotify Account auf der Spotify Entwickler Seite anmelden und das Dashboard öffnen (klicken auf Account oben rechts). Im Dashboard klicken Sie auf den Button Create App und tragen als Nächstes einen beliebigen Namen und Beschreibung ein. Für den redirect Host benutzen Sie die folgende Adresse: http://localhost/callback , diese Adresse wird für die Authentifizierung benötigt. Als API Typ wählen Sie Web API.
Nach erfolgreicher Konfiguration der Spotify App können Sie unter dem Punkt Settings der App eine Client ID und durch Klicken auf “View client Secret” den API key einsehen.

Speichern Sie sich diese beiden Informationen zwischen.

2 Autorisierung

Öffnen Sie nun in Ihrem Browser den folgenden Link unter Verwendung der ID aus dem vorherigen Schritt:

https://accounts.spotify.com/authorize?response_type=code&client_id=YOUR_CLIENT_ID&scope=user-read-currently-playing%20user-read-playback-state&redirect_uri=http://localhost/callback

Nach einer kurzen Zeit öffnet sich ein Fenster, in dem nach der Zustimmung gefragt wird. Nach dem Zustimmen liefert der Browser nun eine Antwort, die wie folgt aussehen sollte:

Speichern Sie sich hier den Code (in der Suchleiste nach code=) ebenfalls zwischen. Bei diesem Code handelt es sich um einen Authorization Token.
Nachdem Sie jetzt den Authorization Code erhalten haben, muss dieser über die API gegen einen Request Token “getauscht” werden. Generelle Informationen dazu finden Sie in der Dokumentation. 

Für die Kommunikation mit der API über einen Arduino eignet sich die im ESP32 Paket enthaltene HTTPclient Library. Da die Antwort des Servers im json Format erfolgt, wird für die Dekodierung in Klartext die ArduinoJson Bibliothek benötigt.

Die Library kann über den Link als .zip heruntergeladen und in der Arduino IDE unter Sketch>Include Library>Add .ZIP Library… hinzugefügt werden.
Falls Sie PlatformIO verwenden, kopieren Sie folgendes in die lib_deps in der platformio.ini Datei:

bblanchon/ArduinoJson@^7.2.1

3 Abfrage des Refresh & Access Tokens

Durch folgenden Programmcode wird der Authorization Token, bei erster Inbetriebnahme, im finalen Programm von der API abgefragt:

HTTPClient http;
http.
begin(tokenEndpoint);

 
// Set headers
  http.addHeader(
"Content-Type", "application/x-www-form-urlencoded");
  http.addHeader(
"Authorization", "Basic " + base64Encode(String(clientID) + ":" + String(clientSecret)));

 
// Prepare the POST body
 
String body = "grant_type=authorization_code";
  body +=
"&code=" + authorizationCode;
  body +=
"&redirect_uri=http://localhost/callback";

 
int httpResponseCode = http.POST(body);

 
// Check the response
 
if (httpResponseCode == 200) {
   
String payload = http.getString();
   
//Serial.println("Response: " + payload);

   
// Parse the JSON response
    DynamicJsonDocument doc(
2048);
    DeserializationError error = deserializeJson(doc, payload);

   
if (error) {
     
Serial.println("JSON Parsing Error");
      http.
end();
     
return false;
    }

   
// Extract tokens
    accessToken = doc[
"access_token"].as<String>();
    refreshToken = doc[
"refresh_token"].as<String>();

   
Serial.println("Access Token: " + accessToken);
   
Serial.println("Refresh Token: " + refreshToken);
    StoreString(refreshToken);

    http.
end();
   
return true;
  }
else {
   
Serial.println("HTTP POST failed with code: " + String(httpResponseCode));
    http.
end();
   
return false;
  }

 

Der im ersten Schritt erhaltene Authorization Token wird im finalen Programm durch den Seriellen Monitor auf das Board übertragen.
Zuerst werden nach den Vorgaben der Dokumentation ein HTTP Header und ein Body mit den Informationen erstellt. Diese werden dann mit POST an den Spotify-Server übermittelt, wenn der Antwort-Code 200 erhalten wird, war die Anfrage erfolgreich, die übermittelten Daten können zwischengespeichert und die benötigten Informationen extrahiert werden.
Informationen über den Ablauf erhalten Sie unter folgender Dokumentationsseite: Codeflow.

4 Aktualisierung des Access Tokens

Da der Access Token nur einen begrenzten Zeitraum von einer Stunde gültig ist, muss dieser nach dem Ablaufen wieder aktualisiert werden. Das grundlegende Programm bleibt, wie bei der ersten Abfrage des Request Tokens, unverändert, nur wird jetzt statt des Authorisation Codes der Request Token aus dem ersten Schritt verwendet.

5 Abfrage der Daten

Nachdem jetzt gesichert ist, dass immer ein aktueller Access Token vorliegt, kann zur Abfrage der relevanten Informationen gewechselt werden. Auf der Dokumentationsseite befindet sich auf der rechten Seite die Antwort des Servers mit den aktuellen Daten Ihres Accounts. Vom ESP32 können diese Daten mit folgendem Programm abgefragt werden:

  HTTPClient http;
 
 
// Configure HTTP GET request
  http.
begin(endpoint);
  http.addHeader(
"Authorization", "Bearer " + accessToken);

 
int httpResponseCode = http.GET();
 
if (httpResponseCode == 200) {
   
String payload = http.getString();
   
//Serial.println("Response: " + payload);

   
// Parse JSON response
    DynamicJsonDocument doc(
4096);
    DeserializationError error = deserializeJson(doc, payload);
   
if (error) {
     
Serial.println("Failed to parse JSON");
     
return;
    }

   
// Extract track data
   
const char* trackName = doc["item"]["name"];

    const char* artistName = doc["item"]["artists"][0]["name"];

    const char* albumName = doc["item"]["album"]["name"];
   
int durationS = doc["item"]["duration_ms"];
   
int progressS = doc["progress_ms"];
    durationS = durationS /
1000;
    progressS = progressS /
1000;

   
// Display the data
   
Serial.println("Now Playing:");
   
Serial.println("Track: " + String(trackName));
   
Serial.println("Artist: " + String(artistName));
   
Serial.println("Album: " + String(albumName));
   
//Serial.println("Album Image URL: " + String(albumImage));
   
Serial.println("Duration (s): " + String(durationS));
   
Serial.println("Progress (s): " + String(progressS));
   
float perc = ((float)progressS/(float)durationS) * 100;
   
Serial.printf("Progress     : %.2f \n", perc);

  }
else if (httpResponseCode == 204) {
   
Serial.println("No track is currently playing");
  }
else if (httpResponseCode == 401) {
   
Serial.println("expired Token");
    refreshAccessToken();
  }
 
 
else {
   
Serial.println("HTTP GET failed with code: " + String(httpResponseCode));
  }

  http.
end();

Als erstes wird der HTTP Header generiert und danach mit dem POST Befehl an den Server gesendet. Der Antwort-Code 401 bedeutet, dass der Access Token nicht mehr gültig ist und erneuert werden muss. Bei Code 200 werden die empfangenen Daten aus dem JSON Format extrahiert und in die entsprechenden Variablen zwischengespeichert. Für die bessere Ablesbarkeit werden die Zeiten in Sekunden umgewandelt und danach alle Informationen (Titel, Künstler, Album, Dauer, vergangene Zeit und Fortschritt) auf dem Seriellen Monitor ausgegeben.

6 Finales Programm

Laden Sie das finale Programm auf das Board und geben Sie den Authorization Token über den Monitor ein. Im Seriellen Monitor sollten die Daten des gerade abgespielten Songs angezeigt werden.

Sollte es zu Problemen kommen, vergleichen Sie den HTTP Response Code mit den verschiedenen Codes aus der Dokumentation.

 

Das komplette Programm können Sie hier als Datei herunterladen.

Erklärung des Programms:
Im setup() wird der gespeicherte Token abgerufen. Wenn kein Token vorhanden ist, muss dieser im Seriellen Monitor eingegeben werden. Im Programm wird deshalb so lange gewartet, bis eine Eingabe erfolgt ist und dieser Code daraufhin im SPIFFS gespeichert wird. Falls bereits ein Request Token vorhanden ist, wird mittels diesem ein Access Token angefragt. Im loop() werden die Informationen unter Verwendung des oben generierten Access Tokens abgerufen. Die erhaltenen Daten werden daraufhin im Seriellen Monitor ausgegeben.
Sollte der HTTP request den Code 401 liefern, heißt dies, dass der Access Token abgelaufen ist, und erneuert werden muss, dies wird automatisch durchgeführt.

Im Programm befinden sich des weiteren drei Hilfsmethoden.
Die Methode base64Encode() ändert die Zugangsdaten in das base64 Format, welches von der API Schnittstelle verlangt wird.
Die letzten zwei Funktionen sind store- und read-Token welche verwendet werden, um den Refresh Token im Flash zu speichern. Der gespeicherte Token bleibt auch nach einem neuen Flashen des Programms erhalten, somit muss die Autorisierung nur bei der ersten Inbetriebnahme durchgeführt werden.

 

Nachdem dieser Teil die grundlegende Kommunikation mit der API Schnittstelle thematisiert hat, werden Sie im nächsten Teil noch weitere nützliche Funktionen der Spotify API Endpoints kennenlernen. Des Weiteren werden die jetzt ermittelten Informationen genutzt, um sie auf einem Display benutzerfreundlich darzustellen.

Viel Spaß beim Nachbauen :)

Spotify und Spotify Premium sind eingetragene Marken von Spotify AB. Dieser Blog steht in keiner Verbindung zu Spotify AB und wird weder von Spotify AB gesponsert noch unterstützt. Alle in diesem Beitrag verwendeten Markennamen, Logos und Warenzeichen gehören ihren jeweiligen Eigentümern und werden ausschließlich zur Beschreibung oder Identifikation verwendet.

Esp32Für arduino

Kommentar hinterlassen

Alle Kommentare werden von einem Moderator vor der Veröffentlichung überprüft

Empfohlene Blogbeiträge

  1. ESP32 jetzt über den Boardverwalter installieren - AZ-Delivery
  2. Internet-Radio mit dem ESP32 - UPDATE - AZ-Delivery
  3. Arduino IDE - Programmieren für Einsteiger - Teil 1 - AZ-Delivery
  4. ESP32 - das Multitalent - AZ-Delivery