summaryrefslogtreecommitdiffhomepage
path: root/lib/media
diff options
context:
space:
mode:
Diffstat (limited to 'lib/media')
-rw-r--r--lib/media/jao-lyrics.el17
-rw-r--r--lib/media/jao-mpc.el266
-rw-r--r--lib/media/jao-mpris.el49
-rw-r--r--lib/media/jao-random-album.el77
-rw-r--r--lib/media/jao-spt.el148
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