summaryrefslogtreecommitdiff
path: root/mpc-notify
blob: 48cb5c7ad9759d32245465043cd0693d5a78ac23 (plain)
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
153
154
155
156
157
158
159
160
161
162
#!/bin/sh -e
# Based on:
# 	https://wiki.archlinux.org/title/Ncmpcpp#With_album_art
#
# mpc-notify: sends notification of currently playing MPD music accompanied
# by album cover art.
#
# Dependencies:
# 	mpc
# 	ffmpeg
# 	notify-send
# 	and my other script, notify-replace.
# 	recommended: a home directory setup with xdg-user-dirs (for finding your
# 	music directory)
#
# For getting notifications on media keys:
# 	Bind media key to calls to mpc-notify instead of mpc or other media
# 	controllers.
# For getting notifications on song change, add:
# 		execute_on_song_change = "mpc-notify"
# 	to your ncmpcpp's configuration file.

# exit early if we're in tty
if [ -z "$WAYLAND_DISPLAY" ] && [ -z "$DISPLAY" ]; then
	exit 2
fi

# globals
command="$1"
use_preview=0

# defaults
# FEATURE: make defaults configurable through flags
preview_dir="${XDG_CONFIG_HOME:-$HOME/.config}/mpc/previews"
preview_width=64
preview_height=64
default_song_icon="media-playback-start"

# issue an mpc command based on arguments and assemble notification message
case "$command" in
"")
	# use defaults
	song_head="Now Playing"
	use_preview=1
	;;
"stop")
	mpc -q stop
	song_head="Stopped Playing"
	song_icon="media-playback-stop"
	;;
"toggle")
	mpc -q toggle
	state="$(mpc status %state%)"
	case "$state" in
	"playing")
		song_head="Now Playing"
		use_preview=1
		;;
	"paused")
		song_head="Paused"
		song_icon="media-playback-pause"
		;;
	esac
	;;
"shuffle")
	mpc -q shuffle
	song_head="Shuffled Playlist"
	song_icon="media-playlist-shuffle"
	;;
"single")
	mpc -q single
	state="$(mpc status %single%)"
	case "$state" in
	"on")
		song_head="Single Mode: On";;
	"once")
		song_head="Single Mode: Once";;
	"off")
		song_head="Single Mode: Off";;
	esac
	# TODO: consider a more appropriate icon
	song_icon="multimedia-player"
	;;
"random")
	mpc -q random
	state="$(mpc status %random%)"
	case "$state" in
	"on")
		song_head="Random Mode: On";;
	"off")
		song_head="Random Mode: Off";;
	esac
	# TODO: consider a more appropriate icon
	song_icon="media-eject"
	;;
"repeat")
	mpc -q repeat
	state="$(mpc status %repeat%)"
	case "$state" in
	"on")
		song_head="Repeat Mode: On";;
	"off")
		song_head="Repeat Mode: Off";;
	esac
	song_icon="media-playlist-repeat"
	;;
*)
	mpc -q "$command"
	# don't notify if mpc changed song because ncmpcpp would notify on
	# song change anyway
	[ "$command" = "next" ] || [ "$command" = "prev" ] && exit
	;;
esac

# use album preview for song icon
if [ "$use_preview" -eq 1 ]; then
	[ -d "$preview_dir" ] || mkdir -p "$preview_dir"

	# find xdg music directory
	# user-dirs.dirs is not guaranteed to exist
	# shellcheck disable=SC1091
	. "${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs" 2>/dev/null || true
	xdg_music_dir="${XDG_MUSIC_DIR:-$HOME/Music}"

	# get preview filename
	song_filename="$(mpc --format "${xdg_music_dir}/%file%" current)"
	song_album_name="$(mpc --format %album% current)"
	if [ -z "$song_album_name" ]; then
		# fallback to the default icon for an empty album name
		song_icon="$default_song_icon"
	else
		preview_path="${preview_dir}/$(echo "$song_album_name" | base64).png"
		if [ -f "$preview_path" ]; then
			# use cached preview
			song_icon="$preview_path"
		elif ffmpeg -y -i "$song_filename" -an -vf \
			scale="${preview_width}:${preview_height}" \
			"$preview_path" >/dev/null 2>&1;
		then
			# or use generated preview
			song_icon="$preview_path"
		else
			song_dirname=$(dirname "$song_filename")
			if art_filename="$(find "$song_dirname" -type f |
				grep -Esm 1 '.*\.(jpg|png)')"
			then
				# or use scaled cover art from directory
				ffmpeg -y -i "$art_filename" -an -vf \
					scale="${preview_width}:${preview_height}" \
					"$preview_path" >/dev/null 2>&1;
				song_icon="$preview_path"
			else
				# or fallback to default icon
				song_icon="$default_song_icon"
			fi
		fi
	fi
fi

# now send the actual notification
song_body="$(mpc --format '[%title%[ \n%artist% - %album%]]|[%file%]' current)"
notify-replace 'mpc-notify' "$song_head" "$song_body" -i "$song_icon" -u low