Somewhat fancy voice command recognition software
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

mpris.py 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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
  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. # This error is raised if the media player was closed after we got
  72. # the proxy but before we called next.
  73. # FIXME raise a different exception to tell Kaylee that we failed
  74. pass
  75. class MPRISPauseHandler(MPRISHandler):
  76. """Handler for the MPRIS Pause method"""
  77. def __call__(self, tts):
  78. """Call the MPRIS Pause method"""
  79. try:
  80. self.proxy.Pause()
  81. except GLib.Error:
  82. # This error is raised if the media player was closed after we got
  83. # the proxy but before we called pause.
  84. # FIXME raise a different exception to tell Kaylee that we failed
  85. pass
  86. class MPRISPlayHandler(MPRISHandler):
  87. """Handler for the MPRIS Play method"""
  88. def __call__(self, tts):
  89. """Call the MPRIS Play method"""
  90. try:
  91. self.proxy.Play()
  92. except GLib.Error:
  93. # This error is raised if the media player was closed after we got
  94. # the proxy but before we called play.
  95. # FIXME raise a different exception to tell Kaylee that we failed
  96. pass
  97. class MPRISPreviousHandler(MPRISHandler):
  98. """Handler for the MPRIS Previous method"""
  99. def __call__(self, tts):
  100. """Call the MPRIS Previous method"""
  101. try:
  102. self.proxy.Previous()
  103. except GLib.Error:
  104. # This error is raised if the media player was closed after we got
  105. # the proxy but before we called previous.
  106. # FIXME raise a different exception to tell Kaylee that we failed
  107. pass