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"""
49 class Sleep(musicpd.MPDClient):
52 'prog': basename(__file__),
55 'formatter_class': argparse.RawDescriptionHelpFormatter,
60 musicpd.MPDClient.__init__(self)
66 def _test_volume_access(self):
67 status = self.status()
68 if 'volume' not in status:
69 print('Mixer not available!')
70 print('Try to set the always_on audio_output option on.')
75 parser = argparse.ArgumentParser(**self.__class__.script_info)
76 parser.add_argument('--version', action='version',
77 version='v%s' % VERSION)
78 group = parser.add_mutually_exclusive_group()
79 group.add_argument('-m', '--minutes', type=int,
80 help='duration to fade in/out over')
81 group.add_argument('-s', '--seconds', type=int,
82 help='duration to fade in/out over')
83 parser.add_argument('volume', type=int, nargs='?',
84 help='final volume level')
85 args = parser.parse_args()
87 self.tempo = args.minutes*60
89 self.tempo = args.seconds
91 self.volum = args.volume
96 self.mpd_state = str(self.status().get('state'))
97 if self.mpd_state == 'play':
98 self.mpd_vol = int(self.status().get('volume'))
100 self.volum = self.mpd_vol // 10
101 if self.volum >= self.mpd_vol:
102 print('Error: specified min volume (%d%%) >= to current volume (%d%%)' % (
103 self.volum, self.mpd_vol))
105 print('fading down from %d%% to %d%% over %ss' % (self.mpd_vol, self.volum, self.tempo), file=sys.stdout)
106 if self.fade(self.mpd_vol, self.volum):
108 elif self.mpd_state in ['stop', 'pause']:
109 self._test_volume_access()
112 print('fading up from 0%% to %d%% over %ss' % (self.volum, self.tempo), file=sys.stdout)
116 self.fade(self.mpd_vol, self.volum)
118 def fade(self, mpd_vol, target):
120 # TODO: handle possible lost connections
122 span = target - mpd_vol
123 step = span / (resolution*self.tempo)
129 self.setvol(round(vol))
130 # monitor external volume change
131 # print(vol, round(vol), self.status().get('volume'))
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