#!/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