Spotify: end the session for OTA; app volume starts at the player's
- OTA: the player now ends the Spotify session (spotify_suspend: stop flag, waits until the session's tasks are gone, refuses new ones) instead of pausing it, and suspends HLS. Pausing was not enough (an upload still failed once with a paused session). Verified twice with a session running for minutes: "Disconnecting mercury session / session ended / suspended", installed in ~26 s, clean reboot. - Volume: createFromBlob() starts cspot at volume 0, which the app showed while we played at 100 %. The session now starts with the player's volume (spotify_set_volume); volumes coming from the app are stored exactly, without echo. Verified: slider starts at 100 %. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,12 +33,44 @@ static std::string s_name; // advertised device nam
|
||||
static std::atomic<bool> s_enabled{false};
|
||||
static std::atomic<bool> s_stop{false}; // end the running session
|
||||
static std::atomic<bool> s_got_blob{false};
|
||||
static std::atomic<bool> s_in_session{false}; // session() running (its tasks may exist)
|
||||
static std::atomic<int> s_volume{65535}; // player volume in Spotify units (0..65535)
|
||||
static std::atomic<const char *> s_state{"disabled"};
|
||||
static std::atomic<uint64_t> s_pcm_bytes{0};
|
||||
static std::shared_ptr<cspot::SpircHandler> s_handler; // running session, else null
|
||||
static spotify_pcm_cb_t s_pcm_cb;
|
||||
static spotify_event_cb_t s_event_cb;
|
||||
|
||||
extern "C" void spotify_suspend(bool suspend)
|
||||
{
|
||||
if (!suspend) {
|
||||
spotify_apply();
|
||||
return;
|
||||
}
|
||||
s_enabled = false;
|
||||
s_stop = true;
|
||||
s_got_blob = false;
|
||||
s_state = "suspended";
|
||||
for (int i = 0; i < 30 && s_in_session; i++) { // session loop exits within 200 ms, then disconnect
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
ESP_LOGI(TAG, "suspended%s", s_in_session ? " (session still ending)" : "");
|
||||
}
|
||||
|
||||
extern "C" void spotify_set_volume(int pct)
|
||||
{
|
||||
pct = pct < 0 ? 0 : pct > 100 ? 100 : pct;
|
||||
int v = pct * 65535 / 100;
|
||||
if (v == s_volume) {
|
||||
return;
|
||||
}
|
||||
s_volume = v;
|
||||
auto h = s_handler;
|
||||
if (h) {
|
||||
h->setRemoteVolume(v);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void spotify_pause(bool pause)
|
||||
{
|
||||
auto h = s_handler;
|
||||
@@ -203,6 +235,8 @@ static void session(void)
|
||||
ctx->config.clientSecret = client_secret;
|
||||
ctx->config.audioFormat = bitrate >= 320 ? AudioFormat_OGG_VORBIS_320
|
||||
: bitrate >= 160 ? AudioFormat_OGG_VORBIS_160 : AudioFormat_OGG_VORBIS_96;
|
||||
// createFromBlob() starts at volume 0, which the app would show; report what we actually play.
|
||||
ctx->config.volume = s_volume;
|
||||
s_state = "connecting";
|
||||
ctx->session->connectWithRandomAp();
|
||||
auto token = ctx->session->authenticate(login);
|
||||
@@ -246,6 +280,7 @@ static void session(void)
|
||||
}
|
||||
break;
|
||||
case E::VOLUME:
|
||||
s_volume = std::get<int>(ev->data); // exact value from the app, no echo back
|
||||
if (s_event_cb) {
|
||||
s_event_cb(SPOTIFY_EV_VOLUME, std::get<int>(ev->data));
|
||||
}
|
||||
@@ -278,6 +313,7 @@ static void spotify_task(void *arg)
|
||||
}
|
||||
s_got_blob = false;
|
||||
s_stop = false;
|
||||
s_in_session = true;
|
||||
try {
|
||||
session();
|
||||
} catch (const std::exception &e) {
|
||||
@@ -285,6 +321,7 @@ static void spotify_task(void *arg)
|
||||
ESP_LOGE(TAG, "session ended: %s", e.what());
|
||||
}
|
||||
s_handler.reset();
|
||||
s_in_session = false;
|
||||
vTaskDelay(pdMS_TO_TICKS(2000));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user