Skip to content

feat+fix(config): add Auto streaming mode with is_active && is_playing disambiguation - #1049

Open
louzt wants to merge 2 commits into
aome510:masterfrom
louzt:feat/streaming-auto-mode
Open

louzt wants to merge 2 commits into
aome510:masterfrom
louzt:feat/streaming-auto-mode

Conversation

@louzt

@louzt louzt commented Jul 29, 2026 •

Copy link
Copy Markdown

Summary

enable_streaming currently accepts Always, DaemonOnly, and Never. There is no option for the common case where the user already has a Spotify Connect device active (phone, smart speaker, TV) and does not want the terminal client to spin up a second local audio engine.

This PR adds Auto, with one important refinement discovered during local validation:

  • When Auto is selected, the client queries both available_devices() and current_playback(). Web API remote-control mode is only entered when both signals agree: a Connect device reports is_active == true and the user's account currently reports is_playing == true. Any other case (no devices, devices online but idle, or a failed playback probe) falls back to the existing Always path and boots a local librespot session.

Typical use case: an Amazon Echo linked to the user's account is sitting idle in another room. Opening the terminal client on the laptop should pair audio locally, not defer to the standby Echo.

Background

The initial scope of this PR used is_active alone as the disambiguator. Local validation against a real account showed that a Connect device which is online but idle still reports is_active == true, which would leave the TUI in Web API remote-control mode with no local audio engine and surface a misleading No playback found message. Cross-referencing current_playback().is_playing rules out that case without re-introducing the original problem the user wanted to avoid (a second audio engine while a real device is playing).

The fix is intentionally narrow:

  • is_active == true && is_playing == true → Web API mode (existing behaviour).
  • is_active == false (no devices, or all idle) → local librespot.
  • is_active == true && is_playing == false (online device, idle account) → local librespot.
  • available_devices() error or current_playback() error → local librespot, with a tracing::warn! explaining which probe failed. This preserves the Always-style fallback semantics.

Changes

This PR adds only the is_active && is_playing disambiguation. The base Auto enum variant and its branches live in #1049.

Compatibility

  • Default stays Always; existing users see no behaviour change.
  • enable_streaming = "Auto" is now a valid value. Existing true / false, Always, DaemonOnly, and Never continue to work identically.
  • No public API changes. StreamingType is a public enum and adding a variant is additive.

Validation

cargo fmt --all -- --check
cargo check --no-default-features --features rodio-backend,media-control,streaming,image,notify,fzf
cargo clippy --no-default-features --features rodio-backend,media-control,streaming,image,notify,fzf -- -D warnings

All three pass clean. Full release build also succeeds (cargo build --release --features streaming,image,notify,media-control,rodio-backend,fzf).

Repro / environment

Verified by the reporter on:

Local log evidence (sanitized — track names and URIs removed, identifiers kept) showing the fix correctly identifying an idle Echo and falling back to local librespot:

INFO  librespot_playback::audio_backend::rodio: Using Rodio sink with format S16 and cpal host: ALSA
INFO  librespot_playback::audio_backend::rodio: Using audio device: default
INFO  spotify_player::client: Auto streaming: no active playback detected
      (active_devices=false, playing=false); initializing a local librespot player
INFO  librespot_playback::player: Loading <track-1> with Spotify URI <spotify:track:REDACTED>
INFO  librespot_playback::player: <track-1> (165857 ms) loaded
INFO  librespot_playback::player: Loading <track-2> with Spotify URI <spotify:track:REDACTED>
INFO  librespot_playback::player: <track-2> (78342 ms) loaded

Notes

louzt added 2 commits July 28, 2026 16:36
…t device

When `enable_streaming = "Auto"`, the client first queries the user's
available Spotify Connect devices. If any device is already active, it
skips the local librespot initialization and operates in Web API mode
(remote control only). If no device is active, or the device query
fails, it falls back to the existing `Always` path.

This lets users with another Spotify Connect device active (phone,
desktop, smart speaker) run the terminal client without spawning a
second audio engine, while keeping a single uniform config knob.

- config: add `Auto` variant to `StreamingType` and `RawStreamingType`
- client: route `Auto` through `available_devices()` in `new_session`

No behavior change for `Always` / `DaemonOnly` / `Never`.
…to streaming

The Auto streaming mode currently treats any device with is_active == true
as evidence that something is already playing, and skips local librespot
initialization in favour of Web API remote control. A Spotify Connect device
(e.g. an Amazon Echo linked to the user's account) reports is_active == true
while it is idle in standby, which leaves the TUI with no local audio and
surfaces the 'No playback found' message.

Resolve Auto against both available_devices() and current_playback(): only
enter Web API mode when a Connect device is actively playing. Any other case
(no devices, devices online but idle, or a failed playback probe) falls back
to the existing local librespot path, preserving the Always-style behaviour
on error.

This is a follow-up to aome510#1049. The fix is intentionally narrow:
  - public API unchanged
  - Default behaviour for Always / DaemonOnly / Never unchanged
  - Failure mode unchanged: any probe error falls back to local librespot
@louzt louzt changed the title feat(config): add Auto streaming mode that defers to an active Spotify Connect device feat+fix(config): add Auto streaming mode with is_active && is_playing disambiguation Jul 31, 2026
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