Ncmpcpp is a really nice mpd client for anyone that prefers cli based applications. It has all the functionality one would need, but sadly it has no built-in way of showing album art for the current playing song (to be fair, rendering images via a terminal emulator is pretty tricky).
Here I'll show you how to include album art in your ncmcpp client and include the built-in visualizer while browsing songs.
The final result would be something like this:
To start off, a few dependencies that need to be installed in order for this to work:
tmux (to encapsulate everything in one window) inotify-tools (for changing album art when switching songs) ueberzug (for image rendering) ffmpeg (used in scaling the album art) mpc (cli client for MPD)
You can get Ueberzug here.
The basic idea is that each time the song changes it triggers a script that searches for an album
cover inside the file itself or the containing folder and copies it in /tmp
as album_cover.png
.
Another script listens for changes on that file and renders the new image in the terminal.
Start by creating a script named cover.sh
in ~/.ncmcpp/
:
#!/bin/bash
source "`ueberzug library`"
COVER="/tmp/album_cover.png"
function add_cover {
ImageLayer::add [identifier]="img" [x]="2" [y]="1" [path]="$COVER"
}
ImageLayer 0< <(
if [ ! -f "$COVER" ]; then
cp "$HOME/.ncmpcpp/default_cover.png" "$COVER"
fi
#rerender image when changed
while inotifywait -q -q -e close_write "$COVER"; do
add_cover
done
)
This is going to listen for cover changes and render them.
If no album cover for the current song is found, a default image will be selected. Be sure to
add one named default_cover.png
in ~/.ncmpcpp/
.
Now create cover_obs.sh
in the same directory:
#!/bin/bash COVER="/tmp/album_cover.png" COVER_SIZE="400" #path to current song file="$MUSIC_DIR/$(mpc --format %file% current)" album="${file%/*}" #search for cover image #use embedded image if present, otherwise take it from the current folder err=$(ffmpeg -loglevel 16 -y -i "$file" -an -vcodec copy $EMB_COVER 2>&1) if [ "$err" != "" ]; then art=$(find "$album" -maxdepth 1 | grep -m 1 ".*\.\(jpg\|png\|gif\|bmp\)") else art=$EMB_COVER fi if [ "$art" = "" ]; then art="$HOME/.ncmpcpp/default_cover.png" fi #copy and resize image to destination ffmpeg -loglevel 0 -y -i "$art" -vf "scale=$COVER_SIZE:-1" "$COVER"
This is the script executed when switching songs. It searches for images in the directory of the current song.
Here I chose a render size of 400 x 400, but it can be anything.
Notice the use of $MUSIC_DIR
. You need to export it with the path to your music directory.
Tell ncmpcpp to execute it every time the song changes by adding this to ~/.ncmpcpp/config
execute_on_song_change = "~/.ncmpcpp/cover_obs.sh"
And don't forget to make them executable
chmod +x cover.sh chmod +x cover_obs.sh
As mentioned above, we use tmux to run multiple terminal based programs in a single window so that everything fits nicely (i.e. 2 instances of ncmpcpp and one terminal running our image rendering script).
Create a file named tsession
in ~/.ncmpcpp/
to define a tmux session:
neww set -g status off #image pane; run cover script, disable text output and remove prompt send-keys "stty -echo" C-m send-keys "tput civis -- invisible" C-m send-keys "export PS1=''" C-m send-keys "clear" C-m send-keys "~/.ncmpcpp/cover.sh " C-m #catalog pane; run instance of ncmpcpp split-window -v select-pane -t 1 send-keys "ncmpcpp --config='~/.ncmpcpp/catalog.conf'" C-m send-keys 1 #visualizer pane; run instance of ncmpcpp in visualizer mode select-pane -t 0 split-window -h send-keys "ncmpcpp --config='~/.ncmpcpp/visualizer.conf'" C-m send-keys 8 send-keys u #resize image and visualizer pane to fit image resize-pane -t 0 -x 49 -y 23 resize-pane -t 1 -y 23 #hook for keeping the image pane size constant set-hook client-resized 'resize-pane -t 0 -x 49 -y 23' #focus on catalog pane select-pane -t 2
Here I used some custom configuration for both catalog and visualizer, but it's not mandatory. If you
changed the image size from cover_obs.sh
, you may want to adjust the pane resize values.
Define an alias in your .bashrc
so it's more convenient to start:
alias music='tmux new-session -s $$ "tmux source-file ~/.ncmpcpp/tsession"'
This will create the session and name it after it's PID. One important thing to note is that whenever you close the terminal, the session will keep running in a detached state. To circumvent this, also add the following:
_trap_exit() { tmux kill-session -t $$; }
This way the session will be killed and no resources will be wasted.
Now simply type music
into the terminal to launch it.
You can take a look at the complete config files here.