Hey Rhythmbox, go pause yourself!

brad's picture

A while back NBM wrote a script to pause Amarokk when his screensaver turned on. Since I get competitive I felt I could do it better, and do it for the media player that I love, Rhythmbox. If you are wondering what purpose this really serves, imagine you are away from your desk for a long time, you want to make sure the music is the same when you come back, and you don't want to bug any co-workers. It also serves the purpose of deepening my understanding of python, and scratches the itch of customising desktops (and feeling better than windows people). So...

I started out writing a daemonisd script like the one nbm built, which listens on the d-bus (the Linux/Freedesktop inter-process messaging/control bus), and connects to Rhythmbox on the same bus to get in control. Taking his script and changing the message passing to point to RB instead of Amarokk was trivial (but a mission due to lack of documentation) and I threw in some improvements.

Then I got itchy and figured I could write a plugin for RB and push control of the functionality to RB (where it belongs), and drop the need for a daemon script. So I opened up the artdisplay plugin for Rhythmbox (since it is a python based plugin) to get an idea of what is involved. After browsing through the plugin, and reading the Rhythmbox plugins writing guide I rolled my own.

I call my plugin dbusevents because while it pauses when the screen saver is on it could be extended to support multiple events and actions (maybe you want the volume turned up louder when you first plug in your mouse so you can party). So, a Rhythmbox plugin inhabits a directory and has atleast two parts: A descriptor file, and the plugin.

You can download the whole thing: dbusevents.tar.gz. To use it drop the extracted directory in /usr/lib/rhythmbox/plugins/

My descriptor file looks like:

[RB Plugin]
Loader=python
Module=dbusevents
IAge=1
Name=DBUS Events
Name[en_GB]=DBUS Events
Description=Connects Rhythmbox actions to DBUS events (for e.g. pausing when the screensaver is on)
Description[en_GB]=Connects Rhythmbox actions to DBUS events (for e.g. pausing when the screensaver is on)
Authors=Bradley Whittington 
Copyright=Copyright © 2007 Bradley Whittington
Website=http://www.rhythmbox.org

Pretty straightforward stuff eh? The net result is:
rhythmbox-dbus-config.png

The meat of the plugin is contained in dbusevents/__init__.py which implements a Rhythmbox plugin, which means it inherits from rb.plugin (import rb), implements at least __init__, activate, and deactivate.

So:

class DbusEventsPlugin (rb.Plugin):
#Initialisation 
        def __init__ (self):
                rb.Plugin.__init__ (self)

        def activate (self, shell):
                self.shell = shell
                self.rb = shell.get_player ()
                self.session_bus = dbus.SessionBus()
                self.load_events()
                self.connect_events()

        def deactivate (self, shell):
                self.disconnect_events()
                self.save_events()
                self.shell = None
                self.rb = None
                self.session_bus = None

When my plugin is told to activate it assigns self.rb to an instance of the Rhythmbox shell, makes a connection to the D-BUS session bus, and assigns the instance to self.session_bus, then it calls load_events (which could load events and actions from a config file), and finally connect_events which tells the session_bus which functions to call when certain events happen. The deactivate function does everything, in reverse ;). Ultimately I would like to make a configuration dialogue which allows you to have your custom event-action set up, but I havent found anything more beyond pausing when the screensaver is on.

The magic in connect_events and disconnect_events is pretty basic, at the moment it walks a dictionary with relevant information:

        events = {
                        'Screensaver Play/Pause':{
                                '__doc__':'Pauses Rhythmbox when the Screensaver is running',
                                'handler':'playPause',
                                'signal':('SessionIdleChanged','org.gnome.ScreenSaver'),
                                'enabled':True,
                        }
                }

The functions use self.session_bus.add_signal_receiver and self.session_bus.remove_signal_receiver to attach events to actions. I have only defined a PlayPause function at the moment:

        def playPause(self,state):
                if not state:
                        if self.wasplaying:
                                self.rb.play()
                else:
                        self.wasplaying = self.rb.get_playing()
                        self.rb.pause()

Which checks if it is playing when the screensaver is turned on, and pauses if it is, and unpauses when the screensaver turns off, if it was paused when the screensaver went on.

I would appreciate feedback, so drop me a comment if you have any!

AttachmentSize
dbusevents.tar.gz1.42 KB

Trackback URL for this post:

http://whijo.net/trackback/109

Works great! Thanks for the handy script.

GREEEAAAATTT

Any idea how I could feed 'current track' into a screensaver? i.e gltext? Sounds easy but haven't been able to find anything.

Thanks for this awesome plugin. Works great on Ubuntu 8.04. Coming from Windows and foobar2000 I was looking for a foo_lock replacement. This fills that gap :) Jory

Post new comment

The content of this field is kept private and will not be shown publicly.
Captcha
This question is used to make sure you are a human visitor and to prevent spam submissions.
Syndicate content

The Whijos

site tools

User login

Log in using OpenID

Syndicate

Syndicate content

@love() python

Afrigator

Recent comments

About this website

Whijo.net is the online internets of Bradley Whittington, Amanda Joseph, and our son Finley James Whittington. "Whijo" is 29% Whittington, 33% Joseph, and 37% Internet. Quite Web 2.0 of us.