2 # -*- coding: utf-8 -*-
4 # Copyright (c) 2009,2010,2012,2019 kaliko <kaliko@azylum.org>
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.
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.
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/>.
22 heavily borrowed from perl script mpdtoys and converted to python.
23 mpdtoys © 2007 Joey Hess <joey@kitenet.net>
24 http://kitenet.net/~joey/code/mpdtoys
30 from time import sleep
31 from os.path import basename
37 DESC = """Fade in/out to <final volume level> over <time>.
38 Defaults are from 0% to 50% when paused or stopped
39 and from current volume to 10th of it if playing,
40 both over 10 minutes."""
41 DESC = """Fade in/out to <final volume level> over <time>.
42 Defaults are from 0% to 50% when paused or stopped and from current volume to 10th of it if playing, both over 10 minutes."""
43 EPILOG = """You might need to set your audio_output with "always_on yes" for
44 this command to work properly.
46 Set MPD host/port in env. var"""
48 class Sleep(musicpd.MPDClient):
51 'prog': basename(__file__),
54 'formatter_class': argparse.RawDescriptionHelpFormatter,
59 musicpd.MPDClient.__init__(self)
65 def _test_volume_access(self):
66 status = self.status()
67 if 'volume' not in status:
68 print('Mixer not available!')
69 print('Try to set the always_on audio_output option on.')
74 parser = argparse.ArgumentParser(**self.__class__.script_info)
75 parser.add_argument('--version', action='version',
76 version='v%s' % VERSION)
77 group = parser.add_mutually_exclusive_group()
78 group.add_argument('-m', '--minutes', type=int,
79 help='duration to fade in/out over')
80 group.add_argument('-s', '--seconds', type=int,
81 help='duration to fade in/out over')
82 parser.add_argument('volume', type=int, nargs='?',
83 help='final volume level')
84 args = parser.parse_args()
86 self.tempo = args.minutes*60
88 self.tempo = args.seconds
90 self.volum = args.volume
95 self.mpd_state = str(self.status().get('state'))
96 if self.mpd_state == 'play':
97 self.mpd_vol = int(self.status().get('volume'))
99 self.volum = self.mpd_vol // 10
100 if self.volum > self.mpd_vol:
101 print('Error: specified min volume (%d%%) > to current volume (%d%%)' % (
102 self.volum, self.mpd_vol))
104 print('fading down from %d%% to %d%% over %ss' % (self.mpd_vol, self.volum, self.tempo), file=sys.stdout)
105 if self.fade(self.mpd_vol, self.volum):
107 elif self.mpd_state in ['stop', 'pause']:
108 self._test_volume_access()
111 print('fading up from 0%% to %d%% over %ss' % (self.volum, self.tempo), file=sys.stdout)
115 self.fade(self.mpd_vol, self.volum)
117 def fade(self, mpd_vol, target):
119 # TODO: handle possible lost connections
120 span = target - mpd_vol
121 step = span / (10*self.tempo)
126 if int(vol) != int(self.status().get('volume')):
128 'Warning: external volume change, aborting!\n')
131 self.setvol(int(vol))
132 if abs(vol - target) < 1.1*abs(step):
139 if __name__ == '__main__':
142 except KeyboardInterrupt:
143 sys.stdout.write('exit')
146 # vim: ai ts=4 sw=4 sts=4 expandtab