156 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/python
 | |
| 
 | |
| from __future__ import print_function
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import dbus
 | |
| import dbus.service
 | |
| import dbus.mainloop.glib
 | |
| try:
 | |
|   from gi.repository import GObject
 | |
| except ImportError:
 | |
|   import gobject as GObject
 | |
| import bluezutils
 | |
| 
 | |
| class Player(dbus.service.Object):
 | |
| 	properties = None
 | |
| 	metadata = None
 | |
| 
 | |
| 	def set_object(self, obj = None):
 | |
| 		if obj != None:
 | |
| 			bus = dbus.SystemBus()
 | |
| 			mp = dbus.Interface(bus.get_object("org.bluez", obj),
 | |
| 						"org.bluez.MediaPlayer1")
 | |
| 			prop = dbus.Interface(bus.get_object("org.bluez", obj),
 | |
| 						"org.freedesktop.DBus.Properties")
 | |
| 
 | |
| 			self.properties = prop.GetAll("org.bluez.MediaPlayer1")
 | |
| 
 | |
| 			bus.add_signal_receiver(self.properties_changed,
 | |
| 				path = obj,
 | |
| 				dbus_interface = "org.freedesktop.DBus.Properties",
 | |
| 				signal_name = "PropertiesChanged")
 | |
| 		else:
 | |
| 			track = dbus.Dictionary({
 | |
| 					"xesam:title" : "Title",
 | |
| 					"xesam:artist" : "Artist",
 | |
| 					"xesam:album" : "Album",
 | |
| 					"xesam:genre" : "Genre",
 | |
| 					"xesam:trackNumber" : dbus.Int32(1),
 | |
| 					"mpris:length" : dbus.Int64(10000) },
 | |
| 					signature="sv")
 | |
| 
 | |
| 			self.properties = dbus.Dictionary({
 | |
| 					"PlaybackStatus" : "playing",
 | |
| 					"LoopStatus" : "None",
 | |
| 					"Rate" : dbus.Double(1.0),
 | |
| 					"Shuffle" : dbus.Boolean(False),
 | |
| 					"Metadata" : track,
 | |
| 					"Volume" : dbus.Double(1.0),
 | |
| 					"Position" : dbus.UInt32(0),
 | |
| 					"MinimumRate" : dbus.Double(1.0),
 | |
| 					"MaximumRate" : dbus.Double(1.0),
 | |
| 					"CanGoNext" : dbus.Boolean(False),
 | |
| 					"CanGoPrevious" : dbus.Boolean(False),
 | |
| 					"CanPlay" : dbus.Boolean(False),
 | |
| 					"CanSeek" : dbus.Boolean(False),
 | |
| 					"CanControl" : dbus.Boolean(False),
 | |
| 					},
 | |
| 					signature="sv")
 | |
| 
 | |
| 			handler = InputHandler(self)
 | |
| 			GObject.io_add_watch(sys.stdin, GObject.IO_IN,
 | |
| 							handler.handle)
 | |
| 
 | |
| 	@dbus.service.method("org.freedesktop.DBus.Properties",
 | |
| 					in_signature="ssv", out_signature="")
 | |
| 	def Set(self, interface, key, value):
 | |
| 		print("Set (%s, %s)" % (key, value), file=sys.stderr)
 | |
| 		return
 | |
| 
 | |
| 	@dbus.service.signal("org.freedesktop.DBus.Properties",
 | |
| 							signature="sa{sv}as")
 | |
| 	def PropertiesChanged(self, interface, properties,
 | |
| 						invalidated = dbus.Array()):
 | |
| 		"""PropertiesChanged(interface, properties, invalidated)
 | |
| 
 | |
| 		Send a PropertiesChanged signal. 'properties' is a dictionary
 | |
| 		containing string parameters as specified in doc/media-api.txt.
 | |
| 		"""
 | |
| 		pass
 | |
| 
 | |
| 	def help(self, func):
 | |
| 		help(self.__class__.__dict__[func])
 | |
| 
 | |
| 	def properties_changed(self, interface, properties, invalidated):
 | |
| 		print("properties_changed(%s, %s)" % (properties, invalidated))
 | |
| 
 | |
| 		self.PropertiesChanged(interface, properties, invalidated)
 | |
| 
 | |
| class InputHandler:
 | |
| 	commands = { 'PropertiesChanged': '(interface, properties)',
 | |
| 			'help': '(cmd)' }
 | |
| 	def __init__(self, player):
 | |
| 		self.player = player
 | |
| 		print('\n\nAvailable commands:')
 | |
| 		for cmd in self.commands:
 | |
| 			print('\t', cmd, self.commands[cmd], sep='')
 | |
| 
 | |
| 		print("\nUse python syntax to pass arguments to available methods.\n" \
 | |
|                 "E.g.: PropertiesChanged({'Metadata' : {'Title': 'My title', \
 | |
| 		'Album': 'my album' }})")
 | |
| 		self.prompt()
 | |
| 
 | |
| 	def prompt(self):
 | |
| 		print('\n>>> ', end='')
 | |
| 		sys.stdout.flush()
 | |
| 
 | |
| 	def handle(self, fd, condition):
 | |
| 		s = os.read(fd.fileno(), 1024).strip()
 | |
| 		try:
 | |
| 			cmd = s[:s.find('(')]
 | |
| 			if not cmd in self.commands:
 | |
| 				print("Unknown command ", cmd)
 | |
| 		except ValueError:
 | |
| 			print("Malformed command")
 | |
| 			return True
 | |
| 
 | |
| 		try:
 | |
| 			exec "self.player.%s" % s
 | |
| 		except Exception as e:
 | |
| 			print(e)
 | |
| 			pass
 | |
| 		self.prompt()
 | |
| 		return True
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
| 	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
 | |
| 
 | |
| 	bus = dbus.SystemBus()
 | |
| 
 | |
| 	if len(sys.argv) > 1:
 | |
| 		path = bluezutils.find_adapter(sys.argv[1]).object_path
 | |
| 	else:
 | |
| 		path = bluezutils.find_adapter().object_path
 | |
| 
 | |
| 	media = dbus.Interface(bus.get_object("org.bluez", path),
 | |
| 						"org.bluez.Media1")
 | |
| 
 | |
| 	path = "/test/player"
 | |
| 	player = Player(bus, path)
 | |
| 	mainloop = GObject.MainLoop()
 | |
| 
 | |
| 	if len(sys.argv) > 2:
 | |
| 		player.set_object(sys.argv[2])
 | |
| 	else:
 | |
| 		player.set_object()
 | |
| 
 | |
| 	print('Register media player with:\n\tProperties: %s' \
 | |
| 						% (player.properties))
 | |
| 
 | |
| 	media.RegisterPlayer(dbus.ObjectPath(path), player.properties)
 | |
| 
 | |
| 	mainloop.run()
 | 
