Browse Source

Added MPRIS plugin

Now you can control media players supporting MPRIS using Kaylee.  Just
load the plugin and commands like "play the music", "pause the video",
"previous song", and "next video" magically work.
Clara Hobbs 7 years ago
parent
commit
327ec9d778
2 changed files with 96 additions and 0 deletions
  1. 5
    0
      README.rst
  2. 91
    0
      kayleevc/plugins/mpris.py

+ 5
- 0
README.rst View File

@@ -17,6 +17,11 @@ Requirements
17 17
 5. python-gobject (required for GStreamer and the GTK-based UI)
18 18
 6. python-requests (required for automatic language updating)
19 19
 
20
+Optional
21
+~~~~~~~~
22
+
23
+1. python-pydbus (required for MPRIS plugin)
24
+
20 25
 **Note:** it may also be required to install
21 26
 ``pocketsphinx-hmm-en-hub4wsj``
22 27
 

+ 91
- 0
kayleevc/plugins/mpris.py View File

@@ -0,0 +1,91 @@
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
+
6
+"""MPRIS media player control plugin
7
+
8
+This plugin allows control of a media player supporting the Media
9
+Player Remote Interfacing Specification (MPRIS) D-Bus interface.  To
10
+use this plugin, you must first install `pydbus
11
+<https://github.com/LEW21/pydbus>`__ for Python 3.  This plugin takes
12
+no configuration, so load it as follows::
13
+
14
+    ".mpris": {}
15
+
16
+Note: if your microphone can hear the audio produced by your speakers,
17
+it is recommended to load PulseAudio's module-echo-cancel when using
18
+this plugin.  Recognition while music is playing may still be mediocre,
19
+but without module-echo-cancel it has almost no chance of working.
20
+"""
21
+
22
+from pydbus import SessionBus
23
+
24
+from .pluginbase import PluginBase
25
+
26
+
27
+class Plugin(PluginBase):
28
+    """Main class for the MPRIS plugin"""
29
+
30
+    def __init__(self, config, name):
31
+        """Initialize the MPRIS plugin"""
32
+        super().__init__(config, name)
33
+
34
+        # Get the D-Bus proxy object
35
+        self._bus = SessionBus()
36
+        self._dbus_proxy = self._bus.get('.DBus')
37
+
38
+        self.commands = {
39
+            'next song': self._next,
40
+            'next video': self._next,
41
+            'pause the music': self._pause,
42
+            'pause the video': self._pause,
43
+            'play the music': self._play,
44
+            'play the video': self._play,
45
+            'previous song': self._previous,
46
+            'previous video': self._previous
47
+        }
48
+
49
+        self.corpus_strings.update(self.commands)
50
+
51
+    def _mpris_proxy(self):
52
+        """Get a proxy for the first MPRIS media player, or None"""
53
+        try:
54
+            # Get the bus name of the first MPRIS media player
55
+            bus_name = [name for name in self._dbus_proxy.ListNames()
56
+                        if name.startswith('org.mpris.MediaPlayer2')][0]
57
+            # Get the proxy
58
+            return self._bus.get(bus_name, '/org/mpris/MediaPlayer2')
59
+        except IndexError:
60
+            print('No media player found')
61
+            return None
62
+
63
+    def _next(self):
64
+        p = self._mpris_proxy()
65
+        if p is not None:
66
+            p.Next()
67
+
68
+    def _pause(self):
69
+        p = self._mpris_proxy()
70
+        if p is not None:
71
+            p.Pause()
72
+
73
+    def _play(self):
74
+        p = self._mpris_proxy()
75
+        if p is not None:
76
+            p.Play()
77
+
78
+    def _previous(self):
79
+        p = self._mpris_proxy()
80
+        if p is not None:
81
+            p.Previous()
82
+
83
+    def recognizer_finished(self, recognizer, text):
84
+        """Print and speak the phrase when it is heard"""
85
+        # Is there a matching command?
86
+        if text in self.corpus_strings:
87
+            self.emit('processed', text)
88
+            self.commands[text]()
89
+            return True
90
+        else:
91
+            return False

Loading…
Cancel
Save