]> kaliko git repositories - mpd-goodies.git/blob - mfade
* mfade: no longer stops playing when aborting after external volume changes
[mpd-goodies.git] / mfade
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 # Copyright (c) 2009 Efrim <efrim@azylum.org> {{{
5 #
6 #   This program is free software: you can redistribute it and/or modify
7 #   it under the terms of the GNU General Public License as published by
8 #   the Free Software Foundation, either version 3 of the License, or
9 #   (at your option) any later version.
10 #
11 #   This program is distributed in the hope that it will be useful,
12 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #   GNU General Public License for more details.
15 #
16 #   You should have received a copy of the GNU General Public License
17 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 #  }}}
20
21 """
22 DOC:
23     heavily borrowed from perl script mpdtoys and converted to python.
24     mpdtoys © 2007 Joey Hess <joey@kitenet.net>
25     http://kitenet.net/~joey/code/mpdtoys
26 """
27
28 import sys
29
30 from time import sleep
31
32 from lib.mpdutils import mconnect
33
34 USAGE = """Usage:
35
36 mfade [time [min|max]]
37
38    * time in seconds
39    * min|max in percentag
40
41 when MPD is:
42 - not palying: fade in from 0% to max over time
43                default 10 minutes / 50%
44 -    playing:  fade out from current volume to min over time
45                default 10 minutes / 1/10 of current vol
46
47 Manual or any external volume change will abort the script.
48 """
49
50
51 class Sleep(object):
52     """
53     """
54
55     def __init__(self):
56         """"""
57         self.tempo = int(10)
58         self.volum = None
59         self._consume_sopt()
60         self.cli = mconnect()
61         self._run()
62         self.cli.disconnect()
63
64     def _consume_sopt(self):
65         """"""
66         # TODO: use optparse?
67         options = sys.argv
68         if len(sys.argv) > 1 and sys.argv[1] in ['-h', '--help']:
69             sys.stderr.write(USAGE)
70             sys.exit(1)
71         try:
72             self.tempo = int(options.pop(1))
73             self.volum = int(options.pop(1))
74         except IndexError:
75             pass
76         except ValueError, err:
77             sys.stderr.write('Error: wrong option passed: %s' % err)
78             sys.stdout.write(USAGE)
79             sys.exit(1)
80
81     def _run(self):
82         """"""
83         self.mpd_state = str(self.cli.status().get('state'))
84         self.mpd_vol = int(self.cli.status().get('volume'))
85         if self.mpd_state == 'play':
86             if not self.volum:
87                 self.volum = self.mpd_vol / 10
88             if self.volum > self.mpd_vol:
89                 sys.stderr.write('Error: specified min volume (%d%%) > to current volume (%d%%)' % (self.volum, self.mpd_vol))
90                 sys.exit(1)
91             print >> sys.stdout, 'fading down from %d%% to %d%% over %smin' % (self.mpd_vol, self.volum, self.tempo)
92             if self.fade():
93                 self.cli.stop()
94         if self.mpd_state in ['stop', 'pause']:
95             if not self.volum:
96                 self.volum = int(50)
97             print >> sys.stdout, 'fading up from 0%% to %d%% over %smin' % (self.volum, self.tempo)
98             self.cli.setvol(0)
99             self.mpd_vol = 0
100             self.cli.play()
101             self.fade()
102         sleep(1)
103
104     def fade(self):
105         """"""
106         # TODO: handle possible lost connections
107         span = float(self.volum - self.mpd_vol)
108         step = span / float(60 * self.tempo)
109         vol = self.mpd_vol
110         while 42:
111             if int(vol) != int(self.cli.status().get('volume')):
112                 sys.stderr.write('Warning: external volume change, aborting!\n')
113                 return False
114             vol += step
115             self.cli.setvol(int(vol))
116             if abs(vol - self.volum) < 1:
117                 self.cli.setvol(self.volum)
118                 return True
119             sleep(1)
120
121
122 # Script starts here
123 if __name__ == '__main__':
124     try:
125         Sleep()
126     except KeyboardInterrupt:
127         sys.stdout.write('exit')
128
129 # VIM MODLINE
130 # vim: ai ts=4 sw=4 sts=4 expandtab