;;; 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) (emms-mode-line-disable) (defun ambrevar/emms-playing-time-toggle () (if (or (derived-mode-p 'emms-browser-mode) (derived-mode-p 'emms-playlist-mode)) (emms-playing-time-mode-line) (emms-playing-time-restore-mode-line))) (add-hook 'window-state-change-hook 'ambrevar/emms-playing-time-toggle) (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) (require 'emms-info-libtag) (if (executable-find emms-info-libtag-program-name) (progn (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. ;; TODO: Seems to be quite broken (does not resume at the right time + sometimes ;; remains silent). Anyways, it's not so useful, remove? ;; (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") (cl-flet ((track-at-point () (if (eq major-mode 'emms-playlist-mode) (emms-playlist-track-at) (car (emms-browser-tracks-at-point))))) (if (not (use-region-p)) (message "%s" (emms-browser-track-duration (track-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 (track-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)