DLNA Media Controller plugin - Common library for UPnP AV

Plugin version 0.8 has been released.
You can download it here (ZIP archive at the bottom of this page): 1.0 in tags – DLNA Media Controller

What’s new in version 1.0:

[ol][li]
Device category updated (set to AV)
[/li]
[li]
Short codes added for the following state variables: CurrentTitle, CureentArtist, CurrentAlbum, CurrentPlayMode and online
[/li]
[li]
Plugin icon with transparency
[/li]
[li]
Init all variables when the device is created
[/li][/ol]

What’s new in version 0.8:

[ol][li]
Volume control added in the device panel
[/li]
[li]
Volume control added in the UI player tab
[/li]
[li]
New UI tab for TTS
[/li]
[li]
AVTransport and RenderingControl services files renamed again
[/li][/ol]

What’s new in version 0.7:

[ol][li]
New TTS library with multiple engines support
[/li]
[li]
New parameter Engine for the Say action
[/li][/ol]

What’s new in version 0.6:

[ol][li]
Fixed: relative URL in the XML description
[/li]
[li]
Improove performance when browsing content + abort timeout (30 s) in case of very big content
[/li]
[li]
Workaround for a bug in Freebox Player firmware 1.2.12
[/li][/ol]

What’s new in version 0.5:

[ol][li]
Fixed: compatibility with MiniDLNA and Synology servers
[/li]
[li]
Changed: log of debug information
[/li]
[li]
New variable DebugLogs; default value is 0; value set to 1 enables log of additional debug information
[/li][/ol]

What’s new in version 0.4:

[ol][li]
Fixed: Ignore case for transport actions (required for GMrender Media Renderer)
[/li]
[li]
Fixed: handling protocol for the PS3 Media Server
[/li]
[li]
Changed: Play action has now an optional parameter named “Protocol”
[/li]
[li]
Changed! PlayDMSMedia action has now an additional parameter named “DescriptionURL”
[/li]
[li]
UI Player and Settings tab: display of identity for discovered servers and renderers changed
[/li]
[li]
UI Player tab: a protocol amongst all the protocols accepted by the Media Renderer can now be selected in addition to the URI
[/li]
[li]
UI Player tab: new entry named “None” in the protocol pick list; when selected, no protocol information is delivered to the Media Renderer
[/li]
[li]
UI Player tab: new info message displayed
[/li]
[li]
UI Help tab: display information about last played media server object
[/li]
[li]
UI Help tab: list of protocols accepted by the Media Renderer is now displayed in the Help tab
[/li]
[li]
UI Settings tab: current Media Renderer is now selected by default in the “discover” pick list
[/li]
[li]
New variable DelayBeforePlayback: delay in ms before SetAVTransportURI and Play; default value is 0
[/li]
[li]
New variable CheckStateRate: delay in minutes between automatic state checks; default value is 0 meaning no automatic check
[/li]
[li]
New variable DefaultLanguageTTS: default language (2 characters) used by TTS; default value is “en” meaning “english”
[/li]
[li]
Changed: files renamed for AVTransport and RenderingControl services
[/li][/ol]

What’s new in version 0.3:

[ol][li]
Fixed: browsing media from BubbleUPnP server
[/li]
[li]
Fixed: compatibility check between the Media Renderer and the Media Server
[/li][/ol]

What’s new in version 0.2:

[ol][li]
fixed: browsing of Media Servers
[/li]
[li]
fixed: managing of URI with non standard characters like French accents
[/li]
[li]
fixed: do not try to set AV transport URI when URI is not set (not found)
[/li]
[li]
control added to find a compatible protocol between the media to be played with the protocols accepted by the Media Renderer
[/li]
[li]
UI updated: browsing of Media Servers
[/li]
[li]
UI updated: user can now select an available server protocol or let the plugin select automatically a protocol compatible with the Media Renderer
[/li]
[li]
Scene editor: actions are now available in the devices tab
[/li]
[li]
action BrowseDMS: parameters updated
[/li]
[li]
action PlayItem: renamed into PlayDMSMedia and parameters updated
[/li]
[li]
new variable SinkProtocolInfo: store the list (CSV) of protocols accepted by the Media Renderer
[/li]
[li]
new variable CurrentAlbumArt2: same as CurrentAlbumArt except when CurrentAlbumArt is not accessible; in this case, it is set to a default album art
[/li][/ol]

