Somewhat fancy voice command recognition software
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mpris.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # This is part of Kaylee
  2. # -- this code is licensed GPLv3
  3. # Copyright 2015-2017 Clayton G. Hobbs
  4. # Portions Copyright 2013 Jezra
  5. """MPRIS media player control plugin
  6. This plugin allows control of a media player supporting the Media
  7. Player Remote Interfacing Specification (MPRIS) D-Bus interface. To
  8. use this plugin, you must first install `pydbus
  9. <https://github.com/LEW21/pydbus>`__ for Python 3. This plugin takes
  10. no configuration, so load it as follows::
  11. ".mpris": {}
  12. Note: if your microphone can hear the audio produced by your speakers,
  13. it is recommended to load PulseAudio's module-echo-cancel when using
  14. this plugin. Recognition while music is playing may still be mediocre,
  15. but without module-echo-cancel it has almost no chance of working.
  16. """
  17. from gi.repository import GLib
  18. from pydbus import SessionBus
  19. from . import PluginBase, Handler, HandlerFailure
  20. class Plugin(PluginBase):
  21. """Main class for the MPRIS plugin"""
  22. def __init__(self, config, name):
  23. """Initialize the MPRIS plugin"""
  24. super().__init__(config, name)
  25. # Get the D-Bus proxy object
  26. self._bus = SessionBus()
  27. self._dbus_proxy = self._bus.get('.DBus')
  28. self.commands = {
  29. 'next song': MPRISNextHandler,
  30. 'next video': MPRISNextHandler,
  31. 'pause music': MPRISPauseHandler,
  32. 'pause video': MPRISPauseHandler,
  33. 'play music': MPRISPlayHandler,
  34. 'play video': MPRISPlayHandler,
  35. 'previous song': MPRISPreviousHandler,
  36. 'previous video': MPRISPreviousHandler
  37. }
  38. self.corpus_strings.update(self.commands)
  39. def _mpris_proxy(self):
  40. """Get a proxy for the first MPRIS media player, or None"""
  41. try:
  42. # Get the bus name of the first MPRIS media player
  43. bus_name = [name for name in self._dbus_proxy.ListNames()
  44. if name.startswith('org.mpris.MediaPlayer2')][0]
  45. # Get the proxy
  46. return self._bus.get(bus_name, '/org/mpris/MediaPlayer2')
  47. except IndexError:
  48. return None
  49. def get_handler(self, text):
  50. """Return a handler if a recognized command is heard"""
  51. if text not in self.corpus_strings:
  52. return None
  53. p = self._mpris_proxy()
  54. if p is None:
  55. return None
  56. # Make a handler for the command we heard
  57. return self.commands[text](1, p)
  58. class MPRISHandler(Handler):
  59. """Base class for MPRIS plugin handlers"""
  60. def __init__(self, confidence, proxy):
  61. """Store the MPRIS proxy object"""
  62. super().__init__(confidence)
  63. self.proxy = proxy
  64. class MPRISNextHandler(MPRISHandler):
  65. """Handler for the MPRIS Next method"""
  66. def __call__(self, tts):
  67. """Call the MPRIS Next method"""
  68. try:
  69. self.proxy.Next()
  70. except GLib.Error:
  71. raise HandlerFailure()
  72. class MPRISPauseHandler(MPRISHandler):
  73. """Handler for the MPRIS Pause method"""
  74. def __call__(self, tts):
  75. """Call the MPRIS Pause method"""
  76. try:
  77. self.proxy.Pause()
  78. except GLib.Error:
  79. raise HandlerFailure()
  80. class MPRISPlayHandler(MPRISHandler):
  81. """Handler for the MPRIS Play method"""
  82. def __call__(self, tts):
  83. """Call the MPRIS Play method"""
  84. try:
  85. self.proxy.Play()
  86. except GLib.Error:
  87. raise HandlerFailure()
  88. class MPRISPreviousHandler(MPRISHandler):
  89. """Handler for the MPRIS Previous method"""
  90. def __call__(self, tts):
  91. """Call the MPRIS Previous method"""
  92. try:
  93. self.proxy.Previous()
  94. except GLib.Error:
  95. raise HandlerFailure()