summaryrefslogtreecommitdiff
path: root/mpc-notify
blob: ac0ced07c00da77075897439b5c526f27a5071e9 (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
#!/bin/sh -e
# Based on:
# 	https://wiki.archlinux.org/title/Ncmpcpp#With_album_art

# Sends notification of currently playing MPD music with 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 notification on song change:
# 	Assign execute_on_song_change to this script in ncmpcpp's config file.
# For notification on media keys:
# 	Bind media key to a call to mpc with the approprite command.

# 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
	;;
"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
	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
	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 anway
	[ "$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="$(mpc --format %album% current)"
	if [ -z "$song_album" ]; then
		# fallback to default for empty album name
		song_icon="$default_song_icon"
	else
		preview_path="${preview_dir}/$(echo "$song_album" | 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
		unset song_dirname
	fi
	unset preview_path
fi
unset xdg_music_dir song_filename song_album

# 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

# cleanup
unset command preview_dir preview_width preview_height default_song_icon \
	use_preview song_head song_body song_icon