29
29
30
30
#include < TJpg_Decoder.h> // Ensure you include the required decoder library
31
31
32
- // HTTP client setup remains as is in your project
33
-
34
- int SpotifyPlayer::getAlbumReleaseYear ()
35
- {
36
- // // if (!_pCurrentTrack->albumUri || strlen(_pCurrentTrack->albumUri) == 0)
37
- // if (_currentlyPlayingMetadata.albumUri == nullptr)
38
- // {
39
- // spLogE(LOGTAG_PLAYER, "Album URI is empty.");
40
- // return -1; // Indicate error
41
- // }
42
-
43
- // // Extract album ID from albumUri (typically of the form spotify:album:<id>)
44
- // String albumId = String(_currentlyPlayingMetadata.albumUri).substring(14); // Skip "spotify:album:"
45
-
46
- // String url = "https://api.spotify.com/v1/albums/" + albumId + "?market=US";
47
-
48
- // HTTPClient http;
49
- // WiFiClientSecure wifiClient;
50
- // //wifiClient.setInsecure(); // TODO: Remove... just debugging...
51
- // wifiClient.setCACert(spotify_server_cert); // Ensure proper certificate
52
-
53
- // http.begin(wifiClient, url);
54
- // http.addHeader("Authorization", "Bearer " + _spotifyRefreshToken); // Use your Spotify token
55
-
56
- // int httpCode = http.GET();
57
- // if (httpCode != 200)
58
- // {
59
- // spLogE(LOGTAG_PLAYER, "Failed to get album details, HTTP code: %d", httpCode);
60
- // http.end();
61
- // return -1;
62
- // }
63
-
64
- // // Parse JSON response
65
- // String payload = http.getString();
66
- // http.end();
67
-
68
- // DynamicJsonDocument doc(1024);
69
- // deserializeJson(doc, payload);
70
-
71
- // // Get release_date (e.g., "2020-05-01")
72
- // const char* releaseDate = doc["release_date"];
73
- // if (releaseDate && strlen(releaseDate) >= 4)
74
- // {
75
- // String year = String(releaseDate).substring(0, 4);
76
- // return year.toInt();
77
- // }
78
-
79
- // // spLogE(LOGTAG_PLAYER, "Release date not found in album details.");
80
- return -1 ; // Indicate error
81
- }
82
-
83
32
// Spotify related
84
33
#define SP_SPOTIFY_MARKET " IE"
85
34
@@ -127,9 +76,21 @@ SpotifyPlayer& SpotifyPlayer::getInstance()
127
76
128
77
void SpotifyPlayer::initialize (QueueHandle_t *pScuiQueue)
129
78
{
130
- // _pUI = pUI;
131
79
_pScuiQueue = pScuiQueue;
132
- initSpotify ();
80
+
81
+ // keep reference since SpotifyArduino is dependent on values
82
+ // remaining in memory
83
+ _spotifyClientId = Vault::getInstance ().getSpotifyClientID ();
84
+ _spotifyClientSecret = Vault::getInstance ().getSpotifyClientSecret ();
85
+
86
+ _pSpotify = new SpotifyArduino (
87
+ client,
88
+ _spotifyClientId.c_str (),
89
+ _spotifyClientSecret.c_str ()
90
+ );
91
+ // client is defined in ThingPulse/spotify.h
92
+ client.setCACert (spotify_server_cert);
93
+
133
94
}
134
95
135
96
/*
@@ -170,30 +131,48 @@ void SpotifyPlayer::startBackgroundRefreshes()
170
131
171
132
/*
172
133
** ===================================================================
173
- ** verifyRefreshToken ()
134
+ ** isRefreshTokenAvailable ()
174
135
**
175
- ** Returns true if previously saved token found; false otherwise.
136
+ ** Returns whether the refresh token is available. This will also
137
+ ** internally initialize the token if it exists.
176
138
** ===================================================================
177
139
*/
178
- bool SpotifyPlayer::verifyRefreshToken ()
140
+ bool SpotifyPlayer::isRefreshTokenAvailable ()
179
141
{
180
- _spotifyRefreshToken = SCFileIO::getInstance ().readFsString (SPOTIFY_REFRESH_TOKEN_FILE_NAME);
181
- if (_spotifyRefreshToken == " " )
182
- {
183
- spLogI (LOGTAG_PLAYER, " No Spotify refresh token found. Requesting one through the browser via auth code." );
142
+ _spotifyRefreshToken = SCFileIO::getInstance ().readFsString (SPOTIFY_REFRESH_TOKEN_FILE_NAME);
143
+
144
+ if (_spotifyRefreshToken == " " )
145
+ {
146
+ spLogI (LOGTAG_PLAYER, " Spotify refresh token not found." );
147
+ return false ;
148
+ }
149
+ else
150
+ {
151
+ spLogI (LOGTAG_PLAYER, " Spotify refresh token found." );
152
+ return true ;
153
+ }
154
+ }
184
155
185
- String spotifyAuthCode = fetchSpotifyAuthCode ();
186
- _spotifyRefreshToken = spotify.requestAccessTokens (spotifyAuthCode.c_str (), SPOTIFY_REDIRECT_URI);
187
- SCFileIO::getInstance ().saveFsString (SPOTIFY_REFRESH_TOKEN_FILE_NAME, _spotifyRefreshToken);
156
+ /*
157
+ ** ===================================================================
158
+ ** requestRefreshToken()
159
+ **
160
+ ** Requests a fresh refresh token. A refresh token is a security
161
+ ** credential that allows client applications to obtain new access
162
+ ** tokens without requiring users to reauthorize the application.
163
+ ** ===================================================================
164
+ */
165
+ bool SpotifyPlayer::requestRefreshToken ()
166
+ {
188
167
189
- return false ;
168
+ spLogI (LOGTAG_PLAYER, " Requesting Spotify refresh token through the browser via auth code." );
169
+
170
+ String spotifyAuthCode = fetchSpotifyAuthCode ();
171
+ _spotifyRefreshToken = _pSpotify->requestAccessTokens (spotifyAuthCode.c_str (), SPOTIFY_REDIRECT_URI);
172
+ SCFileIO::getInstance ().saveFsString (SPOTIFY_REFRESH_TOKEN_FILE_NAME, _spotifyRefreshToken);
173
+
174
+ return true ;
190
175
191
- }
192
- else
193
- {
194
- spLogI (LOGTAG_PLAYER, " Using previously saved Spotify refresh token." );
195
- return true ;
196
- }
197
176
}
198
177
199
178
/*
@@ -217,8 +196,8 @@ void SpotifyPlayer::login()
217
196
// - keeps track of the refresh token and its TTL internally
218
197
// - automatically renews the actual access token using the refresh token
219
198
// -> see SpotifyArduino.h#autoTokenRefresh and SpotifyArduino::checkAndRefreshAccessToken() (called before every API function)
220
- spotify. setRefreshToken (_spotifyRefreshToken.c_str ());
221
- spotify. refreshAccessToken ();
199
+ _pSpotify-> setRefreshToken (_spotifyRefreshToken.c_str ());
200
+ _pSpotify-> refreshAccessToken ();
222
201
spLogI (LOGTAG_PLAYER, " Authentication against Spotify done. Refresh token: %s" , _spotifyRefreshToken.c_str ());
223
202
}
224
203
@@ -273,7 +252,7 @@ void SpotifyPlayer::nextSong()
273
252
static_cast <int >(TFTColor::SC_NetworkInProgress));
274
253
if (xSemaphoreTake (_xSemaphoreNetwork, portMAX_DELAY))
275
254
{
276
- if (spotify. nextTrack ())
255
+ if (_pSpotify-> nextTrack ())
277
256
{
278
257
// _pUI->drawStatusBox(TFTColor::SC_NetworkSuccess);
279
258
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
@@ -316,7 +295,7 @@ void SpotifyPlayer::previousSong()
316
295
317
296
if (xSemaphoreTake (_xSemaphoreNetwork, portMAX_DELAY))
318
297
{
319
- if (spotify. previousTrack ())
298
+ if (_pSpotify-> previousTrack ())
320
299
{
321
300
// _pUI->drawStatusBox(TFTColor::SC_NetworkSuccess);
322
301
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
@@ -362,7 +341,7 @@ void SpotifyPlayer::pauseSong()
362
341
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
363
342
" Making Call" ,
364
343
static_cast <int >(TFTColor::SC_NetworkInProgress));
365
- if (spotify. pause ())
344
+ if (_pSpotify-> pause ())
366
345
{
367
346
// _pUI->drawStatusBox(TFTColor::SC_NetworkSuccess);
368
347
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
@@ -385,7 +364,7 @@ void SpotifyPlayer::pauseSong()
385
364
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
386
365
" Making Call" ,
387
366
static_cast <int >(TFTColor::SC_NetworkInProgress));
388
- if (spotify. play ())
367
+ if (_pSpotify-> play ())
389
368
{
390
369
// _pUI->drawStatusBox(TFTColor::SC_NetworkSuccess);
391
370
postScuiMessage (SCUIMessageType::UM_STATUS_BOX,
@@ -435,7 +414,7 @@ void SpotifyPlayer::refreshCurrentTrack()
435
414
spLogI (LOGTAG_MULTITASK, " Invoking spotify.getCurrentlyPlaying(...)" );
436
415
// vTaskDelay(pdMS_TO_TICKS(200));
437
416
Monitor::start (MONITOR_ID_SPOTIFY_GET_CURRENTLY_PLAYING, LOGTAG_METRICS, " spotify.getCurrentlyPlaying(...)" );
438
- status = spotify. getCurrentlyPlaying (SpotifyPlayer::getCurrentlyPlayingCallback, SP_SPOTIFY_MARKET);
417
+ status = _pSpotify-> getCurrentlyPlaying (SpotifyPlayer::getCurrentlyPlayingCallback, SP_SPOTIFY_MARKET);
439
418
Monitor::stop (MONITOR_ID_SPOTIFY_GET_CURRENTLY_PLAYING);
440
419
xSemaphoreGive (_xSemaphoreNetwork);
441
420
}
0 commit comments