+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2009,2010,2012,2019 kaliko <kaliko@azylum.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+"""
+DOC:
+ heavily borrowed from perl script mpdtoys and converted to python.
+ mpdtoys © 2007 Joey Hess <joey@kitenet.net>
+ http://kitenet.net/~joey/code/mpdtoys
+"""
+
+import argparse
+import sys
+
+from time import sleep
+from os.path import basename
+
+import musicpd
+
+
+VERSION = '0.2'
+DESC = """Fade in/out to <final volume level> over <time>.
+Defaults are from 0% to 50% when paused or stopped
+and from current volume to 10th of it if playing,
+both over 10 minutes."""
+DESC = """Fade in/out to <final volume level> over <time>.
+Defaults are from 0% to 50% when paused or stopped and from current volume to 10th of it if playing, both over 10 minutes."""
+EPILOG = """You might need to set your audio_output with "always_on yes" for
+this command to work properly.
+
+Set MPD host/port in env. var"""
+
+class Sleep(musicpd.MPDClient):
+ """"""
+ script_info = dict({
+ 'prog': basename(__file__),
+ 'description': DESC,
+ 'epilog': EPILOG,
+ 'formatter_class': argparse.RawDescriptionHelpFormatter,
+ })
+
+ def __init__(self):
+ """"""
+ musicpd.MPDClient.__init__(self)
+ self.tempo = 600
+ self.volum = None
+ self._get_args()
+ self._run()
+
+ def _test_volume_access(self):
+ status = self.status()
+ if 'volume' not in status:
+ print('Mixer not available!')
+ print('Try to set the always_on audio_output option on.')
+ sys.exit(1)
+
+ def _get_args(self):
+ """"""
+ parser = argparse.ArgumentParser(**self.__class__.script_info)
+ parser.add_argument('--version', action='version',
+ version='v%s' % VERSION)
+ group = parser.add_mutually_exclusive_group()
+ group.add_argument('-m', '--minutes', type=int,
+ help='duration to fade in/out over')
+ group.add_argument('-s', '--seconds', type=int,
+ help='duration to fade in/out over')
+ parser.add_argument('volume', type=int, nargs='?',
+ help='final volume level')
+ args = parser.parse_args()
+ if args.minutes:
+ self.tempo = args.minutes*60
+ if args.seconds:
+ self.tempo = args.seconds
+ if args.volume:
+ self.volum = args.volume
+
+ def _run(self):
+ """"""
+ self.connect()
+ self.mpd_state = str(self.status().get('state'))
+ if self.mpd_state == 'play':
+ self.mpd_vol = int(self.status().get('volume'))
+ if not self.volum:
+ self.volum = self.mpd_vol // 10
+ if self.volum > self.mpd_vol:
+ print('Error: specified min volume (%d%%) > to current volume (%d%%)' % (
+ self.volum, self.mpd_vol))
+ sys.exit(1)
+ print('fading down from %d%% to %d%% over %ss' % (self.mpd_vol, self.volum, self.tempo), file=sys.stdout)
+ if self.fade(self.mpd_vol, self.volum):
+ self.stop()
+ elif self.mpd_state in ['stop', 'pause']:
+ self._test_volume_access()
+ if not self.volum:
+ self.volum = int(50)
+ print('fading up from 0%% to %d%% over %ss' % (self.volum, self.tempo), file=sys.stdout)
+ self.mpd_vol = 0
+ self.setvol(0)
+ self.play()
+ self.fade(self.mpd_vol, self.volum)
+
+ def fade(self, mpd_vol, target):
+ """"""
+ # TODO: handle possible lost connections
+ span = target - mpd_vol
+ step = span / (10*self.tempo)
+ vol = mpd_vol
+ if step == 0:
+ return True
+ while True:
+ if int(vol) != int(self.status().get('volume')):
+ sys.stderr.write(
+ 'Warning: external volume change, aborting!\n')
+ return False
+ vol += step
+ self.setvol(int(vol))
+ if abs(vol - target) < 1.1*abs(step):
+ self.setvol(target)
+ return True
+ sleep(.1)
+
+
+# Script starts here
+if __name__ == '__main__':
+ try:
+ Sleep()
+ except KeyboardInterrupt:
+ sys.stdout.write('exit')
+
+# VIM MODLINE
+# vim: ai ts=4 sw=4 sts=4 expandtab