1 ;;; cmus.el --- A very simple interface to cmus, useable locally and remotely via ssh. 2 ;------------------------------------------------------------------------------ 3 ;; Remote control of cmus audio player 4 ;; Copyright (C) 2015-2017, Winfried S. Dietmayer ---==WDI==--- 5 6 ;; Author: Winfried S. Dietmayer ---==WDI==--- <winfried@sunkiddance.de> 7 ;; Version: 0.2 8 ;; Keywords: multimedia, audio player remote control, cmus, ssh, elisp 9 10 ;; cmus.el is free software: you can redistribute it and/or modify 11 ;; it under the terms of the GNU General Public License as published by 12 ;; the Free Software Foundation, either version 3 of the License, or 13 ;; (at your option) any later version. 14 15 ;; cmus.el is distributed in the hope that it will be useful, 16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 ;; GNU General Public License for more details. 19 20 ;; You should have received a copy of the GNU General Public License 21 ;; along with cmus.el. If not, see <https://www.gnu.org/licenses/>. 22 ;; 23 ;; To summarize: This is *free* but copyrighted software, 24 ;; *free* as in *free*dom or *free* will. 25 26 ;;; Commentary: 27 ;; Overview 28 ;; -------- 29 ;; cmus.el provides a simple interface for cmus, the C* music player. 30 ;; It allows to control the basics, i.e. start, stop, pause, previous track, 31 ;; next track, status of cmus player, lyrics for the currently playing track 32 ;; and a possibility to look up the lyrics of a song, given artist and title 33 ;; of the song. 34 ;; It provides this basic functionality either on the local machine with cmus 35 ;; and Emacs running, or on a remote machine issuing the cmus commands via ssh. 36 ;; The main scenario is to remote control cmus from within a virtual machine 37 ;; running on the local machine. You don't have to leave the virtual machine 38 ;; in order to control cmus. No distractions only to mute the sound or to go 39 ;; on to the next track. 40 ;; 41 ;; Prerequisites 42 ;;-------------- 43 ;; * Local machine 44 ;; ** cmus installed, any version will do 45 ;; ** sshd installed if you plan to use it remotely, i.e. from a virtual machine 46 ;; ** Script to retrieve the lyrics from the internet, say ~/bin/lyrics-cmus.sh 47 ;; * Remote machine 48 ;; ** ssh public-key authentication to localhost configured 49 ;; 50 ;; Configuration of cmus 51 ;; --------------------- 52 ;; On cmus command line: 53 ;; :set status_display_program=/path/to/program/cmus-artist-title.sh 54 ;; To make this permanent, add the line above to your ~/.cmus/rc 55 ;; cmus-artist-title.sh writes the current cmus status 56 ;; (artist, track title, etc.) to a defined file, say ~/cmus-status.txt. 57 ;; 58 ;; Configuration of cmus.el 59 ;; ------------------------ 60 ;; cmus.el support the Emacs Custom interface invoked with 'M-x customize'. 61 ;; cmus is located in the subgroups 'Application/cmus' and 'Multimedia/cmus', respectively. 62 ;; The entries there are self-explanatory, really, believe me 8-) . 63 ;; The parameter 'Cmus Lyrics Command' is the full path to a script/program which retrieves 64 ;; the lyrics of the currently playing track. It reads this information from cmus-status.txt. 65 ;; Alternatively, the script shall accept two parameters, 'artist' and 'title', 66 ;; for example 'Beatles yesterday'. 67 ;; 68 ;; cmus.el buffer 69 ;; -------------- 70 ;; Messages returned to Emacs are logged into buffer *CMUS-Shell-Output*. 71 ;; If things go awry, look there for a clue what went wrong. 72 ;; 73 ;; Configuration of ~/.emacs 74 ;; ------------------------- 75 ;; In order to load cmus.el at startup, add the following line to ~/.emacs: 76 ;; (load-file "~/bin/emacs/cmus.el") 77 78 ;------------------------------------------------------------------------------ 79 ;;; Code: 80 (defgroup cmus () 81 "Very simple remote and local client for the C* music player (cmus)." 82 :prefix "cmus-" 83 :group 'multimedia 84 :group 'applications) 85 (defcustom 86 cmus-remote-ssh-port "" 87 "The port number sshd on remote *cmus* host is listening to. Leave blank if invoked locally." 88 :type 'string) 89 (defcustom 90 cmus-remote-ssh-login "" 91 "The ssh user and remote *cmus* host name to login, f.e. <user@192.168.1.1>. Leave blank if invoked locally." 92 :type 'string) 93 (defcustom 94 cmus-local-ssh-command "" 95 "The *local* ssh command to connect to remote *cmus* host. Leave blank if invoked locally." 96 :type 'string) 97 (defcustom 98 cmus-local-ssh-parameter "" 99 "The *local* ssh command parameters to connect to remote *cmus* host. Note that the last parameter has to be -p. 100 Leave blank if invoked locally." 101 :type 'string) 102 (defcustom 103 cmus-command "/opt/local/bin/cmus-remote" 104 "The command to control *cmus* locally or remotely." 105 :type 'string) 106 (defcustom 107 cmus-lyrics-command "/Users/winfried/bin/lyrics-cmus.sh" 108 "The *cmus* command to retrieve the lyrics." 109 :type 'string) 110 ;; ------------------------------------------------------------------------------ 111 ; cmus helper functions 112 (defun ssh-command-string () 113 "The complete shell command string to control *cmus*." 114 (mapconcat 'identity 115 (list cmus-local-ssh-command 116 cmus-local-ssh-parameter 117 cmus-remote-ssh-port 118 cmus-remote-ssh-login 119 cmus-command) 120 " ")) 121 122 (defun ssh-command-lyrics-string () 123 "The complete shell command string to retrieve lyrics." 124 (mapconcat 'identity 125 (list cmus-local-ssh-command 126 cmus-local-ssh-parameter 127 cmus-remote-ssh-port 128 cmus-remote-ssh-login 129 cmus-lyrics-command) 130 " ")) 131 ;; ------------------------------------------------------------------------------ 132 (defun cmus-play () 133 "Start playing the current song in cmus." 134 (interactive) 135 (start-process-shell-command "*CMUS-Shell-Play*" "*CMUS-Shell-Output*" (ssh-command-string) "-p")) 136 (global-set-key "\C-c\C-xp" 'cmus-play) 137 138 (defun cmus-pause () 139 "Pause playing the current song in cmus." 140 (interactive) 141 (start-process-shell-command "*CMUS-Shell-Pause*" "*CMUS-Shell-Output*" (ssh-command-string) "-u")) 142 (global-set-key "\C-c\C-xu" 'cmus-pause) 143 144 (defun cmus-stop () 145 "Stop playing the current song in cmus." 146 (interactive) 147 (start-process-shell-command "*CMUS-Shell-Stop*" "*CMUS-Shell-Output*" (ssh-command-string) "-s")) 148 (global-set-key "\C-c\C-xs" 'cmus-stop) 149 150 (defun cmus-vol (volume) 151 "Set the VOLUME in cmus. 152 The complete possible command is as follows: [+-]NUM[%]. 153 NUM is a number in (0..100)." 154 (interactive "MVolume:(0..100):") 155 (start-process-shell-command "*CMUS-Shell-Vol*" "*CMUS-Shell-Output*" (ssh-command-string) "-v" volume)) 156 (global-set-key "\C-c\C-xv" 'cmus-vol) 157 158 (defun cmus-next () 159 "Play the next song in cmus." 160 (interactive) 161 (start-process-shell-command "*CMUS-Shell-Next*" "*CMUS-Shell-Output*" (ssh-command-string) "-n")) 162 (global-set-key "\C-c\C-xn" 'cmus-next) 163 164 (defun cmus-previous () 165 "Play the previous song in cmus." 166 (interactive) 167 (start-process-shell-command "*CMUS-Shell-Previous*" "*CMUS-Shell-Output*" (ssh-command-string) "-r")) 168 (global-set-key "\C-c\C-xr" 'cmus-previous) 169 170 (defun cmus-show-lyrics () 171 "Retrieve the lyrics of the song currently played and display it in the buffer *CMUS Lyrics*." 172 (interactive) 173 (switch-to-buffer (create-file-buffer "*CMUS Lyrics*")) 174 (text-mode) 175 (insert (shell-command-to-string (ssh-command-lyrics-string))) 176 (goto-char (point-min)) 177 (view-mode)) 178 (global-set-key "\C-c\C-xl" 'cmus-show-lyrics) 179 180 (defun cmus-show-lyrics-user (&optional artist title) 181 "Retrieve the lyrics of the ARTIST and TITLE provided by the user and displays it in the buffer *CMUS Lyrics*." 182 (interactive 183 "Martist: \nMtitle: ") 184 (switch-to-buffer (create-file-buffer "*CMUS Lyrics*")) 185 (text-mode) 186 (insert 187 (shell-command-to-string 188 (concat (ssh-command-lyrics-string) 189 (shell-quote-argument 190 (concat " \""artist"\"" " " "\""title"\""))))) 191 (goto-char (point-min)) 192 (view-mode)) 193 (global-set-key "\C-c\C-xt" 'cmus-show-lyrics-user) 194 195 (defun cmus-status () 196 "Show the current state of cmus." 197 (interactive) 198 (switch-to-buffer (create-file-buffer "*CMUS Status*")) 199 (text-mode) 200 (insert (shell-command-to-string (concat (ssh-command-string) " -Q"))) 201 (goto-char (point-min)) 202 (view-mode)) 203 (global-set-key "\C-c\C-xQ" 'cmus-status) 204 ;------------------------------------------------------------------------------ 205 206 (provide 'cmus) 207 208 ;;; cmus.el ends here