Blob


1 #!/bin/sh -e
2 # mpc-notify: sends notification of currently playing MPD music accompanied
3 # by album cover art.
5 # exit early if we're in tty
6 if [ -z "$WAYLAND_DISPLAY" ] && [ -z "$DISPLAY" ]; then
7 exit 2
8 fi
10 # globals
11 command="$1"
12 use_preview=0
14 # defaults
15 # FEATURE: make defaults configurable through flags
16 preview_dir="${XDG_CONFIG_HOME:-$HOME/.config}/mpc/previews"
17 preview_width=64
18 preview_height=64
19 default_song_icon="media-playback-start"
21 # issue an mpc command based on arguments and assemble notification message
22 case "$command" in
23 "")
24 # use defaults
25 song_head="Now Playing"
26 use_preview=1
27 ;;
28 "stop")
29 mpc -q stop
30 song_head="Stopped Playing"
31 song_icon="media-playback-stop"
32 ;;
33 "toggle")
34 mpc -q toggle
35 state="$(mpc status %state%)"
36 case "$state" in
37 "playing")
38 song_head="Now Playing"
39 use_preview=1
40 ;;
41 "paused")
42 song_head="Paused"
43 song_icon="media-playback-pause"
44 ;;
45 esac
46 ;;
47 "shuffle")
48 mpc -q shuffle
49 song_head="Shuffled Playlist"
50 song_icon="media-playlist-shuffle"
51 ;;
52 "single")
53 mpc -q single
54 state="$(mpc status %single%)"
55 case "$state" in
56 "on")
57 song_head="Single Mode: On";;
58 "once")
59 song_head="Single Mode: Once";;
60 "off")
61 song_head="Single Mode: Off";;
62 esac
63 # TODO: consider a more appropriate icon
64 song_icon="multimedia-player"
65 ;;
66 "random")
67 mpc -q random
68 state="$(mpc status %random%)"
69 case "$state" in
70 "on")
71 song_head="Random Mode: On";;
72 "off")
73 song_head="Random Mode: Off";;
74 esac
75 # TODO: consider a more appropriate icon
76 song_icon="media-eject"
77 ;;
78 "repeat")
79 mpc -q repeat
80 state="$(mpc status %repeat%)"
81 case "$state" in
82 "on")
83 song_head="Repeat Mode: On";;
84 "off")
85 song_head="Repeat Mode: Off";;
86 esac
87 song_icon="media-playlist-repeat"
88 ;;
89 *)
90 mpc -q "$command"
91 # don't notify if mpc changed song because ncmpcpp would notify on
92 # song change anyway
93 [ "$command" = "next" ] || [ "$command" = "prev" ] && exit
94 ;;
95 esac
97 # use album preview for song icon
98 if [ "$use_preview" -eq 1 ]; then
99 [ -d "$preview_dir" ] || mkdir -p "$preview_dir"
101 # find xdg music directory
102 # user-dirs.dirs is not guaranteed to exist
103 # shellcheck disable=SC1091
104 . "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" 2>/dev/null || true
105 xdg_music_dir="${XDG_MUSIC_DIR:-$HOME/Music}"
107 # get preview filename
108 song_filename="$(mpc --format "${xdg_music_dir}/%file%" current)"
109 song_album_name="$(mpc --format %album% current)"
110 if [ -z "$song_album_name" ]; then
111 # fallback to the default icon for an empty album name
112 song_icon="$default_song_icon"
113 else
114 preview_path="${preview_dir}/$(echo "$song_album_name" | base64).png"
115 if [ -f "$preview_path" ]; then
116 # use cached preview
117 song_icon="$preview_path"
118 elif ffmpeg -y -i "$song_filename" -an -vf \
119 scale="${preview_width}:${preview_height}" \
120 "$preview_path" >/dev/null 2>&1;
121 then
122 # or use generated preview
123 song_icon="$preview_path"
124 else
125 song_dirname=$(dirname "$song_filename")
126 if art_filename="$(find "$song_dirname" -type f |
127 grep -Esm 1 '.*\.(jpg|png)')"
128 then
129 # or use scaled cover art from directory
130 ffmpeg -y -i "$art_filename" -an -vf \
131 scale="${preview_width}:${preview_height}" \
132 "$preview_path" >/dev/null 2>&1;
133 song_icon="$preview_path"
134 else
135 # or fallback to default icon
136 song_icon="$default_song_icon"
137 fi
138 fi
139 fi
140 fi
142 # now send the actual notification
143 song_body="$(mpc --format '[%title%[ \n%artist% - %album%]]|[%file%]' current)"
144 notify-replace 'mpc-notify' "$song_head" "$song_body" -i "$song_icon" -u low