Add DLNA Receiver plugin provider#3611
Add DLNA Receiver plugin provider#3611trudenboy wants to merge 19 commits intomusic-assistant:devfrom
Conversation
🔒 Dependency Security Report✅ No dependency changes detected in this PR. |
|
Isn’t this the same as #2501 which we just decided not to progress due to security concerns? |
I think this one is the other way around. It turns MA into a DLNA target to send audio to (as source) |
|
Ok then I’m a little confused as to why this is needed as why wouldn’t MA just get the media items directly from where ever the DLNA app is getting them from? |
|
Thanks for the question @OzGav - it's a fair one! Let me clarify both the difference from #2501 and the "why" behind this. How this differs from #2501
Why not "just get the media directly in MA"?This is the key question. There are real scenarios where the audio source cannot or should not be accessed directly by MA:
In shortThe existing Happy to discuss any architectural or security concerns! |
|
I think it's fine to add it - as long as you take care of maintenance @trudenboy as I am not a fan of DLNA :-) |
There was a problem hiding this comment.
Pull request overview
Adds a new dlna_receiver plugin provider that exposes Music Assistant as a UPnP/DLNA MediaRenderer, enabling DLNA control points to discover MA via SSDP and control playback (SOAP/GENA) toward configured MA players.
Changes:
- Introduces a UPnP renderer HTTP server (device description, SCPDs, SOAP actions) plus GENA event subscription/notification handling.
- Implements SSDP multicast advertisement and M-SEARCH responses for discovery on the local network.
- Adds unit tests covering URL helpers, SSDP behavior, renderer SOAP handling, and eventing logic.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
music_assistant/providers/dlna_receiver/__init__.py |
Provider setup + config entries for DLNA receiver. |
music_assistant/providers/dlna_receiver/manifest.json |
Declares the new plugin provider manifest. |
music_assistant/providers/dlna_receiver/constants.py |
Centralizes UPnP/SSDP constants and config keys. |
music_assistant/providers/dlna_receiver/urls.py |
Adds URL validation/redaction helpers (security-related). |
music_assistant/providers/dlna_receiver/ssdp.py |
Implements SSDP advertise/search response logic. |
music_assistant/providers/dlna_receiver/eventing.py |
Implements GENA subscriptions + NOTIFY dispatch. |
music_assistant/providers/dlna_receiver/renderer.py |
Implements aiohttp UPnP renderer (SOAP, SCPD serving, event routes). |
music_assistant/providers/dlna_receiver/provider.py |
Implements provider lifecycle, multi-renderer management, playback bridging, metadata parsing. |
music_assistant/providers/dlna_receiver/scpd/AVTransport.xml |
Service description for AVTransport actions/state variables. |
music_assistant/providers/dlna_receiver/scpd/RenderingControl.xml |
Service description for RenderingControl actions/state variables. |
music_assistant/providers/dlna_receiver/scpd/ConnectionManager.xml |
Service description for ConnectionManager actions/state variables. |
tests/providers/dlna_receiver/__init__.py |
Test package marker for the provider’s tests. |
tests/providers/dlna_receiver/test_urls.py |
Tests for URL validation/redaction helpers. |
tests/providers/dlna_receiver/test_ssdp.py |
Tests for SSDP advertiser and MX parsing. |
tests/providers/dlna_receiver/test_eventing.py |
Tests for subscription parsing/timeout/propertyset building. |
tests/providers/dlna_receiver/test_renderer.py |
Tests for SOAP action handling and SCPD serving. |
tests/providers/dlna_receiver/test_provider.py |
Tests for deterministic UDN generation and renderer instantiation behavior. |
Summary
New plugin provider that exposes Music Assistant as a UPnP/DLNA MediaRenderer on the local network. External apps (BubbleUPnP, Qobuz, foobar2000, mconnect, etc.) can discover MA via SSDP and cast audio streams to any configured player.
Key features
239.255.255.250:1900)StreamMetadataPluginSource/get_audio_stream()into the MA pipelineAVTransport,RenderingControl,ConnectionManagerArchitecture
Changed files
__init__.pyprovider.pyDLNAReceiverProvider(PluginProvider)— lifecycle, DIDL parsing, metadata loop, audio proxyrenderer.pyUPnPRenderer— aiohttp server handling SOAP actions (SetAVTransportURI, Play, Pause, Stop, etc.)ssdp.pySSDPAdvertiser— multicast SSDP alive/byebye/search responseseventing.pyconstants.pyscpd/*.xmlmanifest.jsonplugin_provider, domaindlna_receiver)tests/Notes
network_mode: hostin Docker for SSDP multicast to workdlnaplayer provider (MA as DLNA client) is complementary — this adds the server sideRelated PRs