From 5db90844cbc3ec55e0f878a845a76776f1a12b51 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 4 Jun 2026 06:34:00 -0400 Subject: [PATCH] fix(android): DIDL-Lite includes Rincon namespace + cdudn desc for Sonos --- .../player/output/upnp/AVTransportClient.kt | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/output/upnp/AVTransportClient.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/output/upnp/AVTransportClient.kt index 61e2a2ad..11dbbe58 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/output/upnp/AVTransportClient.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/output/upnp/AVTransportClient.kt @@ -204,22 +204,29 @@ class AVTransportClient( } private fun buildDidlLite(uri: String, mime: String, title: String): String { - // Sonos firmware accepts boolean-style restricted ("true"/"false") only - // and rejects "1"/"0" silently; if it can't parse our DIDL it regenerates - // its own with generic class object.item, no title, and the URL query - // string as the displayed name (logcat 2026-06-04 confirmed). Match the - // SoCo convention which the firmware definitely accepts. + // Sonos requires (a) the rinconnetworks namespace declared on + // even if we don't use Rincon elements directly, and + // (b) a element identifying the URI as an + // external (non-Sonos-library) source. Without those, Sonos + // discards our metadata content and regenerates its own with + // class=object.item and the URL query string as the title + // (logcat 2026-06-04 confirmed). Match SoCo's pattern. val safeTitle = title.ifBlank { "Minstrel" } return buildString { append("") + append("xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\" ") + append("xmlns:r=\"urn:schemas-rinconnetworks-com:metadata-1-0/\">") append("") append("").append(xmlEscape(safeTitle)).append("") append("object.item.audioItem.musicTrack") append("").append(xmlEscape(uri)).append("") + append("") + append("RINCON_AssociatedZPUDN") + append("") append("") append("") }