]> kaliko git repositories - mpd-goodies.git/blob - bin/nalbum
Massive refactoring
[mpd-goodies.git] / bin / nalbum
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3
4 # Copyright (c) 2009,2010,2012,2019 kaliko <kaliko@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 import sys
21 import argparse
22
23 from time import sleep
24 from os.path import basename
25
26 import musicpd
27
28 VERSION = '0.2'
29
30
31 class Nalbum(musicpd.MPDClient):
32     script_info = dict({
33         'prog': basename(__file__),
34         'description': 'Jump to next album in playlist.',
35         'epilog': 'Set MPD host/port in env. var'
36     })
37
38     def __init__(self):
39         musicpd.MPDClient.__init__(self)
40         self.args = self._get_args()
41         self._run()
42
43     def _get_args(self):
44         parser = argparse.ArgumentParser(**self.__class__.script_info)
45         parser.add_argument('--version', action='version',
46                             version='v%s' % VERSION)
47         parser.add_argument('-c', '--cross-fade', type=int, dest='time',
48                             help='fade out/fade in over t seconds.',)
49         args = parser.parse_args()
50         return args
51
52     def _setvol(self, vol):
53         """
54         Sometimes while fading in on next album, MPD fails.
55         Log shows :
56         "exception: Failed to set mixer for 'My Pulse Output': disconnected"
57         python-musicpd then raises "[52@0] {setvol} problems setting volume"
58         """
59         try:
60             self.setvol(int(vol))
61         except musicpd.CommandError as err:
62             print('MPD raised "%s"' % err)
63             print('Try to set the output with \'always_on    "yes"\'')
64             if 'problems setting volume' in str(err):
65                 sleep(.1)
66                 self._setvol(int(vol))
67
68     def _fade(self, mpd_vol, io='out'):
69         """
70         end_volum => End volume value
71         start_vol   => Start volume value
72         """
73         if io == 'out':
74             end_volum = mpd_vol // 10
75             start_vol = mpd_vol
76         if io == 'in':
77             end_volum = mpd_vol
78             start_vol = mpd_vol // 10
79         # print(start_vol, end_volum)
80         span = float(end_volum - start_vol)
81         step = span / float(10*self.args.time)
82         if step == 0:
83             return True
84         while True:
85             start_vol += step
86             self._setvol(int(start_vol))
87             if abs(start_vol - end_volum) < 1.1*abs(step):
88                 self._setvol(end_volum)
89                 return True
90             sleep(0.1)
91
92     def _get_next(self):
93         """Retrieve playlist from current song to the end."""
94         if 'song' not in self.status():
95             print('No current song set in MPD!')
96             self.disconnect()
97             sys.exit(0)
98         current_album = str(self.currentsong().get('album', 'TAG MISSING'))
99         current_song_pos = int(self.currentsong().get('pos'))
100         print('Current album: "%s"' % current_album)
101         next_album_pos = current_song_pos
102         album = current_album
103         while album == current_album:
104             next_album_pos += 1
105             pl_length = int(self.status().get('playlistlength')) - 1
106             if pl_length < next_album_pos:
107                 print('Next album not found in the playlitst!')
108                 self.disconnect()
109                 sys.exit(0)
110             album = self.playlistinfo(next_album_pos)[
111                 0].get('album', 'TAG MISSING')
112         print('Next album appears to be: "%s"' % album)
113         return next_album_pos
114
115     def _run(self):
116         self.connect()
117         nalbum = self._get_next()
118         init_vol = int(self.status().get('volume', 0))
119         if self.args.time:
120             print('Cross fading next album')
121             self._fade(init_vol)
122         self.play(nalbum)
123         if self.args.time:
124             self._fade(init_vol, io='in')
125         self.disconnect()
126         sys.exit(0)
127
128
129 # Script starts here
130 if __name__ == '__main__':
131     try:
132         Nalbum()
133     except KeyboardInterrupt:
134         sys.stdout.write('exit')
135
136 # VIM MODLINE
137 # vim: ai ts=4 sw=4 sts=4 expandtab