DLNA, client side

While we were busy fixing the server and rendering side of DLNA with Rygel, the guys at Intel OTC are fixing the Client side of DLNA with something called dLeyna, a nice set of APIs to access and maipulate UPnP-AV and DLNA servers / renderers (such as Rygel, of course), so you can easily add DLNA support to your applications, including the obvious server browsing and render remote control, but also the more non-obvious like media pushing, synchronization, server-side playlists. They already prepared a cool set of demos (for example a Firefox extension to send images from your browser to your TV).
So why is this better than using GUPnP for this? Let me show you some examples.

Controlling a renderer

Not much code to see here, you get the usual suspects of player control functions such as start, stop, etc. as well as methods to query device’s capabilities as there are a lot of optional things on UPnP devices.


Well, say you want to upload a file to a server. The code how to do that in GUPnP is  available in gupnp-tools and it’s not exactly pretty. With dLeyna, on the other hand, it’s a fewliner:

#!/usr/bin/env python
import sys
import mediaconsole as mc
u = mc.UPNP()
d = u.server_from_udn(sys.argv[1])
d.upload_to_any(sys.argv[2], sys.argv[3])

In DLNA land, this is called “+UP+”.

Playing a file

Or you want to show some media file you got on your device or app on a DLNA-capable TV? Korva is showing how you can do that with plain GUPnP, again with a lots of lines of code. dLeyna providing a nice and clean solution:

#!/usr/bin/env python
import sys
import rendererconosle as rc
m = rc.Manager()
d = m.renderer_from_udn(sys.argv[1])
uri = d.host_file(sys.argv[2])

And this is called “+PU+” in DLNA land.
Behind the scenes, this is all GUPnP of course. Currently it consists of two DBus services, dleyna-renderer-service and dleyna-server-service, although other IPC mechanisms are on its way. What happens is that that these two services scan the network for available devices and making them available through a set of DBus interfaces, relieving you from the need of searching for devices yourself (and with that providing a device cache, relieving the network from UDP packet bursts), introspecting the devices for supported capabilities and methods and so on.
If you execute the push script from above you get a python wrapper for the com.intel.dLeynaRenderer.Manager DBus interface, which is then locally looking for the DBus path matching the given UPnP UDN and returning a python object implementing the com.intel.dLeynaRenderer.PushHost and com.intel.dLeynaRenderer.RendererDevice interfaces.
Then we temporarily host the file given on the command-line on dLeyna’s internal HTTP server, stopping the currently running playback (Which translates to RenderingControl:Stop SOAP call), send the URI to the server (RenderingControl:SetAVTransportURI) and last but not least start the playback (RenderingControl:Play) which in the end starts the HTTP streaming from dleyna’s internal HTTP server to (Rygel’s) renderer.
And it doesn’t stop at the application level, there’s even integration with HTML5 through cloudeebus and cloud-dLeyna.
As a sidenote: You might ask how that relates to Grilo’s UPnP-AV support or Korva. This is a very valid question. Grilo and Korva are doing very specific tasks while dLeyna aims to be a more complete SDK. It should be quite easy, for example, to port Grilo’s UPnP-AV suppport to dLeyna.

10 thoughts on “DLNA, client side

  1. Hi,
    I’m considering to control Rygel’s dmr from a python script given that both are installed on a Rpi.
    Have you tried to install dLeyna i a Rpi ? There is not package of dleyna for the raspbian, but It should not be complicated either.

  2. Thank a lot !
    I didn’t find that much solutions to control a dmr from the same computer. Rygel does not expose himself as a MPRIS device and there is no IPC (dbus) to communicate with dmr plugin of Rygel, is there ?
    Keep me posted when you have time to backport dleyna, I would be pleased to test packages 😉

  3. Thanks a lot for the packaging !!! It helped me a lot.
    I keep you posted if I find some bug 😉

    1. root@rpi-chroot:/# cat /etc/apt/sources.list.d/rygel.list
      deb http://rygel-project.org/raspbian wheezy/
      deb-src http://rygel-project.org/raspbian wheezy/

      And with that (after apt-get update), I get:

      root@rpi-chroot:/# apt-cache search dleyna
      libdleyna-connector-dbus-1.0-1 - DBus connector module for the dLeyna services
      libdleyna-connector-dbus-1.0-dbg - DBus connector module for the dLeyna services (debug files)
      libdleyna-core-1.0-1 - Utility functions for higher level dLeyna components
      libdleyna-core-1.0-dbg - Utility functions for higher level dLeyna components (debug files)
      libdleyna-core-1.0-dev - Utility functions for higher level dLeyna components (development files)
      dleyna-renderer - DBus service to interact with DLNA Digital Media Renderers
      dleyna-renderer-dbg - DBus service to interact with DLNA Digital Media Renderers (debug files)
      dleyna-server - DBus service to interact with DLNA Digital Media Servers
      dleyna-server-dbg - DBus service to interact with DLNA Digital Media Servers (debug files)

Comments are closed.