As you say the playlists are just lists of absolute paths to files
I wasn't talking about playlists specifically; every level in the browse hierarchy is an item from a list (in very simple terms) that's been sent from the server (MinimServer/Emby) to the control point (WHA) for displaying to the user.
If we take MinimServer as an example, the initial browse tree is sent to the control point as DIDL:
XML:
<DIDL-Lite>
<container id="0$albums" parentID="0" restricted="1" searchable="1">
<dc:title>8 albums</dc:title>
<upnp:class>object.container</upnp:class>
</container>
<container id="0$items" parentID="0" restricted="1" searchable="1">
<dc:title>30 items</dc:title>
<upnp:class>object.container</upnp:class>
</container>
<container id="0$playlists" parentID="0" restricted="1" searchable="1">
<dc:title>2 playlists</dc:title>
<upnp:class>object.container</upnp:class>
</container>
<container id="0$=Artist" parentID="0" restricted="1" searchable="1">
<dc:title>Artist</dc:title>
<upnp:class>object.container</upnp:class>
</container>
<container id="0$=Genre" parentID="0" restricted="1" searchable="1">
<dc:title>Genre</dc:title>
<upnp:class>object.container</upnp:class>
</container>
...
...
</DIDL-Lite>
As you can see we have our initial browsing hierarchy:
Code:
8 albums
30 items
2 playlists
Artist
Genre
...
When we select '2 playlists' the WHA requests the next level in the hierarchy from MinimServer:
XML:
<DIDL-Lite>
<container id="0$playlists$*p0" parentID="0$playlists" childCount="1" restricted="1" searchable="1">
<dc:title>Playlist aa</dc:title>
<upnp:class>object.container.playlistContainer</upnp:class>
</container>
<container id="0$playlists$*p1" parentID="0$playlists" childCount="1" restricted="1" searchable="1">
<dc:title>Playlist zz</dc:title>
<upnp:class>object.container.playlistContainer</upnp:class>
</container>
</DIDL-Lite>
Which translates to:
The only way to bookmark an item (excluding tracks) is to record the container id (Playlist zz = '0$playlists$*p1'), but there is nothing in the UPnP specification to say that the internal browsing id's have to persist across rescans, so for most servers they don't.
If you had bookmarked Playlist zz (0$playlists$*p1) then created a new playlist called 'Playlist mm' and performed a MinimServer rescan, your bookmark would now be pointing to your new playlist, because the container id's MinimServer generates are distributed alphabetically e.g.
Initial scan:
Code:
Playlist Container id
Playlist aa.m3u 0$playlists$*p0
Playlist zz.m3u 0$playlists$*p1
Add 'Playlist mm' and rescan:
Code:
Playlist Container id
Playlist aa.m3u 0$playlists$*p0
Playlist mm.m3u 0$playlists$*p1
Playlist zz.m3u 0$playlists$*p2
I have suggested to WiiM that using UPnP search is a better alternative, but this differs across servers too (some don't even support search!).
Not every server works the same way (I've used MinimServer for years so I know how it works) but
hopefully you now understand why it's not a simple request.