ambevar-dotfiles/.emacs.d/lisp/init-emms.el

171 lines
7.0 KiB
EmacsLisp

;;; Emms
;;; TODO: See if mpd is faster at building the db. Not so important.
;;; TODO: Change face from purple to white?
;;; TODO: emms-all causes some "require"d files to be loaded twice if called after, say, emms-browser was loaded.
(emms-all)
(emms-history-load)
(setq emms-player-list (list emms-player-mpv)
emms-source-file-default-directory (file-truename "~/music")
emms-source-file-directory-tree-function 'emms-source-file-directory-tree-find
;; Cover thumbnails.
emms-browser-covers 'emms-browser-cache-thumbnail-async)
(add-to-list 'emms-player-mpv-parameters "--no-audio-display")
(add-to-list 'emms-info-functions 'emms-info-cueinfo)
(when (version<= emms-version "5.3")
(setq emms-player-mpv-ipc-method 'file)) ; TODO: Remove once Emms 5.4 is out.
(if (executable-find "emms-print-metadata")
(progn
(require 'emms-info-libtag)
(add-to-list 'emms-info-functions 'emms-info-libtag)
(delete 'emms-info-ogginfo emms-info-functions)
(delete 'emms-info-mp3info emms-info-functions))
(add-to-list 'emms-info-functions 'emms-info-ogginfo)
(add-to-list 'emms-info-functions 'emms-info-mp3info))
;;; Resume on restart.
;;; We don't use bookmarks as that could interfere with user's ones.
(with-eval-after-load 'desktop
(add-to-list 'desktop-globals-to-save 'emms-playing-time)
(when (emms-playlist-current-selected-track)
(let ((time emms-playing-time))
(setq emms-playing-time 0) ; Don't disturb the time display.
(and (memq 'emms-player-mpv emms-player-list)
(executable-find "mpv")
(push "--mute=yes" emms-player-mpv-parameters))
(emms-start)
(sleep-for 0 300) ; This is required for the player might not be ready yet.
;; TODO: This 'sleep-for' is a kludge and upstream should provide a provision for it.
(with-demoted-errors "EMMS error: %S" (emms-player-seek-to time))
(and (memq 'emms-player-mpv emms-player-list)
(executable-find "mpv")
(pop emms-player-mpv-parameters)
;; TODO: Adapt this to new mpv backend when emms 5.1 is out.
(call-process-shell-command (emms-player-mpv--format-command "mute") nil nil nil))
(emms-pause))))
(when (require 'helm-emms nil t)
(setq helm-emms-dired-directories (list emms-source-file-default-directory
"~/humour"
"~/Soundtrack"))
(setq helm-emms-default-sources
'(helm-source-emms-dired
helm-source-emms-files ; Disable for a huge speed-up.
helm-source-emms-streams)))
(defun ambrevar/emms-play-on-add (old-pos)
"Play tracks when calling `emms-browser-add-tracks' if nothing
is currently playing."
(interactive)
(when (or (not emms-player-playing-p)
emms-player-paused-p
emms-player-stopped-p)
(with-current-emms-playlist
(goto-char old-pos)
;; if we're sitting on a group name, move forward
(unless (emms-playlist-track-at (point))
(emms-playlist-next))
(emms-playlist-select (point)))
(emms-stop)
(emms-start)))
(add-hook 'emms-browser-tracks-added-hook 'ambrevar/emms-play-on-add)
;;; Display album in playlist
(defun ambrevar/emms-artist-album-track-and-title-format (bdata fmt)
(concat
"%i"
(let ((artist (emms-browser-format-elem fmt "a")))
(if (not artist)
"%n" ; If unknown, display the filename.
(concat
"%a - "
(let ((album (emms-browser-format-elem fmt "A")))
(if album "%A - " ""))
(let ((disc (emms-browser-format-elem fmt "D")))
(if (and disc (not (string= disc ""))) "%D/" ""))
(let ((track (emms-browser-format-elem fmt "T")))
(if (and track (not (string= track "0")))
"%T. "
""))
"%t [%d]")))))
(setq emms-browser-playlist-info-title-format 'ambrevar/emms-artist-album-track-and-title-format)
;; Display disc number in browser
(defun ambrevar/emms-browser-track-artist-and-title-format (bdata fmt)
(concat
"%i"
(let ((disc (emms-browser-format-elem fmt "D")))
(if (and disc (not (string= disc "")))
"%D/"))
(let ((track (emms-browser-format-elem fmt "T")))
(if (and track (not (string= track "0")))
"%T. "
""))
"%n"))
(setq emms-browser-info-title-format 'ambrevar/emms-browser-track-artist-and-title-format)
(defun ambrevar/emms-time-for-display (track)
"Inspired by `emms-playing-time-display'."
(let* ((total-playing-time
(or (emms-track-get
track
'info-playing-time)
0))
(total-min-only (/ total-playing-time 60))
(total-sec-only (% total-playing-time 60)))
(format "%02d:%02d" total-min-only total-sec-only)))
(defun ambrevar/emms-track-description-with-album (track)
"Simple function to give a user-readable description of a track.
If it's a file track, just return the file name. Otherwise,
return the type and the name with a colon in between.
Hex-encoded characters in URLs are replaced by the decoded
character."
(let ((type (emms-track-type track)))
(cond ((eq 'file type)
(cl-flet ((fmt (string &optional suffix prefix)
(if string
(concat prefix string suffix)
"")))
(concat
(fmt (emms-track-get track 'info-artist) " - ")
(fmt (emms-track-get track 'info-album) " - ")
(fmt (emms-track-get track 'info-discnumber) "/")
(if (emms-track-get track 'info-tracknumber)
(format "%02d. " (string-to-number (emms-track-get track 'info-tracknumber)))
"")
(emms-track-get track 'info-title)
(fmt (ambrevar/emms-time-for-display track) "]" " ["))))
((eq 'url type)
(emms-format-url-track-name (emms-track-name track)))
(t (concat (symbol-name type)
": " (emms-track-name track))))))
(setq emms-track-description-function 'ambrevar/emms-track-description-with-album)
(defun ambrevar/emms-tracks-duration (begin end)
"Display play time of tracks in region."
(interactive "r")
(if (not (use-region-p))
(message "%s" (emms-browser-track-duration
(car (emms-browser-tracks-at-point))))
(let* ((total-time)
(first-line (line-number-at-pos begin))
(last-line (line-number-at-pos end))
(count 0))
(setq total-time
(save-mark-and-excursion
(cl-loop for line from first-line to last-line
do (goto-line line)
for time = (emms-track-get (car (emms-browser-tracks-at-point))
'info-playing-time)
when time
do (cl-incf count)
when time
sum time)))
(message "%02d:%02d for %d tracks" (/ total-time 60) (% total-time 60)
count))))
(provide 'init-emms)