It is a classical installation, meaning you have to upload all the files with the Vera UI, except the PNG file that requires to be uploaded using WinSCP in directory /www/cmh/skins/default/icons/
Then create a new device using D_DLNAMediaController1.xml. Don’t care about the IP. Restart LUA. When restarted, refresh your browser cache (Ctrl+F5). Then open the Settings tab to select your DMR, either using the UPnP discovery or filling in the UPnP device description URL. Wait few seconds until the setup is done and that’s all, you can now open the Player tab.

Automatic discovery (UPnP discovery) could require an additional setup of your Vera Lite. Please read the explanations in this message if it does not work directly: ​http://forum.micasaverde.com/index.php/topic,16905.msg132502.html#msg132502

Known issues:

[ol][li]
PS3 Media Server sometimes uses MIMITYPE_AUTO in the protocol information; it is not yet well managed by the plugin and the playback of the media will not be accepted by the plugin.
[/li]
[li]
“Last server media played” field value displayed in the Help tab cannot always be copied and pasted in the parameter of the action PlayDMSMedia; depending on the server and the used format for the object id, it can work well or not.
[/li][/ol]

Squeezebox plugin doesn’t use upnp, it uses the telnet service of the squeezebox server. I’ll look into seeing if it can support upnp.

  • Garrett

With this done … how far from making Vera a DLNA Media Controller that can control any DLNA Media Server and Player ?

A UPnP controller library is a natural next step. I sort of had it in the back of my mind when I was writing the WeMo code, so it’s sort of broken into platform-dependent functions and platform-independent functions. I’ve got absolutely no time to commit to it, though, but I’ll gladly donate any code that I’ve already written to the cause.

A UPnP AV / DLNA Media Controller would require 3 items:

  • UPnP discovery of UPnP AV Media servers and UPnP AV Media renderer: - this is not implemented and may be bot easy from Vera (I don’t know)
  • Browse media on UPnP AV Media servers: this is more a user manual task and something that requires a good UI. Vera is not really a good choice for this task
  • Send a media to a UPnP AV Media Renderer: this is typically what we can do with Vera.

Unfortunately, it exists a lot of UPnP AV Media Player (Playstation PS3, Freebox Player, some TV, some DVD and BR players, …) but only few UPnP AV Media Renderers. Media Player don’t provide UPnP interface for remote control by a Control Point. After a quick WEB search, the candidates for a control by a control point would be only:

  • XBMC
  • Windows Media Player/Connect
  • BubbleUPnP (Android)
  • Sonos

So, I can make a generic plugin for these few Media Renderers (XBMC and WMP).

PS: finally XBMC seems to not be a UPnP Media Server, there is no browse capability exposed to UPnP. It is a Media Player + Media Renderer.
PS2: Sonos is a Media Server + Media Renderer

One problem to make something generic is that every device implements its own subset of UPnP AV services. This can be retrieved from the description (XML) file. With Vera, we are constrained by statically declared services.
And I even not sure that in Vera we can hevae different services with the same service type/id ?
Does DLNA defines standard services (AVTransport, RenderingControl, …) ?

On the DLNA Web site, we can serarch for certified DLNA products.
It look slike the Xbox 360 is a Media Renderer. So it could be probably controlled from the Vera too.

Regarding BubbleUPnP: https://play.google.com/store/apps/details?id=com.bubblesoft.android.bubbleupnp&hl=fr

BubbleUPnP is a full featured UPnP/DLNA Control Point, [b]UPnP Media Renderer [/b] and UPnP Media Server

So it is a new candidate.

Updated list of UPnP AV Media Renderers:

  • Xbox 360
  • XBMC
  • Windows Media Player/Connect
  • BubbleUPnP (Android)
  • Sonos

