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