cmus: auto show/hide UI, mark favorites and easier global shortcuts


Laid my hands on cmus recently and it got my spot just right, lightweight yet powerful, and useful plugins with specialized purposes.

One thing is, if I use Krunner to start it, cmus will just silently lie backstage listening on its socket and leave me no way to attach it to a GUI. This causes big problems to me since I always set it to start automatically upon system boot. Also, sometimes I may want to bring up cmus in GUI to alternate the playlist/queue and send it backstage afterwards. With the default cmus-remote it's pretty hard to achieve what I want, especially when I want to do most of the work with shortcuts. Messing around google and I found this solution which tries to attach/detach cmus to a screen/tmux session, and it works nicely. Also I add some keybindings to make the whole use case much smoother.

Attach/detach cmus to a screen/tmux session (credits)
  1. Attach

    • With screen

      #!/bin/bash
      if ! screen -r -D cmus >/dev/null ; then
          screen -S cmus /usr/bin/cmus "$@"
      fi
      

    • With tmux

      #!/bin/bash
      if ! tmux has-session -t cmus 2>/dev/null; then
          tmux new-session -s cmus -d -n cmus -d "/usr/bin/cmus $@"
      fi
      tmux attach -d -t cmus
      

  2. Detach

    Set it in the keybindings view (7) of cmus.

    • With screen
      :bind -f common q shell screen -d cmus
      
    • With tmux
      :bind -f common q shell tmux detach-client -s cmus
      
Mark favorites with cmus

I have a large collection of music and keep updating it all the time. Occassionally some jewel will pop up in my radom list, and needs to be marked as my favorites immediately, and I don't want to stop what I'm doing at that moment. The following script does the job for me, and by assigning it to a shortcut, I can mark the current playing song as my favorite and store it in a predefined playlist, without interrupting the work at hand. The script is a modification of Markus00000's work here. The original script rates the song at a scale of 1 to 5, feel free to grab it if that's what you need.

#!/bin/bash
# By Lynxiayel
# Based on the script by Markus00000 at:
# https://gist.github.com/Markus00000/ad8c0ff46290f9dc2887

# This script mark current playing song as your favorite and adds it to a m3u 
# playlist which holds all your favorites.

# Path to playlists
playlists="$HOME/music_list"

# Prefix and suffix strings for the playlist file name
pl_prefix='cmus_fav'
pl_suffix='.m3u'

# Get current song from cmus
song=$(cmus-remote -Q | grep file)

# Error cases
if [[ -z "$song" ]]; then
    echo 'No song is playing.'
    exit 1
fi

# Path to lock file
lock="/tmp/music-rate.lock"

# Lock the file (other atomic alternatives would be "ln" or "mkdir")
exec 9>"$lock"
if ! flock -n 9; then
    notify-send -t 5000 "Rating failed: Another instance is running."
    exit 1
fi

# Strip "file " from the output
song=${song/file \///}

# Temporary file for grepping and sorting
tmp="$playlists/tmp.m3u"

# # Remove the song from the fav playlists
# f="$playlists/${pl_prefix}${pl_suffix}"
# if [[ -f "$f" ]]; then
#     grep -vF "$song" "$f" > "$tmp"
#     mv -f "$tmp" "$f"
# fi

# Append the song to the fav playlist
f="$playlists/${pl_prefix}$1${pl_suffix}"
mkdir -p "$playlists"
echo "$song" >> "$f"
sort -u "$f" -o "$tmp"
mv -f "$tmp" "$f"
notify-send -t 3000 "$song added to the $pl_prefix list."

# The lock file will be unlocked when the script ends
Add this script to your path, and you can then assign a shortcut to call it from anywhere anytime.

Shortcut settings (Examples in KDE)

Assume you have saved the aforementioned attach code in a script called cmus, and put it in your system path, so it's found before the real cmus program. You can do this by put the following command into your ~/.bashrc

export PATH=path/to/your/cmus/script/:$PATH

Open the KDE custom shortcuts, either with krunner or in your app drawers, and create a new shortcut group for cmus. Then create the following keys with your choices of keybindings.

  • start cmus
    konsole -e "path/to/your/cmus/attach/script"
    
  • play/pause
    cmus-remote -u
    
  • next song
    cmus-remote -n
    
  • previous song
    cmus-remote -r
    
  • increase vol
    cmus-remote -v +5%
    
  • decrease vol
    cmus-remote -v -5%
    

By