;; jao-emms-info-track.el -- utilities to show tracks -*- lexical-binding:t; -*- ;; Copyright (C) 2009, 2010, 2013, 2017, 2020 Jose Antonio Ortega Ruiz ;; Author: Jose Antonio Ortega Ruiz ;; Start date: Sat Jul 04, 2009 13:47 ;; This file is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 3 of the License, or ;; (at your option) any later version. ;; This file is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Code: (require 'emms) (require 'emms-tag-editor) (require 'jao-osd) (require 'jao-emms) (require 'jao-minibuffer) (defgroup jao-emms-faces nil "Faces" :group 'faces :group 'jao-emms) (defface jao-emms-font-lock-album '((t (:foreground "lightgoldenrod2"))) "Album name in EMMS track message." :group 'jao-emms-faces) (defface jao-emms-font-lock-track '((t (:bold t))) "Track number in EMMS track message." :group 'jao-emms-faces) (defface jao-emms-font-lock-title '((t (:foreground "dodgerblue2"))) "Track title in EMMS track message." :group 'jao-emms-faces) (defface jao-emms-font-lock-artist '((t (:foreground "dodgerblue3"))) "Artist name in EMMS track message." :group 'jao-emms-faces) (defcustom jao-emms-show-osd-p nil "Whether to show osd notices on track change" :group 'jao-emms) (defun jao-emms-info-track-stream (track) "Return track info for streams" (let ((name (emms-track-name track)) (title (or (emms-track-get track 'title nil) (car (emms-track-get track 'metadata nil))))) (format "♪ %s (%s)" title (if title (emms-track-type track) name)))) (defsubst jao--put-face (str face) (put-text-property 0 (length str) 'face face str) str) (defun jao-emms--to-number (x) (or (and (numberp x) x) (and (stringp x) (string-match "\\`\\(:?[0-9]+\\)" x) (string-to-number (match-string 1 x))))) (defun jao-emms-info-track-file (track &optional lapsed plen titlesep) "Return a description of the current track." (let ((no (jao-emms--to-number (emms-track-get track 'info-tracknumber "0"))) (time (emms-track-get track 'info-playing-time)) (artist (emms-track-get track 'info-artist "")) (composer (emms-track-get track 'info-composer nil)) (title (emms-track-get track 'info-title "")) (album (emms-track-get track 'info-album)) (last-played (or (emms-track-get track 'last-played) '(0 0 0))) (play-count (or (emms-track-get track 'play-count) 0)) (playlength (if plen (format "/%02d" (string-to-number plen)) ""))) (if (or (not title) (not album)) (emms-track-simple-description track) (format "♪ [%s%s] %s%s%s%s%s%s" (if lapsed (format "%02d:%02d/" (/ lapsed 60) (mod lapsed 60)) "") (if time (format "%02d:%02d" (/ time 60) (mod time 60)) "") (jao--put-face artist 'jao-emms-font-lock-artist) (jao--put-face (if composer (format " [%s]" composer) "") 'jao-emms-font-lock-artist) (jao--put-face (if album (format " (%s)" album) " *") 'jao-emms-font-lock-album) (or titlesep "") (jao--put-face (if (zerop no) "" (format " %02d%s " no playlength)) 'jao-emms-font-lock-track) (jao--put-face title 'jao-emms-font-lock-title))))) ;;;###autoload (defun jao-emms-info-track-description (track &optional lapsed plen tsep) (if (memq (emms-track-type track) '(streamlist url)) (jao-emms-info-track-stream track) (jao-emms-info-track-file track lapsed plen tsep))) ;;;###autoload (defun jao-emms-toggle-osd () (interactive) (setq jao-emms-show-osd-p (not jao-emms-show-osd-p)) (message "Emms OSD %s" (if jao-emms-show-osd-p "enabled" "disabled"))) (defvar jao-emms-show-icon nil) (defun jao-emms--with-mpd-track (callback) (emms-player-mpd-get-status nil (lambda (_ st) (let* ((lapsed (jao-emms--to-number (cdr (assoc "time" st)))) (plen (cdr (assoc "playlistlength" st))) (song (jao-emms--to-number (cdr (assoc "song" st)))) (track (emms-playlist-current-selected-track))) (when (and track song) (emms-track-set track 'info-tracknumber (1+ song))) (funcall callback track lapsed plen))))) ;;;###autoload (defun jao-emms-show-osd () (interactive) (jao-emms--with-mpd-track (lambda (track lapsed play-len) (let* ((sep "~~~~~") (s (jao-emms-info-track-description track lapsed play-len sep)) (s (substring-no-properties s 2)) (cs (split-string s sep))) (jao-notify (cadr cs) (car cs) jao-emms-show-icon))))) (defun jao-emms-show-osd-hook () (interactive) (when jao-emms-show-osd-p (jao-emms-show-osd))) (defun jao-emms-install-i3dv2 () (add-to-list 'emms-tag-editor-tagfile-functions '("mp3" "id3v2" ((info-artist . "a") (info-title . "t") (info-album . "A") (info-tracknumber . "T") (info-year . "y") (info-genre . "g") (info-composer . "-TCOM") (info-note . "c"))))) (defvar jao-emms-echo-string "") (defun jao-emms-update-echo-string () (if (and emms-player-playing-p (not emms-player-paused-p)) (jao-emms--with-mpd-track (lambda (track _ play-len) (setq jao-emms-echo-string (jao-emms-info-track-description track nil play-len)) (jao-minibuffer-refresh))) (setq jao-emms-echo-string "") (jao-minibuffer-refresh))) (defun jao-emms-enable-minibuffer () (jao-minibuffer-add-variable 'jao-emms-echo-string t) (dolist (h '(emms-track-updated-functions emms-player-finished-hook emms-player-stopped-hook emms-player-started-hook emms-player-paused-hook)) (add-hook h #'jao-emms-update-echo-string))) ;;;###autoload (defun jao-emms-info-setup (&optional show-mini show-osd show-echo-line no-id3) (setq emms-track-description-function 'jao-emms-info-track-description) (setq jao-emms-show-osd-p show-osd) (add-hook 'emms-player-started-hook 'jao-emms-show-osd-hook) (when show-mini (jao-emms-enable-minibuffer)) (unless show-echo-line (eval-after-load 'emms-player-mpd '(remove-hook 'emms-player-started-hook 'emms-player-mpd-show))) (unless no-id3 (jao-emms-install-i3dv2))) (provide 'jao-emms-info-track) ;;; jao-emms-info-track.el ends here