Skip to content

Add DLNA Receiver plugin provider#3611

Draft
trudenboy wants to merge 2 commits intomusic-assistant:devfrom
trudenboy:upstream/dlna_receiver
Draft

Add DLNA Receiver plugin provider#3611
trudenboy wants to merge 2 commits intomusic-assistant:devfrom
trudenboy:upstream/dlna_receiver

Conversation

@trudenboy
Copy link
Copy Markdown
Contributor

@trudenboy trudenboy commented Apr 7, 2026

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

  • SSDP discovery — advertises virtual MediaRenderers via multicast (239.255.255.250:1900)
  • Multi-player mode — one renderer per MA player (e.g. "Music Assistant — Kitchen"), each with a unique UDN and HTTP port
  • DIDL-Lite metadata — parses title, artist, album, cover art, duration from control point metadata
  • Elapsed time tracking — continuously updates progress in MA UI via StreamMetadata
  • Audio proxy — streams audio URL through PluginSource / get_audio_stream() into the MA pipeline
  • GENA eventing — UPnP event subscriptions for AVTransport, RenderingControl, ConnectionManager
  • Recursion filter — own renderers are excluded from the player list to prevent feedback loops
  • Full SCPD — complete service description XMLs for all three UPnP services

Architecture

DLNA Control Point
       │
       ▼
  SSDP Discovery ──► UPnP HTTP Server (SOAP actions)
                           │
                           ▼
                    PluginSource bridge
                           │
                           ▼
                    MA streaming pipeline ──► Target Player

Changed files

File Description
__init__.py Config entries (friendly name, target players, bind IP, HTTP port)
provider.py DLNAReceiverProvider(PluginProvider) — lifecycle, DIDL parsing, metadata loop, audio proxy
renderer.py UPnPRenderer — aiohttp server handling SOAP actions (SetAVTransportURI, Play, Pause, Stop, etc.)
ssdp.py SSDPAdvertiser — multicast SSDP alive/byebye/search responses
eventing.py GENA event subscription manager (SUBSCRIBE/RENEW/UNSUBSCRIBE/NOTIFY)
constants.py UPnP URNs, config keys, MIME type mappings
scpd/*.xml Full service description XMLs for AVTransport, RenderingControl, ConnectionManager
manifest.json Provider manifest (plugin_provider, domain dlna_receiver)
tests/ 37 unit tests covering renderer SOAP handling, SSDP, eventing, provider logic

Notes

  • Requires network_mode: host in Docker for SSDP multicast to work
  • The existing dlna player provider (MA as DLNA client) is complementary — this adds the server side

Source: trudenboy/ma-provider-dlna-receiver · tag v1.0.0

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

🔒 Dependency Security Report

✅ No dependency changes detected in this PR.

@trudenboy trudenboy changed the title feat(dlna_receiver): add dlna_receiver provider v1.0.0 feat: add DLNA Receiver plugin provider Apr 7, 2026
@trudenboy trudenboy changed the title feat: add DLNA Receiver plugin provider Add DLNA Receiver plugin provider Apr 7, 2026
@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Apr 7, 2026

Isn’t this the same as #2501 which we just decided not to progress due to security concerns?

@marcelveldt
Copy link
Copy Markdown
Member

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)

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented Apr 7, 2026

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?

@trudenboy
Copy link
Copy Markdown
Contributor Author

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

#2501 (DLNA Server) This PR (DLNA Renderer)
Direction MA exposes its library outward MA receives audio from external apps
Security risk Yes - streaming provider content accessible via unauthenticated DLNA No - MA never exposes any content; it only accepts incoming streams
Piracy vector Any LAN client could download tracks None - the control point already owns/has access to the content
Complexity Needs full library scanning, stream resolution Lightweight - just an HTTP/SOAP endpoint that proxies a URL

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:

  1. Native streaming apps - Qobuz desktop, Tidal, or other apps handle their own auth/DRM. MA can't always access those streams natively, but these apps can cast to a DLNA renderer.

  2. NAS media libraries - users with large FLAC/DSD collections on Synology/QNAP running MinimServer or Asset UPnP. They already have a curated UPnP media server and don't want to re-index everything in MA. With this plugin, BubbleUPnP -> MA -> any player.

  3. Phone-as-remote - audiophile apps like BubbleUPnP (Android), mconnect (iOS), HiFi Cast provide superior browsing UIs for some users. They pick music on their phone and push it to a renderer. MA becomes a universal audio sink that routes to its entire player infrastructure (Chromecast, Sonos, ALSA, squeezelite, etc.).

  4. Multi-room fan-out - instead of each speaker needing its own DLNA renderer stack, MA acts as a single DLNA endpoint that fans out to grouped players.

  5. Third-party apps - audiobook players, podcast apps, DJ software, foobar2000, JRiver - anything that supports UPnP renderer output can now play through MA without any native integration.

In short

The existing dlna player provider makes MA a DLNA controller (MA -> speakers). This plugin makes MA a DLNA target (apps -> MA -> speakers). Together they complete the DLNA story without the security concerns of #2501, since no MA content is ever exposed.

Happy to discuss any architectural or security concerns!

@marcelveldt
Copy link
Copy Markdown
Member

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 :-)

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.

3 participants