On Wikipedia, we can find the list of UPnP media render hardware: List of UPnP AV media servers and clients - Wikipedia
This list includes Sonos and Xbox 360. But it seems that this list includes few products that are only Media Player without ability to control by a remote control point, like for example “Panasonic Plasma Viera NeoPDP V10-Series”. I will check again this evening.
So I am sure that the list in Wikipedia makes a clear distinction between Media Player and Media Renderer.

Do you think that browsing UPnP Media Server from the Vera could be of any real interest ?
Through actions ?
Through UI ?

Regarding UPnP AV standards, we can find all services here: OPEN CONNECTIVITY FOUNDATION (OCF)
So we could define the 4 different versions of AVTransport service for example.
But if I take Sonos example, it does not use the standard, Sonos add additional actions to the AVTransport:1 service.

So if we want something as generic as possible, we use the standards as services, but in this case, we could loose some actions really provided by certain UPnP devices.

Here are ideas:

  • we could have a generic UPnP AV controller plugin, based on UPnP AV standards services.
  • For Sonos plugin (example), we would define additional services, like Sonos_AVTransport:1 that will contain specific actions and state variables defined by Sonos that are not in the UPnP AV standards.

Other point: few URL are currently hardcoded, while they should be extracted from the description file, like control URL or event URL. But without UPnP discovery implementation, that would require that the user provides the URL for the XML device description file.

We might need layers of shared components. I think it would be good to have components that match the standards where they are defined … with a specialization layer that customizes for some specific devices. This would allow continued development to someday get to a DLNA controller.

On the other hand Vera App store provides no support for handling/managing/enforcing the dependencies between shared components.
It will not allow us to maintain the files as components and replicate in a plugin … it enforces that ALL file names are unique across all plugins.

I have a shared evaluation engine between PLEG and PLTS in an invisible plugin called PLC. This is very confusing for users to have a plugin that has no devices on the UI … and then of course they have the problem of making sure all components have compatible versions …

I could first create a generic plugin UPnP_AV_DMC, defining and implementing standard UPnP AV services. This plugin should be ok to control basically any existing UPnP DMR.
This generic plugin would become a template for any specific DMC plugin, like Sonos or XBMC for example.
A specific DMC plugin would allow to add non standard features. It will consist in:

  • defining new dedicated services for non standard actions and state variables
  • implementing some of the standard services actions and dedicated services
  • using the generic plugin library for the standard stuff
  • adding specific code, including UI, for the non standard stuff

The generic plugin would include:
1 - a common library for UPnP: the current L_Sonos1.lua library + additional utility functions relative to UPnP proxy event plugin; a check has to be done to WeMo plugin for UPnP request code, in case it is better handled in WeMo plugin.
2 - a common library for standard UPnP AV with all standard actions implemented

