diff options
Diffstat (limited to 'lib/media')
| -rw-r--r-- | lib/media/jao-lyrics.el | 17 | ||||
| -rw-r--r-- | lib/media/jao-mpc.el | 266 | ||||
| -rw-r--r-- | lib/media/jao-mpris.el | 49 | ||||
| -rw-r--r-- | lib/media/jao-random-album.el | 77 | ||||
| -rw-r--r-- | lib/media/jao-spt.el | 148 |
5 files changed, 266 insertions, 291 deletions
diff --git a/lib/media/jao-lyrics.el b/lib/media/jao-lyrics.el index 5008fae..c00a913 100644 --- a/lib/media/jao-lyrics.el +++ b/lib/media/jao-lyrics.el @@ -1,6 +1,6 @@ -;; jao-lyrics.el -- simple show lyrics using glyrc +;; jao-lyrics.el -- simple show lyrics using glyrc -*- lexical-binding: t; -*- -;; Copyright (C) 2009, 2010, 2017, 2019, 2020, 2022 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009, 2010, 2017, 2019, 2020, 2022, 2026 Jose Antonio Ortega Ruiz ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org> ;; Start date: Sat Jul 04, 2009 13:41 @@ -76,7 +76,7 @@ (use-local-map jao-lyrics-mode-map) (setq major-mode 'jao-lyrics-mode) (setq mode-name "lyrics") - (toggle-read-only 1)) + (read-only-mode)) (defun jao-lyrics-buffer () (or (get-buffer "*Lyrics*") @@ -99,8 +99,13 @@ "^\\(CreditsWritten by:\\|External linksNominate\\)" nil t) (beginning-of-line) (kill-region (point) (point-max))) - (replace-string "
" "" nil (point-min) (point-max)) - (replace-string "\\'" "'" nil (point-min) (point-max)) + (goto-char (point-min)) + (save-excursion + (while (search-forward "
" nil t) + (replace-match ""))) + (save-excursion + (while (search-forward "\\'" nil t) + (replace-match "'"))) (save-buffer))) (defun jao-lyrics--download (artist title &optional noartist) @@ -115,7 +120,7 @@ (jao-lyrics--clean-download fn) (prog1 (jao-lyrics--get-cached artist title) (message nil)))) -(defvar jao-lyrics-info-function) +(defvar jao-lyrics-info-function nil) (defvar-local jao-lyrics--info-function nil) ;;;###autoload diff --git a/lib/media/jao-mpc.el b/lib/media/jao-mpc.el index dc8ff6d..23b2dda 100644 --- a/lib/media/jao-mpc.el +++ b/lib/media/jao-mpc.el @@ -1,6 +1,6 @@ ;;; jao-mpc.el --- Using mpc to interact with mpd -*- lexical-binding: t; -*- -;; Copyright (C) 2021, 2022 jao +;; Copyright (C) 2021, 2022, 2024, 2025, 2026 jao ;; Author: jao <mail@jao.io> ;; Keywords: convenience @@ -30,6 +30,8 @@ (require 'jao-themes) (require 'jao-lyrics) (require 'jao-random-album) +(require 'jao-notify) +(require 'jao-minibuffer) (defconst jao-mpc--albums "*MPC Albums*") (defconst jao-mpc--playlist "*MPC Playlist*") @@ -38,98 +40,130 @@ (defvar-local jao-mpc--port nil) (defun jao-mpc--cmd (cmd &optional port) - (let ((port (or port jao-mpc--port jao-mpc-port))) - (shell-command-to-string (format "mpc -p %s %s" port cmd)))) + (let* ((port (or port jao-mpc--port jao-mpc-port)) + (r (shell-command-to-string (format "mpc -p %s %s" port cmd)))) + (replace-regexp-in-string "^\\(warning: \\)?MPD .+\n" "" r))) + +(defun jao-mpc--fformat (fields) + (mapconcat (lambda (f) (format "%s:::%%%s%%" f f)) fields "\n")) (defconst jao-mpc--fields - '(artist album composer originaldate genre title track position time name)) + '(artist album composer originaldate genre title track position time name + file)) (defconst jao-mpc--stfmt - (mapconcat (lambda (f) (format "%s:::%%%s%%" f f)) jao-mpc--fields "\n")) + (jao-mpc--fformat + '(artist album composer originaldate genre title track name file))) + +(defconst jao-mpc--stfmtt + (jao-mpc--fformat '(currenttime totaltime percenttime songpos length))) + +(defmacro jao-mpc--parse-fields (res-str res) + `(dolist (s (split-string ,res-str "\n" t " ") ,res) + (when (string-match "\\(.+\\):::\\(.+\\)" s) + (push (cons (intern (match-string 1 s)) (match-string 2 s)) ,res)))) (defun jao-mpc--current (&optional port) (let ((s (jao-mpc--cmd (format "-f '%s' current" jao-mpc--stfmt) port)) + (st (jao-mpc--cmd (format "status '%s'" jao-mpc--stfmtt))) (res)) - (dolist (s (split-string s "\n" t " ") res) - (when (string-match "\\(.+\\):::\\(.+\\)" s) - (push (cons (intern (match-string 1 s)) (match-string 2 s)) res))))) - -(defun jao-mpc--playing-p (&optional port) - (not (string-blank-p (jao-mpc--cmd "status|grep '\\[playing\\]'" port)))) - -(defun jao-mpc--queue-len (&optional port) - (string-to-number (jao-mpc--cmd "playlist|wc -l" port))) - -(defsubst jao--put-face (str face) - (put-text-property 0 (length str) 'face face str) - str) - -(defun jao-mpc--current-str (&optional port current len) - (let* ((current (or current (jao-mpc--current port))) - (len (or len (jao-mpc--queue-len port))) - (title (alist-get 'title current (alist-get 'name current ""))) - (album (alist-get 'album current)) - (artist (alist-get 'artist current)) - (composer (alist-get 'composer current)) - (no (string-to-number (alist-get 'position current "0"))) - (time (alist-get 'time current ""))) - (format "> %s%s %s%s%s%s" ;; - (jao--put-face (if (zerop no) "" (format "%02d/%s " no len)) - 'jao-themes-f02) - (jao--put-face title 'jao-themes-f00) - (jao--put-face artist 'jao-themes-f01) - (jao--put-face (if composer (format " [%s]" composer) "") - 'jao-themes-f01) - (jao--put-face (if album (format " (%s)" album) "") 'jao-themes-f11) - (if (string-blank-p time) - "" - (jao--put-face (format " [%s]" time) 'jao-themes-dimm))))) + (jao-mpc--parse-fields s res) + (jao-mpc--parse-fields st res))) + +(defsubst jao-mpc-status (&optional port) + (string-trim (jao-mpc--cmd "status %state%" port))) + +(defsubst jao-mpc-playing-p (&optional port) + (string-prefix-p "playing" (jao-mpc-status port))) + +(defsubst jao-mpc--queue-len (&optional port) + (string-to-number (jao-mpc--cmd "status %length%" port))) + +(defun jao-mpc--current-timestr (playing-times &optional current) + (let* ((current (or current (jao-mpc--current))) + (time (alist-get 'totaltime current "")) + (remaining (jao-mpc-playlist-duration-string current))) + (if playing-times + (format "%s/%s%s - %s" + (alist-get 'currenttime current "") + time + (alist-get 'percenttime current "") + remaining) + (format "%s - %s" time remaining)))) + +(defun jao-mpc--current-str (&optional port times) + (if-let* ((current (jao-mpc--current port)) + (title (alist-get 'title current (alist-get 'name current)))) + (let ((len (alist-get 'length current "0")) + (album (alist-get 'album current)) + (artist (alist-get 'artist current)) + (composer (alist-get 'composer current)) + (no (string-to-number (alist-get 'songpos current "0"))) + (tims (concat " [" (jao-mpc--current-timestr times current) "]"))) + (format "%s%s %s%s%s%s" ;; + (jao--put-face (if (zerop no) "" (format "%d/%s " no len)) + 'jao-themes-f02) + (jao--put-face (or title "") 'jao-themes-f00) + (jao--put-face (or artist "") 'jao-themes-f01) + (jao--put-face (if composer (format " [%s]" composer) "") + 'jao-themes-f01) + (jao--put-face (if album (format " (%s)" album) "") + 'jao-themes-f11) + (jao--put-face tims (if times 'jao-themes-f00 'jao-themes-dimm)))) + "")) (defvar jao-mpc-minibuffer-str "") (defun jao-mpc--set-current-str (&optional port) - (setq jao-mpc-minibuffer-str - (if (jao-mpc--playing-p port) - (jao-mpc--current-str port) - (when (and (null port) jao-random-album-p (not (jao-mpc--current))) - (jao-random-album-next)) - "")) + (let ((status (or (jao-mpc-status port) ""))) + (setq jao-mpc-minibuffer-str + (if (string= "playing" status) (jao-mpc--current-str port) "")) + (when (and jao-random-album-active + (or (string= status "stopped") (string= status "paused")) + (string= "0\n" (jao-mpc--cmd "status %songpos%" port))) + (jao-random-album-next))) (jao-minibuffer-refresh)) (defvar jao-mpc--idle-procs nil) (defun jao-mpc--idle-loop (&optional port) - (when-let (proc (alist-get port jao-mpc--idle-procs)) + (when-let* ((proc (alist-get port jao-mpc--idle-procs))) (ignore-errors (kill-process proc))) (setf (alist-get port jao-mpc--idle-procs nil t) (make-process :name (format "jao-mpc-idleloop (%s)" port) :buffer nil :noquery t - :command `("mpc" "-p" ,(format "%s" (or port jao-mpc-port)) - "idleloop" "player") - :filter (lambda (_p _s) (jao-mpc--set-current-str port))))) + :command + `("mpc" "-p" ,(format "%s" (or port jao-mpc-port)) + "idleloop" "player") + :filter (lambda (_p _s) + (jao-mpc--set-current-str port))))) + +(defvar jao-mpc--browser-port nil) (define-derived-mode jao-mpc-albums-mode fundamental-mode "MPC Albums" "Mode to display the list of albums known by mpd." (read-only-mode -1) (delete-region (point-min) (point-max)) - (insert (jao-mpc--cmd "list album")) + (insert (jao-mpc--cmd "list album" jao-mpc--browser-port)) (goto-char (point-min)) (read-only-mode 1)) (defun jao-mpc--album-buffer () - (if-let (b (get-buffer jao-mpc--albums)) + (if-let* ((b (get-buffer jao-mpc--albums))) b (with-current-buffer (get-buffer-create jao-mpc--albums) (jao-mpc-albums-mode) (current-buffer)))) -(defun jao-mpc--add-and-play (&optional album) +(defun jao-mpc--add-and-play (&optional album port idp) (interactive) - (let ((album (or album (string-trim (thing-at-point 'line))))) - (jao-mpc--cmd "clear") - (jao-mpc--cmd (format "findadd album \"%s\"" album)) - (jao-mpc--cmd "play"))) + (let ((a (or album (string-trim (thing-at-point 'line)))) + (p (or port jao-mpc--browser-port))) + (jao-mpc--cmd "clear" p) + (jao-mpc--cmd (if idp (concat "add " a) (format "findadd album \"%s\"" a)) + p) + (jao-mpc--cmd "play" p))) (define-key jao-mpc-albums-mode-map (kbd "n") #'next-line) (define-key jao-mpc-albums-mode-map (kbd "p") #'previous-line) @@ -161,7 +195,8 @@ (define-key jao-mpc-playlist-mode-map (kbd "n") #'next-line) (define-key jao-mpc-playlist-mode-map (kbd "p") #'previous-line) (define-key jao-mpc-playlist-mode-map (kbd "q") #'bury-buffer) -(define-key jao-mpc-playlist-mode-map (kbd ".") #'jao-mpc--playlist-goto-current) +(define-key jao-mpc-playlist-mode-map (kbd ".") + #'jao-mpc--playlist-goto-current) (define-key jao-mpc-playlist-mode-map (kbd "RET") #'jao-mpc--playlist-play) (define-key jao-mpc-playlist-mode-map (kbd "C") #'jao-mpc-clear) @@ -170,15 +205,52 @@ (let ((jao-mpc-port (or port jao-mpc-port))) (jao-mpc-playlist-mode)) (current-buffer))) +(defun jao-mpc--with-delayed-random-album (cmd port) + (let ((st jao-random-album-active)) + (setq jao-random-album-active nil) + (jao-mpc--cmd cmd port) + (accept-process-output nil 0.5) + (setq jao-random-album-active st))) + +(defun jao-mpc--time-to-secs (str) + (if-let* ((ts (string-split (or str "") ":")) + (mins (string-to-number (car ts))) + (secs (string-to-number (or (cadr ts) "0")))) + (+ secs (* 60 mins)) + 0)) + +(defun jao-mpc--playlist-duration (&optional current port) + (let* ((current (or current (jao-mpc--current))) + (times (string-split (jao-mpc--cmd "playlist -f %time%") nil t)) + (offset (- (string-to-number (alist-get 'songpos current "1")) 1)) + (times (drop offset times)) + (total (- (jao-mpc--time-to-secs (alist-get 'currenttime current))))) + (dolist (time times total) + (setq total (+ total (jao-mpc--time-to-secs time)))))) + +;;;###autoload +(defun jao-mpc-playlist-duration-string (&optional current) + (format-seconds "%hh %mm %ss" (jao-mpc--playlist-duration current))) + +;;;###autoload +(defun jao-mpc-show-playlist-duration () + (interactive) + (message (jao-mpc-playlist-duration-string))) + ;;;###autoload (defun jao-mpc-stop (&optional port) (interactive) - (jao-mpc--cmd "stop" port)) + (jao-mpc--with-delayed-random-album "stop" port)) ;;;###autoload (defun jao-mpc-toggle (&optional port) (interactive) - (jao-mpc--cmd "toggle" port)) + (jao-mpc--with-delayed-random-album "toggle" port)) + +;;;###autoload +(defun jao-mpc-pause (&optional port) + (interactive) + (jao-mpc--with-delayed-random-album "pause" port)) ;;;###autoload (defun jao-mpc-play (&optional port) @@ -208,7 +280,29 @@ ;;;###autoload (defun jao-mpc-echo-current (&optional port) (interactive) - (jao-notify (jao-mpc--current-str port))) + (message "%s" (jao-mpc--current-str port t))) + +;;;###autoload +(defun jao-mpc-echo-current-times (&optional _port) + (interactive) + (message "Playing time: %s" (jao-mpc--current-timestr t))) + +;;;###autoload +(defun jao-mpc-notify (&optional _port) + (interactive) + (when-let* ((current (jao-mpc--current))) + (let* ((artist (or (alist-get 'artist current) "Anonymous")) + (title (or (alist-get 'title current) + (when-let* ((tl (alist-get 'file current))) + (file-name-base tl)) + "")) + (album (or (alist-get 'album current) "")) + (track (or (alist-get 'track current) "")) + (times (jao-mpc--current-timestr t current))) + (jao-notify (format "%s -- %s" artist times) + (format "%s %s" track title) + jao-notify-audio-icon + album)))) ;;;###autoload (defun jao-mpc-add-url (url) @@ -216,9 +310,33 @@ (jao-mpc--cmd (format "add %s" url))) ;;;###autoload -(defun jao-mpc-show-albums () +(defun jao-mpc-add-or-play-url (url &optional play) + "Add the given URL to mpc's playing list, or just play it." + (let ((p (or play (yes-or-no-p (format "Play %s right now?" url))))) + (when p (jao-mpc-clear)) + (jao-mpc-add-url url) + (if p (jao-mpc-play) (message "%s added to mpc queue" url)))) + +(defvar jao-mpc-stream-urls + '(("classic fm" . "http://media-ice.musicradio.com:80/ClassicFMMP3") + ("wcpe" . "http://audio-mp3.ibiblio.org:8000/wcpe.mp3") + ("davide of mimic" . "http://streaming01.zfast.co.uk:8018/stream") + ("cinemix" . "http://94.23.51.96:8000") ;; 209.9.238.4:6022 209.9.238.4:6046 + ("bbc gold" . "http://media-ice.musicradio.com:80/GoldMP3") + ("irish gold" . "http://icecast2.rte.ie/gold"))) + +;;;###autoload +(defun jao-mpc-play-stream () + "Select a predefined stream URL and add or play it in mpc." + (interactive) + (let ((s (completing-read "Stream: " jao-mpc-stream-urls))) + (jao-mpc-add-or-play-url (cdr (assoc s jao-mpc-stream-urls)) t))) + +;;;###autoload +(defun jao-mpc-show-albums (&optional port) "Show album list." (interactive) + (setq jao-mpc--browser-port port) (pop-to-buffer (jao-mpc--album-buffer))) ;;;###autoload @@ -239,35 +357,35 @@ (defun jao-mpc-connect (&optional port) (interactive) (jao-mpc--idle-loop port) - (when (jao-mpc--playing-p port) (jao-mpc--set-current-str port))) + (when (jao-mpc-playing-p port) (jao-mpc--set-current-str port))) ;;;###autoload (defun jao-mpc-setup (&optional secondary-port priority) (setq jao-lyrics-info-function #'jao-mpc-lyrics-track-data) (jao-random-album-setup #'jao-mpc--album-buffer #'jao-mpc--add-and-play - #'jao-mpc-stop - jao-notify-audio-icon) - (jao-mpc-connect) + #'jao-mpc-stop) + (let ((jao-random-album-active nil)) (jao-mpc-connect)) (when secondary-port (jao-mpc-connect secondary-port)) (when priority (if (> priority 0) (jao-minibuffer-add-variable 'jao-mpc-minibuffer-str priority) (jao-minibuffer-add-msg-variable 'jao-mpc-minibuffer-str (- priority))))) -(defvar jao-mpc--album-titles nil) (defconst jao-mpc--albums-cmd "-f '%album% - %artist%' find \"(ALBUM =~ '.*')\" | uniq") +(defconst jao-mpc--simple-albums-cmd "list album") ;;;###autoload -(defun jao-mpc-select-album (refresh) - (interactive "P") - (let ((albums (or (and (not refresh) jao-mpc--album-titles) - (setq jao-mpc--album-titles - (split-string (jao-mpc--cmd jao-mpc--albums-cmd) - "\n" t))))) - (when-let (album (completing-read "Play album: " albums nil t)) - (jao-mpc--add-and-play (car (split-string album "-" t " ")))))) +(defun jao-mpc-select-album (&optional port) + (interactive) + (let* ((albums-str (jao-mpc--cmd jao-mpc--albums-cmd port)) + (albums-str (if (string= "" albums-str) + (jao-mpc--cmd jao-mpc--simple-albums-cmd port) + albums-str)) + (albums (split-string albums-str "\n" t))) + (when-let* ((album (completing-read "Play album: " albums nil t))) + (jao-mpc--add-and-play (car (split-string album "-" t " ")) port)))) (provide 'jao-mpc) ;;; jao-mpc.el ends here diff --git a/lib/media/jao-mpris.el b/lib/media/jao-mpris.el index 47a35a7..c120ae3 100644 --- a/lib/media/jao-mpris.el +++ b/lib/media/jao-mpris.el @@ -1,6 +1,6 @@ ;;; jao-mpris.el --- mpris players control -*- lexical-binding: t; -*- -;; Copyright (C) 2020, 2021, 2022 jao +;; Copyright (C) 2020, 2021, 2022, 2024, 2025, 2026 jao ;; Author: jao <mail@jao.io> ;; Keywords: multimedia @@ -51,10 +51,9 @@ (interactive "p") (jao-mpris-seek (- secs))) -(defun jao-mpris-vol (n) +(defun jao-mpris-vol (vol) (interactive "p") - (let ((secs (if (zerop n) 10 n))) - (jao-mpris--playerctl "volume" (format "%d" n)))) + (jao-mpris--playerctl "volume" (format "%d" (if (zerop vol) 10 vol)))) (defun jao-mpris-vol-down (n) (interactive "p") @@ -97,7 +96,7 @@ jao-mpris--current nil)) (defun jao-mpris--get (k &optional l) - (when-let (v (alist-get k (or l jao-mpris--current))) + (when-let* ((v (alist-get k (or l jao-mpris--current)))) (if (consp v) (car v) v))) (defun jao-mpris--set-current (k v) @@ -119,7 +118,7 @@ (duration (cond (duration duration) ((stringp len) len) ((numberp len) (jao-mpris--fmt-time (/ len 1e6) ""))))) - (format "> %s %s %s%s%s" + (format "%s %s %s%s%s" (jao--put-face (format "%s" (or track "")) 'jao-themes-f00) (jao--put-face (or title "") 'jao-themes-f01) (jao--put-face (or artist "") 'jao-themes-f11) @@ -130,6 +129,7 @@ (defun jao-mpris--track (&optional info) (let ((info (or info (jao-playerctl--status)))) + (setq jao-mpris--current info) (if (string= "Playing" (jao-mpris--get 'status info)) (setq jao-mpris-track-string (jao-mpris--format info)) (setq jao-mpris-track-string ""))) @@ -145,9 +145,10 @@ (interactive "P") (when refresh (jao-mpris--track)) (when jao-mpris--current - (jao-notify (format "%s%s" (if-let (s (jao-mpris--get 'status)) - (format "%s: " s) - "") + (jao-notify (format "%s%s" + (if-let* ((s (jao-mpris--get 'status))) + (format "%s: " s) + "") (jao-mpris--format))))) (defun jao-mpris-minibuffer-order (order) @@ -157,25 +158,25 @@ (defun jao-mpris--handler (iname properties &rest _args) (let ((inhibit-message t)) - (message "Received properties: %S from %s" properties iname)) - (when-let (md (caadr (assoc "Metadata" properties))) - (let ((tno (caadr (assoc "xesam:trackNumber" md))) - (tlt (caadr (assoc "xesam:title" md))) - (art (caadr (assoc "xesam:artist" md))) - (alb (caadr (assoc "xesam:album" md))) - (len (caadr (assoc "mpris:length" md)))) - (if (string= (or tlt "") "TIDAL") - (jao-mpris-reset) + (message "Received properties: %S from %s" properties iname) + (when-let* ((md (caadr (assoc "Metadata" properties)))) + (let ((tno (caadr (assoc "xesam:trackNumber" md))) + (tlt (caadr (assoc "xesam:title" md))) + (art (caadr (assoc "xesam:artist" md))) + (alb (caadr (assoc "xesam:album" md))) + (len (caadr (assoc "mpris:length" md)))) (jao-mpris--set-current 'track tno) (jao-mpris--set-current 'title tlt) (jao-mpris--set-current 'artist art) (jao-mpris--set-current 'album alb) - (jao-mpris--set-current 'length len)))) - (when-let (st (caadr (assoc "PlaybackStatus" properties))) - (jao-mpris--set-current 'status st) - (when (string= st "Stopped") - (dolist (k '(track title artist album length)) - (jao-mpris--del-current k)))) + (jao-mpris--set-current 'length len))) + (when-let* ((st (caadr (assoc "PlaybackStatus" properties)))) + (jao-mpris--set-current 'status st) + (when (string= st "Stopped") + (dolist (k '(track title artist album length)) + (jao-mpris--del-current k)))) + ;; (message "Current is: %S" jao-mpris--current) + ) (jao-mpris--track jao-mpris--current)) ;;;###autoload diff --git a/lib/media/jao-random-album.el b/lib/media/jao-random-album.el index 2800115..540f6a6 100644 --- a/lib/media/jao-random-album.el +++ b/lib/media/jao-random-album.el @@ -1,6 +1,6 @@ -;; jao-random-album.el -- play random albums +;; jao-random-album.el -- play random albums -*- lexical-binding: t; -*- -;; Copyright (C) 2009, 2010, 2017, 2018, 2019, 2021 Jose Antonio Ortega Ruiz +;; Copyright (C) 2009, 2010, 2017-2019, 2021-2022, 2024, 2026 Jose Antonio Ortega Ruiz ;; Author: Jose Antonio Ortega Ruiz <jao@gnu.org> ;; Start date: Sat Jul 04, 2009 13:06 @@ -18,38 +18,33 @@ ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see <http://www.gnu.org/licenses/>. -(require 'jao-notify) +(require 'multisession) -(defvar jao-random-album-p t) -(defvar jao-random-lines nil) -(defvar jao-random-lines-file (expand-file-name "~/.emacs.d/random-lines")) -(defvar jao-random-album-notify-p t) -(defvar jao-random-album-notify-icon jao-notify-audio-icon) +(defvar jao-random-album-active t) +(defvar jao-random-album-notify nil) (defvar jao-random-album-skip-lines 2) +(define-multisession-variable jao-random-lines nil) + +(defun jao-random-album--buffer-lines () + (let ((lines nil)) + (dotimes (n (1- (line-number-at-pos (point-max)))) + (when (> n jao-random-album-skip-lines) + (push (1+ n) lines))) + lines)) + (defun jao-random-lines () - (or jao-random-lines - (and (file-exists-p jao-random-lines-file) - (with-current-buffer - (find-file-noselect jao-random-lines-file) - (goto-char (point-min)) - (setq jao-random-lines (read (current-buffer))))) - (dotimes (n (1- (line-number-at-pos (point-max))) - jao-random-lines) - (when (> n jao-random-album-skip-lines) - (push (1+ n) jao-random-lines))))) - -(defun jao-random-lines-save () - (with-current-buffer (find-file-noselect jao-random-lines-file) - (delete-region (point-min) (point-max)) - (insert (format "%s\n" jao-random-lines)) - (save-buffer))) + (or (multisession-value jao-random-lines) + (jao-random-lines-save (jao-random-album--buffer-lines)))) + +(defun jao-random-lines-save (v) + (setf (multisession-value jao-random-lines) v)) (defun jao-goto-random-album () - (let* ((pos (random (length (jao-random-lines)))) - (line (nth pos jao-random-lines))) - (setq jao-random-lines (remove line jao-random-lines)) - (jao-random-lines-save) + (let* ((lines (jao-random-lines)) + (pos (random (length lines))) + (line (nth pos lines))) + (jao-random-lines-save (remove line lines)) (goto-line line))) @@ -58,41 +53,45 @@ (defvar jao-random-album-add-tracks-and-play) (defvar jao-random-album-stop) +;;;###autoload (defun jao-random-album-start () (interactive) - (setq jao-random-album-p t) + (setq jao-random-album-active t) (jao-random-album-next)) +;;;###autoload (defun jao-random-album-stop () (interactive) - (setq jao-random-album-p nil) + (setq jao-random-album-active nil) (funcall jao-random-album-stop)) +;;;###autoload (defun jao-random-album-toggle () (interactive) - (setq jao-random-album-p (not jao-random-album-p)) + (setq jao-random-album-active (not jao-random-album-active)) (message "Random album %s" - (if jao-random-album-p "enabled" "disabled"))) + (if jao-random-album-active "enabled" "disabled"))) +;;;###autoload (defun jao-random-album-next () (interactive) (with-current-buffer (get-buffer (funcall jao-random-album-buffer)) (jao-goto-random-album) (let ((album (string-trim (thing-at-point 'line)))) (funcall jao-random-album-add-tracks-and-play album) - (when jao-random-album-notify-p - (jao-notify album "Next album" jao-random-album-notify-icon))))) + (when jao-random-album-notify + (funcall jao-random-album-notify album))))) +;;;###autoload (defun jao-random-album-reset () (interactive) - (setq jao-random-lines nil) - (jao-random-lines-save)) + (jao-random-lines-save nil)) -(defun jao-random-album-setup (album-buffer add-and-play stop &optional icon) +;;;###autoload +(defun jao-random-album-setup (album-buffer add-and-play stop) (setq jao-random-album-buffer album-buffer jao-random-album-add-tracks-and-play add-and-play - jao-random-album-stop stop - jao-random-album-notify-icon icon)) + jao-random-album-stop stop)) (provide 'jao-random-album) diff --git a/lib/media/jao-spt.el b/lib/media/jao-spt.el deleted file mode 100644 index 4484ead..0000000 --- a/lib/media/jao-spt.el +++ /dev/null @@ -1,148 +0,0 @@ -;;; jao-spt.el --- Access to the spotify-tui CLI -*- lexical-binding: t; -*- - -;; Copyright (C) 2021, 2022 jao - -;; Author: jao <mail@jao.io> -;; Keywords: multimedia - -;; This program 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 program 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 <https://www.gnu.org/licenses/>. - -;;; Commentary: - -;; Simple spotifyd controls via the spt executable. - -;;; Code: - -(require 'jao-minibuffer) -(require 'jao-notify) - -(defvar jao-spt-bin (expand-file-name "~/bin/spt")) -(defvar jao-spt-format "'%s %t - %a [%r] %f'") -(defvar jao-spt-device nil) - -(defun jao-spt--exec-async (&rest args) - (let ((display-buffer-alist `((".*spt commands.*" display-buffer-no-window))) - (buff (get-buffer-create "* spt commands *"))) - (apply #'start-process "spt" buff jao-spt-bin args))) - -(defvar jao-spt--status-str "") - -(defun jao-spt--pb (&rest args) - (let* ((args (mapconcat #'identity args " ")) - (dev (if jao-spt-device (format "-d '%s'" jao-spt-device) "")) - (cmd (format "%s pb %s -f %s %s" jao-spt-bin args jao-spt-format dev)) - (st (string-trim (shell-command-to-string cmd)))) - (setq jao-spt--status-str (when (string-prefix-p "▶" st) st)) - (jao-minibuffer-refresh) - st)) - -(defun jao-spt--pb* (&rest args) - (message (apply 'jao-spt--pb args))) - -;;;###autoload -(defun jao-spt-play-uri (uri) - (jao-spt--exec-async "play" "--uri" uri)) - -;;;###autoload -(defun jao-spt-update-status () - (interactive) - (jao-spt--pb)) - -;;;###autoload -(defun jao-spt-toggle () - (interactive) - (jao-spt--pb* "-t")) - -;;;###autoload -(defun jao-spt-next () - (interactive) - (jao-spt--pb* "-n")) - -;;;###autoload -(defun jao-spt-previous () - (interactive) - (jao-spt--pb* "-p")) - -;;;###autoload -(defun jao-spt-like () - (interactive) - (jao-spt--pb* "--like")) - -;;;###autoload -(defun jao-spt-dislike () - (interactive) - (jao-spt--pb* "--dislike")) - -;;;###autoload -(defun jao-spt-toggle-shuffle () - (interactive) - (jao-spt--pb* "--shuffle")) - -;;;###autoload -(defun jao-spt-seek (&optional secs) - (interactive "p") - (let ((secs (if (zerop (or secs 0)) 10 secs))) - (jao-spt--pb* "--seek" (format "%d" secs)))) - -;;;###autoload -(defun jao-spt-seek-back (&optional secs) - (interactive "p") - (jao-spt-seek (- secs))) - -(defun jao-spt--get-vol (delta) - (let* ((jao-spt-format "%v") - (v (string-to-number (jao-spt--pb)))) - (number-to-string (max 0 (+ delta v))))) - -;;;###autoload -(defun jao-spt-vol (&optional n) - (interactive "p") - (let ((n (or n 10))) - (jao-spt--pb* "--volume" (jao-spt--get-vol (if (zerop n) 10 n))))) - -;;;###autoload -(defun jao-spt-vol-down (&optional n) - (interactive "p") - (jao-spt-vol (- (or n 10)))) - -;;;###autoload -(defun jao-spt-echo-current () - (interactive) - (let ((jao-notify-use-messages-p t)) - (jao-notify (jao-spt-update-status)))) - -;;;###autoload -(defun jao-spt-toggle-shuffle () - (interactive) - (jao-spt--pb* "--shuffle")) - -;;;###autoload -(defun jao-spt-set-up () - (jao-minibuffer-add-msg-variable 'jao-spt--status-str)) - -(defun jao-spt-lyrics-info () - (let* ((jao-spt-format "%a~~~%t") - (s (jao-spt--pb)) - (at (split-string s "~~~"))) - (cons (car at) (cadr at)))) - -(declare jao-show-lyrics "jao-lyrics") - -;;;###autoload -(defun jao-spt-show-lyrics (force) - (interactive "P") - (jao-show-lyrics force #'jao-spt-lyrics-info)) - -(provide 'jao-spt) -;;; jao-spt.el ends here |
