StevenLooman / python-didl-lite

DIDL-Lite (Digital Item Declaration Language) tools for Python
Other
7 stars 1 forks source link

WiiM Pro issue #13

Closed pp81381 closed 1 day ago

pp81381 commented 1 week ago

Hi,

I have a WiiM Pro and I've noticed that it doesn't quite comply with the UPnP standard in that it doesn't structure the DIDL-Lite event messages correctly. The upnp:class element is in the wrong place in the schema. It should be inside the item element but for some reason it is before the item element instead. Example below.

I note that at line 1095 of didl_lite.py, python-didl-lite (correctly) looks for the upnp class within the item element. I'm wondering whether an option could be added to make it less strict or perhaps specifically allow this for WiiM devices?

I raised a ticket with WiiM about this 6 months ago and they did acknowledge it but nothing has happened yet. I have high hopes that they might fix it one day but I'm thinking that it would be good to have a workaround for us Home Assistant users until they do.

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<DIDL-Lite xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
    xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\"
    xmlns:song=\"www.wiimu.com/song/\"
    xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\">
    <upnp:class>object.item.audioItem.musicTrack</upnp:class>
    <item id=\"0\">
        <song:subid></song:subid>
        <song:description></song:description>
        <song:skiplimit>0</song:skiplimit>
        <song:id></song:id>
        <song:like>0</song:like>
        <song:singerid>0</song:singerid>
        <song:albumid>0</song:albumid>
        <song:actualQuality>LOSSLESS</song:actualQuality>
        <song:atmos>0</song:atmos>
        <song:rate_hz>44100</song:rate_hz>
        <song:format_s>16</song:format_s>
        <song:bitrate>676</song:bitrate>
        <res protocolInfo=\"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;\" duration=\"00:04:44.000\"></res>
        <dc:title>Sweet Lands Experience</dc:title>
        <dc:creator>Underworld</dc:creator>
        <upnp:artist>Underworld</upnp:artist>
        <upnp:album>Strawberry Hotel</upnp:album>
        <upnp:albumArtURI>https://resources.tidal.com/images/272e8ef1/dccc/4fab/ba67/31805d45740e/640x640.jpg</upnp:albumArtURI>
    </item>
</DIDL-Lite> `

FYI, here's my really ugly workaround:

        upnp_class = child_el.find("./upnp:class", NAMESPACES)
        if upnp_class is None or not upnp_class.text:
            upnp_class = xml_el.find("./upnp:class", NAMESPACES) # UGH
            if upnp_class is None or not upnp_class.text:
                continue

Would be keen to hear what you think.

Regards,

StevenLooman commented 6 days ago

Hi @pp81381. Thank you for this issue. I'm certainly not opposed this. In fact, you can use the strict=False argument to the __init__() methods of the didl lite objects for the purpose of work-arounds.

Feel free to create a PR where, if strict=False, the library behaves in a bit more lenient way.

pp81381 commented 1 day ago

Thanks again for this. Once this is released, it would be great if you could also bump the version of didl_lite used by async-upnp-client too please. The ultimate goal is to get this into Home Assistant at some point.