Skip to content

Add Local Audio Out player provider#3585

Merged
marcelveldt merged 7 commits into
devfrom
stupefied-ptolemy
Apr 5, 2026
Merged

Add Local Audio Out player provider#3585
marcelveldt merged 7 commits into
devfrom
stupefied-ptolemy

Conversation

@marcelveldt

Copy link
Copy Markdown
Member

Problem

There was no way to use locally attached soundcards (USB DACs, built-in speakers, HDMI audio) as players in Music Assistant.

Changes

  • New local_audio player provider that enumerates local audio output devices via PortAudio/sounddevice
  • Registers as PlayerType.PLAYER with Sendspin as protocol for synchronized playback
  • Per-device hardware volume control via CoreAudio (macOS) and ALSA/amixer (Linux), with software volume fallback
  • Configurable volume control mode at provider level (hardware/software/disabled)
  • Protocol linking via UUID identifiers for automatic Sendspin association
  • depends_on: sendspin in manifest to ensure correct load order

marcelveldt and others added 3 commits April 5, 2026 11:33
Introduces a new builtin player provider that exposes locally attached
soundcards as Sendspin players via the bridge pattern. Uses sounddevice
(PortAudio) for cross-platform device enumeration and PCM output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 5, 2026 16:44
@github-actions

github-actions Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

🔒 Dependency Security Report

📦 Modified Dependencies

music_assistant/providers/local_audio/manifest.json

Added:

The following dependencies were added or modified:

diff --git a/requirements_all.txt b/requirements_all.txt
index 1f064578..809f1709 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -70,6 +70,7 @@ shortuuid==1.0.13
 snapcast==2.3.7
 soco==0.30.14
 soundcloudpy==0.1.4
+sounddevice==0.5.5
 srptools>=1.0.0
 sxm==0.2.8
 unidecode==1.4.0

New/modified packages to review:

  • sounddevice==0.5.5

🔍 Vulnerability Scan Results

No known vulnerabilities found
✅ No known vulnerabilities found


Automated Security Checks

  • Vulnerability Scan: Passed - No known vulnerabilities
  • Trusted Sources: All packages have verified source repositories
  • Typosquatting Check: No suspicious package names detected
  • License Compatibility: All licenses are OSI-approved and compatible
  • Supply Chain Risk: Passed - packages appear mature and maintained

Manual Review

Maintainer approval required:

  • I have reviewed the changes above and approve these dependency updates

To approve: Comment /approve-dependencies or manually add the dependencies-reviewed label.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new built-in local_audio player provider to expose locally attached soundcards as Music Assistant players by bridging Sendspin PCM output to PortAudio/sounddevice, including provider-level volume control configuration and container/runtime dependency updates.

Changes:

  • Introduces music_assistant/providers/local_audio/ provider implementation (player, bridge manager, CoreAudio volume helper, config entries, manifest, docs, icon).
  • Adds sounddevice==0.5.5 to the full requirements set and libportaudio2 to the base Docker image for runtime support.
  • Implements a Sendspin external-player bridge that writes incoming PCM to sounddevice.RawOutputStream with optional software volume scaling.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
requirements_all.txt Adds sounddevice to the “all” dependency set.
Dockerfile.base Installs libportaudio2 needed by sounddevice at runtime.
music_assistant/providers/local_audio/init.py Provider entrypoint + config entries (volume control mode).
music_assistant/providers/local_audio/provider.py Provider lifecycle wiring (init/load/unload/discover).
music_assistant/providers/local_audio/player.py Local player entity + hardware/software volume handling.
music_assistant/providers/local_audio/sendspin_bridge.py Device discovery + per-device Sendspin external bridge + audio writer.
music_assistant/providers/local_audio/constants.py Provider constants (UUID namespace, buffer size, config keys).
music_assistant/providers/local_audio/coreaudio_volume.py macOS CoreAudio volume/mute control via ctypes.
music_assistant/providers/local_audio/manifest.json Declares provider metadata + Sendspin dependency + sounddevice requirement.
music_assistant/providers/local_audio/README.md Provider documentation/architecture overview.
music_assistant/providers/local_audio/icon.svg Provider icon asset.

