mpc-notify

mpd/ncmpcc notifications with album covers
git clone https://git.pastanoggin.com/mpc-notify.git
Log | Files | Refs | README

mpc-notify (4038B)


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