I’ve put together a (working) quick and dirty script to wrap MPD in a UPnP Media Renderer. This is far from a complete solution, but it allows playing/pausing via UPnP Control Points. (Python-GUPnP CP works just dandy for it!)
from gi.repository import GUPnP, GObject, GLib
import mpd
CON_ID = None
MPDCLIENT = None
GObject.threads_init()
def setup_server():
ctx = GUPnP.Context(interface="eth0")
ctx.host_path("device.xml", "/device.xml")
ctx.host_path("AVTransport2.xml", "/AVTransport2.xml")
desc = "device.xml"
desc_loc = "./"
rd = GUPnP.RootDevice.new(ctx, desc, desc_loc)
rd.set_available(True)
return rd
def setup_mpd():
global CON_ID, MPDCLIENT
HOST = 'localhost'
PORT = '6600'
CON_ID = {'host':HOST, 'port':PORT}
MPDCLIENT = mpd.MPDClient()
def on_play_action(service, action):
print "Play"
MPDCLIENT.connect(**CON_ID)
MPDCLIENT.play()
MPDCLIENT.disconnect()
def on_pause_action(service, action):
print "Pause"
MPDCLIENT.connect(**CON_ID)
MPDCLIENT.pause()
MPDCLIENT.disconnect()
rd = setup_server()
print "UPnP MediaRenderer Service Exported"
setup_mpd()
print "MPD Client Setup"
service = rd.get_service("urn:schemas-upnp-org:service:AVTransport:1")
service.connect("action-invoked::Play", on_play_action)
service.connect("action-invoked::Pause", on_pause_action)
print "Awaiting commands..."
GObject.MainLoop().run()
Update: This is an updated version of the script that supports more commands and properly ends each UPnP action. Unfortunately it doesn’t entirely work because of either 1) A bug in g-i or 2) a problem with the gupnp api that will require a break to fix. Spent a lot of time today to understand the problem, hopefully we’ll have either a gupnp or a g-i fix in a few days.
Update 2: Now available on github. Zhaan (formerly known as “GUPnP-Python UPnP Control Point” has also been pushed)