--- /dev/null
+#!/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/>.
+#
+
+import sys
+import argparse
+
+from time import sleep
+from os.path import basename
+
+import musicpd
+
+VERSION = '0.2'
+
+
+class Nalbum(musicpd.MPDClient):
+ script_info = dict({
+ 'prog': basename(__file__),
+ 'description': 'Jump to next album in playlist.',
+ 'epilog': 'Set MPD host/port in env. var'
+ })
+
+ def __init__(self):
+ musicpd.MPDClient.__init__(self)
+ self.args = self._get_args()
+ self._run()
+
+ def _get_args(self):
+ parser = argparse.ArgumentParser(**self.__class__.script_info)
+ parser.add_argument('--version', action='version',
+ version='v%s' % VERSION)
+ parser.add_argument('-c', '--cross-fade', type=int, dest='time',
+ help='fade out/fade in over t seconds.',)
+ args = parser.parse_args()
+ return args
+
+ def _setvol(self, vol):
+ """
+ Sometimes while fading in on next album, MPD fails.
+ Log shows :
+ "exception: Failed to set mixer for 'My Pulse Output': disconnected"
+ python-musicpd then raises "[52@0] {setvol} problems setting volume"
+ """
+ try:
+ self.setvol(int(vol))
+ except musicpd.CommandError as err:
+ print('MPD raised "%s"' % err)
+ print('Try to set the output with \'always_on "yes"\'')
+ if 'problems setting volume' in str(err):
+ sleep(.1)
+ self._setvol(int(vol))
+
+ def _fade(self, mpd_vol, io='out'):
+ """
+ end_volum => End volume value
+ start_vol => Start volume value
+ """
+ if io == 'out':
+ end_volum = mpd_vol // 10
+ start_vol = mpd_vol
+ if io == 'in':
+ end_volum = mpd_vol
+ start_vol = mpd_vol // 10
+ # print(start_vol, end_volum)
+ span = float(end_volum - start_vol)
+ step = span / float(10*self.args.time)
+ if step == 0:
+ return True
+ while True:
+ start_vol += step
+ self._setvol(int(start_vol))
+ if abs(start_vol - end_volum) < 1.1*abs(step):
+ self._setvol(end_volum)
+ return True
+ sleep(0.1)
+
+ def _get_next(self):
+ """Retrieve playlist from current song to the end."""
+ if 'song' not in self.status():
+ print('No current song set in MPD!')
+ self.disconnect()
+ sys.exit(0)
+ current_album = str(self.currentsong().get('album', 'TAG MISSING'))
+ current_song_pos = int(self.currentsong().get('pos'))
+ print('Current album: "%s"' % current_album)
+ next_album_pos = current_song_pos
+ album = current_album
+ while album == current_album:
+ next_album_pos += 1
+ pl_length = int(self.status().get('playlistlength')) - 1
+ if pl_length < next_album_pos:
+ print('Next album not found in the playlitst!')
+ self.disconnect()
+ sys.exit(0)
+ album = self.playlistinfo(next_album_pos)[
+ 0].get('album', 'TAG MISSING')
+ print('Next album appears to be: "%s"' % album)
+ return next_album_pos
+
+ def _run(self):
+ self.connect()
+ nalbum = self._get_next()
+ init_vol = int(self.status().get('volume', 0))
+ if self.args.time:
+ print('Cross fading next album')
+ self._fade(init_vol)
+ self.play(nalbum)
+ if self.args.time:
+ self._fade(init_vol, io='in')
+ self.disconnect()
+ sys.exit(0)
+
+
+# Script starts here
+if __name__ == '__main__':
+ try:
+ Nalbum()
+ except KeyboardInterrupt:
+ sys.stdout.write('exit')
+
+# VIM MODLINE
+# vim: ai ts=4 sw=4 sts=4 expandtab