summaryrefslogtreecommitdiffhomepage
path: root/lib/media/jao-mpris.el
diff options
context:
space:
mode:
Diffstat (limited to 'lib/media/jao-mpris.el')
-rw-r--r--lib/media/jao-mpris.el139
1 files changed, 139 insertions, 0 deletions
diff --git a/lib/media/jao-mpris.el b/lib/media/jao-mpris.el
new file mode 100644
index 0000000..ad4b452
--- /dev/null
+++ b/lib/media/jao-mpris.el
@@ -0,0 +1,139 @@
+;;; jao-mpris.el --- mpris players control -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2020, 2021 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:
+
+;; controlling and showing info on mpris players
+
+;;; Code:
+
+(require 'dbus)
+(require 'jao-minibuffer)
+(require 'jao-emms-info-track)
+
+(defun jao-mpris--playerctl (&rest args)
+ (shell-command-to-string (format "playerctl %s"
+ (mapconcat #'shell-quote-argument args " "))))
+
+(defmacro jao-playerctl--def (name &rest args)
+ `(defun ,name () (interactive) (jao-mpris--playerctl ,@args)))
+
+(jao-playerctl--def jao-mpris-play-pause "play-pause")
+(jao-playerctl--def jao-mpris-next "next")
+(jao-playerctl--def jao-mpris-previous "previous")
+
+(defun jao-playerctl--status (&optional sep)
+ (let* ((sep (or sep " ||| "))
+ (fmt (mapconcat 'identity
+ '("{{status}}"
+ "{{xesam:trackNumber}}"
+ "{{title}}"
+ "{{artist}}"
+ "{{album}}"
+ "{{duration(mpris:length)}}")
+ sep))
+ (m (jao-mpris--playerctl "metadata" "--format" fmt)))
+ (split-string (car (split-string m "\n")) sep)))
+
+;;;###autoload
+(defun jao-mpris-status-times ()
+ (interactive)
+ (let ((m (jao-mpris--playerctl "metadata" "--format"
+ (concat "{{duration(position)}}/"
+ "{{duration(mpris:length)}}"))))
+ (jao-notify (string-trim m) "Playing")))
+
+(defvar jao-mpris--current nil)
+(defvar jao-mpris-track-string "")
+
+(defun jao-mpris--get (k &optional l)
+ (alist-get k (or l jao-mpris--current)))
+
+(defun jao-mpris--format (&optional info)
+ (let* ((artist (jao-mpris--get 'artist info))
+ (title (jao-mpris--get 'title info))
+ (track (jao-mpris--get 'track info))
+ (album (jao-mpris--get 'album info))
+ (len (jao-mpris--get 'length info))
+ (duration (cond ((stringp len) len)
+ ((numberp len) (jao-emms--fmt-time (/ len 1e6) "")))))
+ (format " %s %s %s%s%s"
+ (jao--put-face (format "%s" (or track "")) 'jao-emms-font-lock-track)
+ (jao--put-face title 'jao-emms-font-lock-title)
+ (jao--put-face artist 'jao-emms-font-lock-artist)
+ (jao--put-face (if album (format " (%s)" album) "")
+ 'jao-emms-font-lock-album)
+ (if duration (format " [%s]" duration) ""))))
+
+(defun jao-mpris--track (&optional info)
+ (let ((info (or info (jao-playerctl--status))))
+ (if (string= "Playing" (jao-mpris--get 'status info))
+ (setq jao-mpris-track-string (jao-mpris--format info))
+ (setq jao-mpris-track-string "")))
+ (jao-minibuffer-refresh))
+
+;;;###autoload
+(defun jao-mpris-artist-title ()
+ (when jao-mpris--current
+ (cons (jao-mpris--get 'artist) (jao-mpris--get 'title))))
+
+;;;###autoload
+(defun jao-mpris-show-osd ()
+ (interactive)
+ (when jao-mpris--current
+ (jao-notify (format "%s: %s" (jao-mpris--get 'status) (jao-mpris--format)))))
+
+(defun jao-mpris-minibuffer-order (order)
+ (jao-minibuffer-add-variable 'jao-mpris-track-string order))
+
+(defun jao-mpris--handler (iname properties &rest args)
+ (when properties
+ (let ((st (caadr (assoc "PlaybackStatus" properties)))
+ (md (caadr (assoc "Metadata" properties))))
+ (cond ((and st (not (string= "Playing" st)))
+ (setq jao-mpris-track-string "")
+ (setq jao-mpris--current
+ (cons (cons 'status st)
+ (assq-delete-all 'status jao-mpris--current)))
+ (jao-minibuffer-refresh)
+ (message "Music %s" st))
+ (md (let ((tno (caadr (assoc "xesam:trackNumber" md)))
+ (tlt (caadr (assoc "xesam:title" md)))
+ (art (caaadr (assoc "xesam:artist" md)))
+ (alb (caadr (assoc "xesam:album" md)))
+ (len (caadr (assoc "mpris:length" md))))
+ (setq jao-mpris--current
+ `((track . ,tno) (title . ,tlt)
+ (artist . ,art) (album . ,alb)
+ (length . ,len) (status . ,st)))
+ (jao-mpris--track jao-mpris--current)))))))
+
+;;;###autoload
+(defun jao-mpris-minibuffer-register (name &optional bus)
+ (dbus-register-signal (or bus :session)
+ name
+ "/org/mpris/MediaPlayer2"
+ "org.freedesktop.DBus.Properties"
+ "PropertiesChanged"
+ 'jao-mpris--handler))
+
+
+(provide 'jao-mpris)
+;;; jao-mpris.el ends here