Improve PulseAudio/PipeWire integration and audio device discovery - #240
Conversation
Set PULSE_PROP_application.{name,id,icon_name} and media.role at process
startup so that libpulse (used by the ALSA pulse/pipewire plug devices and
pipewire-pulse) registers the playback stream as "Sendspin" instead of a
generic "ALSA plug-in [python3]". Highlight the pulse/pipewire/default
device names in `audio-devices list` and the --audio-device help so users
discover the sound-server-routed options.
Refs #239
https://claude.ai/code/session_01H1fE1RpT8dQd3FEhveB5qe
There was a problem hiding this comment.
Pull request overview
This PR improves Linux desktop audio output ergonomics by setting PulseAudio/PipeWire client metadata for better stream identification and by making common desktop routing device choices easier to discover and understand from the CLI.
Changes:
- Add
_set_pulse_client_metadata()to set libpulse-related environment properties before audio client connections. - Enhance
audio-devices listoutput with “Recommended for desktop usage” routing options when present (pulse,pipewire,default). - Update
--audio-devicehelp text in both player and daemon modes to mention desktop routing options.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| def main() -> int: | ||
| """Run the CLI client.""" | ||
| _set_pulse_client_metadata() |
There was a problem hiding this comment.
_set_pulse_client_metadata() is called unconditionally from main(), so these PulseAudio/PipeWire-related env vars are set even on non-Linux platforms and for subcommands that never touch audio output (e.g., serve/servers/clients). If the intent is “only affect Linux desktop environments”, add a sys.platform.startswith("linux") (or similar) guard around the call (or inside the helper) to avoid unnecessary global environment side effects.
| _set_pulse_client_metadata() | |
| if sys.platform.startswith("linux"): | |
| _set_pulse_client_metadata() |
There was a problem hiding this comment.
Good catch — fixed in 145404b. Wrapped the call in if sys.platform.startswith("linux"): so non-Linux platforms and the audio-less subcommands (serve, servers list, clients list) don't touch the global env at all.
Generated by Claude Code
- Only call _set_pulse_client_metadata() on Linux; the PULSE_PROP_* env vars have no effect elsewhere and there's no reason to mutate the global env on macOS/Windows or for the serve/servers/clients subcommands. - Update the daemon --audio-device help to mention raw ALSA device names (e.g. dmixer, olohuone) — the daemon goes through the same resolve_audio_device() / _try_alsa_device() path as the player, so the help should match. https://claude.ai/code/session_01H1fE1RpT8dQd3FEhveB5qe
Upstream rolled two minors with material fixes for our flows: 7.2.0 (PR Sendspin/sendspin-python-cli#240, #241): - Better PulseAudio / PipeWire integration and audio device discovery - Fixed an ALSA device leak 7.3.0 (PR Sendspin/sendspin-python-cli#246, #245, #244, #247): - Fixed unwanted catch-up when joining mid-stream playback — the bridge rejoins streams routinely (after BT reconnect, after warm_restart from /api/config saves, after standby exit), so this was a recurring source of audible artifacts at the start of speaker resumes. - Fixed wrong audio sync delta after a server-driven delay change — matters because MA pushes per-player static_delay_ms (we advertise set_static_delay since v2.68.0), and a slider drag in MA produced a brief glitch from the bad delta. - Aligned stream/clear and stream/end with the protocol spec (drops role versions). - Bumped aiosendspin to 5.2 — already on our side via #271. No breaking changes between 7.1.0 and 7.3.0; the 7.0.0 per-player delay break is already absorbed (see CHANGELOG 2.68.0). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
This PR enhances Sendspin's audio output handling on Linux desktop environments by properly identifying the application to the sound server and improving the audio device discovery experience.
Key Changes
PulseAudio/PipeWire metadata: Added
_set_pulse_client_metadata()function that sets libpulse environment variables before client connection, allowing the audio stream to register as "Sendspin" instead of a generic "ALSA plug-in [python3]" name. Users can override these defaults by setting their own environment variables.Audio device recommendations: Enhanced
list_audio_devices()to display recommended desktop audio routing options (pulse,pipewire,default) when available, making it easier for users to choose appropriate devices.Improved help text: Updated help documentation for the
--audio-deviceargument in both player and daemon modes to explicitly mention thatpulse,pipewire, anddefaultare available routing options on Linux desktops.Automatic initialization: The metadata setup is called automatically in
main()before argument parsing, ensuring proper identification with the sound server from the start.Implementation Details
os.environ.setdefault()to respect user overrideshttps://claude.ai/code/session_01H1fE1RpT8dQd3FEhveB5qe