Skip to content

fix: fall back to an available device when starting playback with no active device#1007

Open
ecschoye wants to merge 1 commit into
aome510:masterfrom
ecschoye:fix/start-playback-device-fallback
Open

fix: fall back to an available device when starting playback with no active device#1007
ecschoye wants to merge 1 commit into
aome510:masterfrom
ecschoye:fix/start-playback-device-fallback

Conversation

@ecschoye

Copy link
Copy Markdown

Summary

When the user starts a new playback (e.g. pressing Enter on a search result) and there is no active playback at that moment, spotify_player silently fails with "No playback found. Please start a new playback. Make sure there is a running Spotify device ...", even though the integrated streaming device is still available. Restarting the app fixes it. This makes StartPlayback recover the same way startup already does.

Related: #705, #710.

Root cause

PlayerRequest::StartPlayback derives its target device solely from the current buffered playback:

let device_id = playback.as_ref().and_then(|p| p.device_id.as_deref());
self.start_playback(p, device_id).await?;

If the integrated device goes idle and Spotify drops it as the active device, the playback poller sets player.playback = None (and clears buffered_playback). After that, device_id is None, so start_playback sends no device id and the Web API targets "the currently active device", of which there is none, producing the error.

initialize_playback does not hit this because on startup it falls back to find_available_device(), which explicitly appends the integrated device id (session.device_id()) under the streaming feature. The runtime play path had no equivalent recovery, which is why only a restart helped.

Fix

In the StartPlayback branch, when no device id is available from the current playback, fall back to find_available_device(), the exact recovery initialize_playback already uses:

let device_id = match playback.as_ref().and_then(|p| p.device_id.clone()) {
    Some(id) => Some(id),
    None => self.find_available_device().await?,
};
self.start_playback(p, device_id.as_deref()).await?;

Scoped to StartPlayback only. The other requests (Resume, NextTrack, Pause, ...) legitimately operate on an existing playback and keep their no playback found guard.

Scope / limitation

This recovers the common case where the integrated device is still registered but no longer the active device. It does not address librespot fully deregistering the device after a network blip (the librespot-side reconnection discussed in #705 / #710), which is a separate concern.

Testing

  • cargo build -p spotify_player — passes.
  • cargo clippy -p spotify_player — no warnings.
  • cargo check -p spotify_player --features streaming — passes (exercises the integrated-device branch in find_available_device).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant