--- lisp/emms-player-mpv.el | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 lisp/emms-player-mpv.el diff --git a/lisp/emms-player-mpv.el b/lisp/emms-player-mpv.el new file mode 100644 index 0000000..dbfba7d --- /dev/null +++ b/lisp/emms-player-mpv.el @@ -0,0 +1,120 @@ +;;; emms-player-mpv.el --- mpv support for EMMS + +;; Copyright (C) 2017 Free Software Foundation, Inc. + +;; Authors: Petteri Hintsanen + +;; This file is part of EMMS. + +;; EMMS 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. + +;; EMMS 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 EMMS; if not, write to the Free Software Foundation, +;; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This provides a player that uses mpv (http://mpv.io). It supports +;; pause and seeking. + +;;; Code: + +(require 'emms-player-simple) + +(defvar emms-player-mpv-socket-file nil + "The local socket listened by mpv.") + +(defvar emms-player-mpv-network-process nil + "Connection to the local socket of the current player.") + +(define-emms-simple-player mpv '(file url) + (concat "\\`\\(http[s]?\\|mms\\)://\\|" + (apply #'emms-player-simple-regexp + emms-player-base-format-list)) + "mpv" "--audio-display=no" "--no-terminal") + +(define-emms-simple-player mpv-playlist '(streamlist) + "\\`http[s]?://" + "mpv" "--audio-display=no" "--no-terminal" "--playlist") + +(defun emms-player-mpv-delete-socket-file () + "Delete an obsolete socket file. +This function is added to several hooks to prevent stray socket +files." + (ignore-errors (delete-file emms-player-mpv-socket-file)) + (setq emms-player-mpv-socket-file nil)) + +(defun emms-player-mpv-ipc-process () + "Return a connection to the IPC socket of the current player. +Return an existing connection if one exists. Otherwise set up a +new connection and return it." + (if (process-live-p emms-player-mpv-network-process) + emms-player-mpv-network-process + (setq emms-player-mpv-network-process + (make-network-process :name "mpv-ipc" + :family 'local + :remote emms-player-mpv-socket-file)))) + +(defun emms-player-mpv-start-with-socket (track) + "Start the player process." + (setq emms-player-mpv-socket-file (make-temp-file "mpv-socket")) + (emms-player-simple-start + (emms-track-name track) + 'emms-player-mpv + emms-player-mpv-command-name + (append emms-player-mpv-parameters + (list (concat "--input-ipc-server=" + emms-player-mpv-socket-file))))) + +(defun emms-player-mpv-pause () + (process-send-string + (emms-player-mpv-ipc-process) + "pause\n")) + +(defun emms-player-mpv-seek (sec) + (process-send-string + (emms-player-mpv-ipc-process) + (format "seek %d\n" sec))) + +(defun emms-player-mpv-seek-to (sec) + (process-send-string + (emms-player-mpv-ipc-process) + (format "seek %d absolute\n" sec))) + +(emms-player-set emms-player-mpv + 'start + 'emms-player-mpv-start-with-socket) + +(emms-player-set emms-player-mpv + 'pause + 'emms-player-mpv-pause) + +(emms-player-set emms-player-mpv + 'resume + 'emms-player-mpv-pause) + +(emms-player-set emms-player-mpv + 'seek + 'emms-player-mpv-seek) + +(emms-player-set emms-player-mpv + 'seek-to + 'emms-player-mpv-seek-to) + +(add-hook 'emms-player-stopped-hook + 'emms-player-mpv-delete-socket-file) +(add-hook 'emms-player-finished-hook + 'emms-player-mpv-delete-socket-file) +(add-hook 'kill-emacs-hook + 'emms-player-mpv-delete-socket-file) + +(provide 'emms-player-mpv) +;;; emms-player-mpv.el ends here -- 2.11.0