Listening to music from the terminal

Not too long ago silent and solitary music listening was not possible. Only with the advent of personal stereos and headphones were humans capable of creating personalised soundtracks and engaging with them privately. Eventually, headphones became a means of negotiating social interaction in crowded urban environments, making it harder to initiate conversations in public.

By now most cultural performances have been cancelled as a result of the coronavirus pandemic, making institutions, artists and their audience more reliant on the internet. This left us with fewer choices, at least until the dry season of live performances is over, over how we interact with music, so maybe it’s a good time to rethink music listening as part of our solitary rituals.

EMMS is what I use often, and I’ve used it for as far as I can remember, but that’s probably only useful for Emacs users. There are still quite a few other options around for browsing and listening to your music library (provided you have one already) without GUIs, advertisements, subscription, or even the internet. For this project, I’ll use mpv, fzf, fd, and a shell script to glue the pieces together. By the way, you don’t really need fd. GNU find should work just fine.

Anyway, with these three programs installed, all you need is a file in your $PATH with the code below. Name it whatever you want, and make it executable by running chmod +x followed by the file name. That’s it. Open your terminal, type the command name and press return. You can also bind the command to some key to avoid typing. For example, I use bindkey -s '^[m' 'thefile\n' (that’s Alt-m), but that may vary depending on the shell you’re using.

#!/bin/bash

shopt -s nullglob

cd ~/Music || exit

FZF_DEFAULT_COMMAND="fd --color=always --type f"
file=$(fzf --ansi --exact)
dir=$(dirname "$PWD/$file")
file=$(basename "$file")

cd "$dir" || exit

array=(*)

for i in "${!array[@]}"; do
    if [ "$file" = "${array[$i]}" ]; then
        mpv -- * --playlist-start="$i"
    fi
done

The script allows you to fuzzy search filenames and directories only, but as long as the naming scheme you’re using is logical to you, it should be easy enough to find the song, artist or album you’re looking for. It also finds the index of the match to create a playlist of all files in the directory.

In general, mpv worked well out of the box, and comes bundled with a reasonable set of keyboard shortcuts. You may, however, consider disabling album covers by adding audio-display=no to the configuration file (~/.config/mpv/mpv.conf), and perhaps enabling term-osd-bar, which prints a progress bar under the status line on the terminal.

You may also consider extending the script if you want to play files from a playlist file, which can be done by determining the file type first so that playlist files are passed to the playlist flag (see here). Note that to stream music, you will also need youtube-dl installed.

That’s all for now. I hope you enjoyed reading this far. There’s no price (literally) in making that black terminal screen function as a media player, and it should be pretty safe too (assuming you do it from $HOME, of course ;).

🏷️ programming