-
Notifications
You must be signed in to change notification settings - Fork 7
/
mediaplayer.py
152 lines (141 loc) · 7.5 KB
/
mediaplayer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env python3
#
# mediaplayer.py
#
# Print the metadata of a mediaplayer on conky and control it
# This can also be used as a stand-alone command line application
#
# Author : Amish Naidu
# I release this in the public domain, do with it what you want.
import dbus, argparse, subprocess
#Concat left and right, add alignr if conky_alignr is true and trunc
def fmt_field(left, right, conky_alignr, width):
res = str(left)
res += ':${alignr}' if conky_alignr else ': '
res += str(right)
if width > 0:
return res[:width]
else:
return res
#Return a string containing time in HH:MM:SS format from microseconds
def fmt_time(microseconds):
seconds = microseconds/1000000
return '{:02}:{:02}:{:02}'.format(int(seconds//3600), int((seconds%3600)//60), int(seconds%60))
if __name__ == '__main__':
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter, description='''\
Connect to a media player through dbus to get the metadata or control it.
This can be used to output the current track playing (and it's attributes) on *conky*
%(prog)s can print the metadata of the track currently playing and
make the player perform an action
If the bus was not found, 'Not found' will be printed.
If any property is not found, 'Unknown' will be used/printed.
The 'player' must support MPRIS 2.0''',
epilog='''\
Examples of usage:
To display the Artist, Title and Album with Clementine
$ python3 %(prog)s clementine -atm
To display the Artist, Title, Album and Genre but this time with ${alignr} between the field and it's value
$ python3 %(prog)s vlc -atmg -r
Using the long form arguments with Audacious
$ python3 %(prog)s audacious --album --artist --length
To switch track
$ python3 %(prog)s amarok --action=next
$ python3 %(prog)s clementine --action=play
Author: Amish Naidu (amhndu --at-- gmail)
Please report any bugs.
''')
parser.add_argument('-i', '--running', action='store_true', help="print 'yes' if the 'player' is running, 'no' otherwise")
parser.add_argument('player', action='store',
help="name of the player e.g. 'clementine', or 'vlc' or 'audacious' or 'xmms2'")
parser.add_argument('-r', '--conkyalignr', action='store_true', help='Add ${alignr} before values')
parser.add_argument('-w', '--width', type=int,
help="Truncate lines upto 'width' characters. No limit if less than zero (default)", default=-1)
parser.add_argument('-t', '--title', action='store_true', help='title of the track')
parser.add_argument('-a', '--artist', action='store_true', help='artist name')
parser.add_argument('-m', '--album', action='store_true', help='album name')
parser.add_argument('-g', '--genre', action='store_true', help='genre of the current track')
parser.add_argument('-y', '--year', action='store_true', help='year of the track')
parser.add_argument('-l', '--length', action='store_true', help='lenght of the track')
parser.add_argument('-e', '--elapsed', action='store_true', help='elapsed time for the track')
parser.add_argument('-p', '--progress', action='store_true',
help='progress of the track as a percent (not formatted)')
parser.add_argument('-n', '--track', action='store_true', help='track number')
parser.add_argument('-c', '--cover', help='Make a (soft) symlink at the specified location to the album art')
parser.add_argument('--cover_default', help='If the the album art could not be found from the player, make a link to this')
parser.add_argument('--action', action='store', help='make the player perform an action : next, prev, play, pause, volume up/down by 0.1',
choices=['next', 'prev', 'pause', 'play', 'playpause', 'volup', 'voldown'])
args = parser.parse_args()
try:
#MPRIS 2.0 Spec http://specifications.freedesktop.org/mpris-spec/latest/index.html
player = dbus.SessionBus().get_object('org.mpris.MediaPlayer2.' + args.player, '/org/mpris/MediaPlayer2')
metadata = player.Get('org.mpris.MediaPlayer2.Player', 'Metadata',
dbus_interface='org.freedesktop.DBus.Properties')
running = True
except dbus.exceptions.DBusException:
running = False
if args.running:
print("yes" if running else "no")
if not running:
print("Not found")
else:
if args.artist:
print(fmt_field('Artist',
metadata['xesam:artist'][0] if 'xesam:artist' in metadata else 'Unknown',
args.conkyalignr, args.width))
if args.title:
print(fmt_field('Title',
metadata['xesam:title'] if 'xesam:title' in metadata else 'Unknown', args.conkyalignr, args.width))
if args.album:
print(fmt_field('Album',
metadata['xesam:album'] if 'xesam:album' in metadata else 'Unknown', args.conkyalignr, args.width))
if args.genre:
print(fmt_field('Genre',
metadata['xesam:genre'][0] if 'xesam:genre' in metadata else 'Unknown', args.conkyalignr, args.width))
if args.year:
print(fmt_field('Year',
metadata['xesam:contentCreated'][:3] if 'xesam:contentCreated' in metadata else 'Unknown',
args.conkyalignr, args.width))
if args.track:
print(fmt_field('Track',
metadata['xesam:trackNumber'] if 'xesam:trackNumber' in metadata else 'Unknown',
args.conkyalignr, args.width))
if args.elapsed:
print(fmt_field('Elapsed', fmt_time(player.Get('org.mpris.MediaPlayer2.Player', 'Position',
dbus_interface='org.freedesktop.DBus.Properties')), args.conkyalignr, args.width))
if args.length:
print(fmt_field('Length',
fmt_time(metadata['mpris:length']) if 'mpris:length' in metadata else 'Unknown',
args.conkyalignr, args.width))
if args.progress:
if 'mpris:length' in metadata and metadata['mpris:length'] != 0:
print(int(player.Get('org.mpris.MediaPlayer2.Player', 'Position',
dbus_interface='org.freedesktop.DBus.Properties')*100/metadata['mpris:length']))
else:
print('Unknown')
if args.cover is not None:
if 'mpris:artUrl' in metadata:
location = metadata['mpris:artUrl'][7:]
subprocess.call(['ln', '-sf', location, args.cover])
elif args.cover_default is not None:
subprocess.call(['ln', '-sf', args.cover_default, args.cover])
if args.action is not None:
try:
interface = dbus.Interface(player, dbus_interface='org.mpris.MediaPlayer2.Player')
if args.action == 'next':
interface.Next()
elif args.action == 'prev':
interface.Previous()
elif args.action == 'pause':
interface.Pause()
elif args.action == 'play':
interface.Play()
elif args.action == 'playpause':
interface.PlayPause()
elif args.action == 'volup' or args.action == 'voldown':
volume = player.Get('org.mpris.MediaPlayer2.Player', 'Volume',
dbus_interface='org.freedesktop.DBus.Properties')
volume += 0.1 if args.action == 'volup' else -0.1
player.Set('org.mpris.MediaPlayer2.Player', 'Volume', volume,
dbus_interface='org.freedesktop.DBus.Properties')
except:
pass