[quote=“lolodomo, post:11, topic:177228”]Regarding UPnP AV standards, we can find all services here: OPEN CONNECTIVITY FOUNDATION (OCF)
So we could define the 4 different versions of AVTransport service for example.
But if I take Sonos example, it does not use the standard, Sonos add additional actions to the AVTransport:1 service.[/quote]
It’s part of the [UPnP] standard to permit “extensions”, and these (both state and action) are permitted to live within the existing Service files (but these must be downloadable/discoverable from the Device. These are logically in the same namespace, so putting them into separate/special S_ files, in addition to the standard/baseline ones, might cause havoc on the declarations in the corresponding D_*.xml files

This is why I checked in the Sonos ones as S_Sonos*.xml, which also avoids NS collisions.

Technically, and with a little work, these could be dynamically downloaded/stored as required. They’d likely end up with odd-looking names, but it would then be possible to code-gen the wrappers using (a derivative of) L_Sonos.lua

This is functionality that’s supposed to be in Vera, but has never really worked.

Anyhow, given there aren’t that many things that folks want to control, and it’s not too hard to do the important ones by hand. The hard part here is that Vera lacks a dependency system. These could readily be packaged into a Lib (plus related files) but we’d be left without a mechanism to indicate that “Plugin X requires Lib Y” from the App Store.

There would also need to be a LOT more thought given to compatible changes over time.

On Squeezebox…
The original Sonos plugin had several things done to it to support a UPnP interface to SqueezeBox, at the [PM] request of 'Ap. Not sure that the validation was ever done though.

On L_Sonos.lua…
The one thing I should have done when I originally wrote this is to extract out the “Connection” level information, into a connection object, and then have the service-level objects require that. It wouldn’t be a hard change to make, and I’d make it before broadening the usage of this lib, since there are other “things” that need the connection also.

A usual, you break my enthousiasm :slight_smile: If I listen to you, I just do nothing because the ideal cannot be reached (due to MCV implementaition or bugs) :slight_smile:
My idea is more to do what is possible to do with what we have. And I think there is now place for a generic UPnP AV Media Control plugin.

Ok, we keep a full service file for each specific UPnP device. I just discovered that they can be easily retrieved from one URL displayed by Device Spy. No need to create the file manually.
I can at least create the standard services for the generic UPnP device.

Technically, what I want to improove is at least get device supported services from the device description file and then filter these services to keep only the services having a service type defined in the D_xxx.xml file. Then I will automatically initialize in the plugin code a service (call to upnp.service) for these services. Is it possible with lua to go through the services attached to a device ? Edit: function device_supports_service should help me.

Not my intent to put you off, just to ensure that you’re aware of the UPnP ruleset, vs what MCV has done… mostly to avoid problems down the line (where we assume that the MCV [UPnP rules were correct, and box ourselves into a corner)… This is easy to do, since they often don’t validate stuff.

Ok, we keep a full service file for each specific UPnP device. I just discovered that they can be easily retrieved from one URL displayed by Device Spy. No need to create the file manually.
Yup, that's what I was referring to when I said you could do it dynamically. Each UPnP endpoint provides a way to retrieve these, and they could be stored locally, using locally-derived names, as needed. The rest would have to be code-gen'd, but again, not mission impossible (I tried this some time back in the SQ stuff, in UI4, but it should work better in UI5)
Is it possible with lua to go through the services attached to a device ?
There's a method to "ask" if a Device supports a service, not enumerate them, but I've never tried it: http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_device_supports_service

Worst case, it’s always possible to derive since the I_*.xml stuff gets code-gen’d into fns. You can likely grab hold of the fn table from inside of Lua, and then just enum it (again, haven’t tried, but lots of stuff like this is exposed in Lua, so there’s a lot of hacking potential). The names of the code-gen’d stuff follow the Service/Action names with a reasonable pattern (a bit lossy).

… On a related note, I’ve always wondered if this technique can be used to dynamically inject methods [at startup, etc] into the runtime map of an I_*.xml, so that you could do the type of thing really needed… just haven’t had the time to play with that (or inclination, since I’ll eventually move off Vera, it’s just my prototyping platform).

I suspect the Service validations, added in UI5, would get a little in the way if it were tried.

[quote=“guessed, post:16, topic:177228”]

Is it possible with lua to go through the services attached to a device ?

There’s a method to “ask” if a Device supports a service, not enumerate them, but I’ve never tried it:
http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_device_supports_service[/quote]

This function does not eexactly what I expect because it returns true if you have a variable of a certain service id set for the device, even if this service is not declared in the D_xxx.xml file.
You could say that it might not normal to be in such a case. Maybe something to change in the Sonos plugin.

I see there are 4 versions of MediaServer and MediaRenderer.
Are they all used today ? Or is almost everybody using MediaServer:1 and MediaRenderer:1 ?

Just for Info if it can help, My Sony Amp Media Renderer and my Raspberry Media Renderer both use MediaRenderer:1 service

I just realize I reply to your other thread about XBMC (http://forum.micasaverde.com/index.php/topic,16879.msg130899.html#msg130899) while my post probably must be here …

My initial idea to control XBMC through UPnP has quickly evolved in a more general plugin that I could name “DLNA Media Renderer Controller”. It should work with any DLNA Digital Media Renderer.
I will add some settings presets to help final users selecting the settings for certain usual DMR like XBMC, Windows Media Connect, BubbleUPnP, …
If you can provide the URL of the XML description file of your specific DMR, I can add a preset for it. And the description file itself would be appreciated too.