[download]
local/bin/music
1
2
3 mocp_control(){ # {{{
4 case $1 in
5 play) mocp --play; sleep 0.2;;
6 stop) mocp --stop;;
7 pause) mocp --toggle-pause;;
8 prev) mocp --previous; sleep 0.1;;
9 next) mocp --next; sleep 0.1;;
10 seek) mocp --seek $2; sleep 0.1;;
11 esac 2>&-
12 } # }}}
13 mocp_status(){ # {{{
14 mapfile -t array < <(mocp -Q '
15 %state
16 %ts
17 %cs
18 %file
19 %artist
20 %album
21 %song
22 ' 2>&-)
23
24 [[ ${array[1]} == STOP ]] && return 1
25 [[ ${array[1]} == PLAY ]] && status=playing || status=paused
26
27 tts=${array[2]}
28 cts=${array[3]}
29
30 file=${array[4]}
31 artist=${array[5]}
32 album=${array[6]}
33 title=${array[7]}
34 } # }}}
35
36 audacious_control(){ # {{{
37 case $1 in
38 play) audtool playback-play;;
39 stop) audtool playback-stop;;
40 pause) audtool playback-playpause;;
41 prev) audtool playlist-reverse;;
42 next) audtool playlist-advance;;
43 seek) audtool playback-seek-relative $2;;
44 esac
45 } # }}}
46 audacious_status(){ # {{{
47 mapfile -t array < <(audtool \
48 playback-status \
49 current-song-length-seconds \
50 current-song-output-length-seconds \
51 current-song-filename \
52 current-song-tuple-data artist \
53 current-song-tuple-data album \
54 current-song-tuple-data title
55 )
56
57 [[ ${array[0]} == stopped ]] && return 1
58 [[ ${array[0]} == playing ]] && status=playing || status=paused
59
60 tts=${array[1]}
61 cts=${array[2]}
62
63 file=${array[3]}
64 artist=${array[4]}
65 album=${array[5]}
66 title=${array[6]}
67 } # }}}
68
69 cmus_control(){ # {{{
70 case $1 in
71 play) cmus-remote --play; sleep 0.2;;
72 stop) cmus-remote --stop;;
73 pause) cmus-remote --pause;;
74 prev) cmus-remote --prev;;
75 next) cmus-remote --next;;
76 seek) cmus-remote --seek $2;;
77 esac
78 } # }}}
79 cmus_status(){ # {{{
80 declare -A array
81 while read k1 k2 v; do
82 [[ $k1 == set || $k1 == tag ]] &&
83 array[$k2]="$v" || array[$k1]="$k2 $v"
84 done <<< "$(cmus-remote --query)"
85
86 [[ ${array[status]} == stopped* ]] && return 1
87 [[ ${array[status]} == playing* ]] && status=playing || status=paused
88
89 tts=${array[duration]}
90 cts=${array[position]}
91
92 file=${array[file]}
93 artist=${array[artist]}
94 album=${array[album]}
95 title=${array[title]}
96 } # }}}
97
98 mpd_control(){ # {{{
99 case $1 in
100 play) mpc play;;
101 stop) mpc stop;;
102 pause) mpc toggle;;
103 prev) mpc prev;;
104 next) mpc next;;
105 seek) mpc seek $2;;
106 esac >&-
107 } # }}}
108 mpd_status(){ # {{{
109 mapfile -t array < <(mpc -f '
110 %file%
111 %artist%
112 %album%
113 %title%
114 ')
115
116 [[ ${array[6]} ]] || return 1
117 [[ ${array[6]} == \[playing\]* ]] && status=playing || status=paused
118
119 read _ _ time _ <<< "${array[6]}"
120 tts=$(date -ud 00:${time#*/} +%s 2>&-)
121 cts=$(date -ud 00:${time%/*} +%s 2>&-)
122
123 file=${array[1]}
124 artist=${array[2]}
125 album=${array[3]}
126 title=${array[4]}
127 } # }}}
128
129 dbus(){ # {{{
130 qdbus org.mpris.MediaPlayer2.$1 \
131 /org/mpris/MediaPlayer2 \
132 org.mpris.MediaPlayer2.Player.$2 $3
133 } # }}}
134 dbus_control(){ # {{{
135 case $2 in
136 play) dbus $1 Play; sleep 0.2;;
137 stop) dbus $1 Stop;;
138 pause) dbus $1 PlayPause;;
139 prev) dbus $1 Previous;;
140 next) dbus $1 Next;;
141 seek) dbus $1 Seek $(( $3 * 1000000 ));;
142 esac
143 } # }}}
144 dbus_status(){ # {{{
145 status=$(dbus $1 PlaybackStatus) || return 1
146
147 [[ $status == Stopped ]] && return 1
148 [[ $status == Playing ]] && status=playing || status=paused
149
150 declare -A array
151 while read k v; do
152 array[$k]=$v
153 done < <(dbus $1 Metadata)
154
155 tts=$(( ${array[mpris:length:]} / 1000000 ))
156 cts=$(( $(dbus $1 Position) / 1000000 ))
157
158 file=${array[xesam:url:]#file://}
159 file=$(echo -e "${file//%/\\x}")
160
161 artist=${array[xesam:artist:]}
162 album=${array[xesam:album:]}
163 title=${array[xesam:title:]}
164 } # }}}
165
166 player_control(){ # {{{
167 case $2 in
168 play) playerctl -p $1 play; sleep 0.2;;
169 stop) playerctl -p $1 stop;;
170 pause) playerctl -p $1 play-pause;;
171 prev) playerctl -p $1 previous;;
172 next) playerctl -p $1 next;;
173 seek) playerctl -p $1 position $3;;
174 esac
175 } # }}}
176 player_status(){ # {{{
177 mapfile -t array < <(playerctl -p $1 metadata -f '
178 {{status}}
179 {{mpris:length}}
180 {{position}}
181 {{xesam:url}}
182 {{artist}}
183 {{album}}
184 {{title}}
185 ')
186
187 [[ ${array[1]} == Stopped ]] && return 1
188 [[ ${array[1]} == Playing ]] && status=playing || status=paused
189
190 tts=$(( ${array[2]} / 1000000 ))
191 cts=$(( ${array[3]} / 1000000 ))
192
193 file=${array[4]#file://}
194 file=$(echo -e "${file//%/\\x}")
195
196 artist=${array[5]}
197 album=${array[6]}
198 title=${array[7]}
199 } # }}}
200
201 rhythmbox_control(){ # {{{
202 command -v playerctl > /dev/null &&
203 player_control rhythmbox "$@" ||
204 dbus_control rhythmbox "$@"
205 } # }}}
206 rhythmbox_status(){ # {{{
207 command -v playerctl > /dev/null &&
208 player_status rhythmbox ||
209 dbus_status rhythmbox
210 } # }}}
211
212 mpv_control(){ # {{{
213 command -v playerctl > /dev/null &&
214 player_control mpv "$@" ||
215 dbus_control mpv "$@"
216 } # }}}
217 mpv_status(){ # {{{
218 command -v playerctl > /dev/null &&
219 player_status mpv ||
220 dbus_status mpv
221 } # }}}
222
223 export player icon file artist album title tt ct tl
224 for player in mocp cmus mpd audacious rhythmbox mpv; do
225 [[ $(pidof $player) ]] || continue
226 ${player}_control "$@" && ${player}_status || continue
227
228 tt=$(date -ud @$tts +%H:%M:%S)
229 ct=$(date -ud @$cts +%H:%M:%S)
230 tl=$(date -ud @$(( tts - cts )) +%H:%M:%S)
231
232 tt=${tt#00:}
233 ct=${ct#00:}
234 tl=${tl#00:}
235
236 [[ $title ]] || title=${file##*/}
237 [[ $status == playing ]] && icon=${MUSIC_ICON_PLAYING:-'>'}
238 [[ $status == paused ]] && icon=${MUSIC_ICON_PAUSED:-'||'}
239
240 [[ $MUSIC_PLAYER ]] && printf '[%9s] ' $player
241 [[ $MUSIC_FORMAT ]] && printf "$MUSIC_FORMAT" | envsubst
242 [[ $MUSIC_FORMAT ]] || echo "$icon $artist${artist:+ - }$title (-$tl)"
243 done
244
245 [[ $MUSIC_FORMAT ]] ||
246 echo "$icon $ct $tt $file" > ~/.cache/music
247
248 [[ $status ]]
|