aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kazantsev <mk.fraggod@gmail.com>2021-06-19 15:42:41 +0500
committerfraggod@malediction <mk.fraggod@gmail.com>2021-06-19 15:42:41 +0500
commitb31db42c402c747342c85aa580b7c92bdd75fc7b (patch)
tree7bd6e90c07b8a53ad2d25293cdbce6d45e148e2b
parent1ce322a085b0852999b8569b1656a557c6c8bb33 (diff)
* emms-player-mpv.el: fix reconnect-playback-restart issue from d4d9171
Adds ability to send/queue batched commands, so that multiple commands can be re-queued after restarting dead mpv process, not just the last one, which was the problem with adding unpause command after loadfile.
-rw-r--r--emms-player-mpv.el77
1 files changed, 42 insertions, 35 deletions
diff --git a/emms-player-mpv.el b/emms-player-mpv.el
index bc5b2d8..b562147 100644
--- a/emms-player-mpv.el
+++ b/emms-player-mpv.el
@@ -571,24 +571,35 @@ HANDLER func will be called with decoded response JSON as (handler data err),
where ERR will be either nil on \"success\", 'connection-error or whatever is in JSON.
If HANDLER is nil, default `emms-player-mpv-ipc-req-error-printer'
will be used to at least log errors.
+Multiple commands can be batched in one list as '(batch (cmd1 . handler1) ...),
+in which case common HANDLER argument is ignored.
PROC can be specified to avoid `emms-player-mpv-ipc' call (e.g. from sentinel/filter funcs)."
- (let
- ((req-id (emms-player-mpv-ipc-id-get))
- (req-proc (or proc (emms-player-mpv-ipc)))
- (handler (or handler #'emms-player-mpv-ipc-req-error-printer)))
- (unless emms-player-mpv-ipc-req-table
- (setq emms-player-mpv-ipc-req-table (make-hash-table)))
- (let ((json (concat (json-encode (list :command cmd :request_id req-id))
- "\n")))
- (emms-player-mpv-debug-msg "json >> %s" json)
- (condition-case _err
- ;; On any disconnect, assume that mpv process is to blame and force restart.
- (process-send-string req-proc json)
- (error
- (emms-player-mpv-proc-stop)
- (funcall handler nil 'connection-error)
- (setq handler nil))))
- (when handler (puthash req-id handler emms-player-mpv-ipc-req-table))))
+ (dolist
+ (cmd-and-handler
+ (if (and (listp cmd)
+ (eq (car cmd)
+ 'batch))
+ (cdr cmd)
+ `((,cmd . ,handler))))
+ (cl-destructuring-bind (cmd . handler)
+ cmd-and-handler
+ (let
+ ((req-id (emms-player-mpv-ipc-id-get))
+ (req-proc (or proc (emms-player-mpv-ipc)))
+ (handler (or handler #'emms-player-mpv-ipc-req-error-printer)))
+ (unless emms-player-mpv-ipc-req-table
+ (setq emms-player-mpv-ipc-req-table (make-hash-table)))
+ (let ((json (concat (json-encode (list :command cmd :request_id req-id))
+ "\n")))
+ (emms-player-mpv-debug-msg "json >> %s" json)
+ (condition-case _err
+ ;; On any disconnect, assume that mpv process is to blame and force restart.
+ (process-send-string req-proc json)
+ (error
+ (emms-player-mpv-proc-stop)
+ (funcall handler nil 'connection-error)
+ (setq handler nil))))
+ (when handler (puthash req-id handler emms-player-mpv-ipc-req-table))))))
(defun emms-player-mpv-ipc-req-resolve (req-id data err)
"Run handler-func for specified req-id."
@@ -764,7 +775,9 @@ Called before `emms-player-mpv-event-functions' and does same thing as these hoo
(defun emms-player-mpv-cmd (cmd &optional handler)
"Send mpv command to process/connection if both are running,
or otherwise schedule start/connect and set
-`emms-player-mpv-ipc-start-track' for `emms-player-mpv-ipc-sentinel'."
+`emms-player-mpv-ipc-connect-command' for `emms-player-mpv-ipc-sentinel'.
+Multiple commands can be batched in one list as '(batch (cmd1 . handler1) ...),
+in which case common HANDLER argument is ignored."
(setq emms-player-mpv-ipc-connect-command nil)
(let ((proc (emms-player-mpv-ipc)))
(if proc
@@ -795,17 +808,6 @@ and will be removed in a future EMMS version."
(memq (emms-track-type track)
'(file url streamlist playlist)))
-(defun emms-player-mpv-start-error-handler (mpv-cmd _mpv-data mpv-error)
- "Playback-restart error handler for `emms-player-mpv-cmd',
-to restart/reconnect-to mpv and re-run MPV-CMD,
-if there was any issue when trying to start it initially."
- (if (eq mpv-error 'connection-error)
- ;; Reconnect and restart playback if current connection fails (e.g. mpv crash)
- (emms-player-mpv-cmd mpv-cmd
- (lambda (_mpv-data _mpv-error)
- (emms-player-mpv-cmd mpv-cmd)
- (emms-player-mpv-cmd '(set pause no))))))
-
(defun emms-player-mpv-start (track)
(setq emms-player-mpv-stopped nil)
(emms-player-mpv-proc-playing nil)
@@ -821,12 +823,17 @@ if there was any issue when trying to start it initially."
track-name)
(emms-player-started emms-player-mpv))
(let*
- ((start-cmd (list (if track-is-playlist 'loadlist 'loadfile)
- track-name 'replace))
- (start-func (lambda ()
- (emms-player-mpv-cmd start-cmd
- (apply-partially #'emms-player-mpv-start-error-handler start-cmd))
- (emms-player-mpv-cmd '(set pause no)))))
+ ((play-cmd
+ `(batch
+ ((,(if track-is-playlist 'loadlist 'loadfile)
+ ,track-name replace))
+ ((set pause no))))
+ (start-func
+ ;; Try running play-cmd and retry it on connection failure, e.g. if mpv died
+ (apply-partially 'emms-player-mpv-cmd play-cmd
+ (lambda (_mpv-data mpv-error)
+ (when (eq mpv-error 'connection-error)
+ (emms-player-mpv-cmd play-cmd))))))
(if emms-player-mpv-ipc-stop-command
(setq emms-player-mpv-ipc-stop-command start-func)
(funcall start-func))))))