Comment thread music_assistant/providers/local_audio/sendspin_bridge.py
Comment thread music_assistant/providers/local_audio/sendspin_bridge.py Outdated
Comment thread music_assistant/providers/local_audio/sendspin_bridge.py
Comment thread music_assistant/providers/local_audio/player.py
Comment thread music_assistant/providers/local_audio/player.py
Comment thread music_assistant/providers/local_audio/sendspin_bridge.py
Comment thread music_assistant/providers/local_audio/player.py Outdated
Use amixer -c <card_index> to target the specific ALSA card instead of
the default card, so hardware volume works correctly when multiple USB
soundcards are attached on Linux.
@marcelveldt marcelveldt added the dependencies-reviewed Indication that any added or modified/updated dependencies on a PR have been reviewed label Apr 5, 2026
- Fix _is_streaming not reset on writer failure (memory leak)
- Use register_or_update to handle re-discovery
- Mark player unavailable on bridge start failure
- Check amixer return code and fallback to software on failure
Copilot AI review requested due to automatic review settings April 5, 2026 16:51
When volume is changed from the Sendspin side (e.g. a Sendspin
controller), forward it to our player so hardware/software volume
stays in sync.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 11 changed files in this pull request and generated 4 comments.

Comment thread music_assistant/providers/local_audio/player.py
Comment thread music_assistant/providers/local_audio/player.py
Comment thread music_assistant/providers/local_audio/sendspin_bridge.py
Comment thread music_assistant/providers/local_audio/README.md
@marcelveldt marcelveldt merged commit 7233c0f into dev Apr 5, 2026
11 checks passed
@marcelveldt marcelveldt deleted the stupefied-ptolemy branch April 5, 2026 17:03
OzGav pushed a commit that referenced this pull request Apr 6, 2026
iVolt1 added a commit to iVolt1/server that referenced this pull request Apr 18, 2026
@adminlife24

adminlife24 commented Jun 11, 2026

Copy link
Copy Markdown

I have Home Assistant OS
Core 2026.6.2
Supervisor 2026.05.1
Operating System 17.3
MUSIC ASSISTANT 2.9.0 addon
Local Audio Out player provider does not find my audio card built into my mini PC HP ProDesk 600 G4 mini. In the logs it says: 2026-06-11 16:11:48.942 INFO (MainThread) [music_assistant] Loaded player provider Local Audio Out 2026-06-11 16:11:48.946 INFO (MainThread) [music_assistant.local_audio.bridge_manager] No local audio output devices found 2026-06-11 16:11:48.949 INFO (MainThread) [music_assistant.local_audio.bridge_manager] No local audio output devices found.

Sink #0 17:59 [180/208]
State: IDLE
Name: alsa_output.pci-0000_00_1f.3.analog-stereo
Description: Built-in Audio Analog Stereo
Driver: module-alsa-card.c
Sample Specification: s16le 2ch 48000Hz
Channel Map: front-left,front-right
Owner Module: 6
Mute: no
Volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
balance 0.00
Base Volume: 65536 / 100% / 0.00 dB
Monitor Source: alsa_output.pci-0000_00_1f.3.analog-stereo.monitor
Latency: 1267890 usec, configured 1837500 usec
Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY
Properties:
alsa.resolution_bits = "16"
device.api = "alsa"
device.class = "sound"
alsa.class = "generic"
alsa.subclass = "generic-mix"
alsa.name = "Generic Analog"
alsa.id = "Generic Analog"
alsa.subdevice = "0"
alsa.subdevice_name = "subdevice #0"
alsa.device = "0"
alsa.card = "0"
alsa.card_name = "HDA Intel PCH"
alsa.long_card_name = "HDA Intel PCH at 0x4000100000 irq 136"
alsa.driver_name = "snd_hda_intel"
device.bus_path = "pci-0000:00:1f.3"
sysfs.path = "/devices/pci0000:00/0000:00:1f.3/sound/card0"
device.bus = "pci"
device.vendor.id = "8086"
device.product.id = "a348"
device.form_factor = "internal"
device.string = "front:0"
device.buffering.buffer_size = "352800"
device.buffering.fragment_size = "176400"
device.access_mode = "mmap+timer"
device.profile.name = "analog-stereo"
device.profile.description = "Analog Stereo"
device.description = "Built-in Audio Analog Stereo"
module-udev-detect.discovered = "1"
device.icon_name = "audio-card-pci"
Ports:
analog-output-speaker: Speakers (type: Speaker, priority: 10000, availability unknown)
analog-output-headphones: Headphones (type: Headphones, priority: 9900, available)
analog-output-headphones-2: Headphones 2 (type: Headphones, priority: 9800, not available)
Active Port: analog-output-headphones
Formats:
pcm

@OzGav

OzGav commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

@adminlife24 you shouldn't post on closed PRs as we may not see it. This will likely fix your problem #3724

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

Labels

dependencies-reviewed Indication that any added or modified/updated dependencies on a PR have been reviewed new-provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants