Discussion:
[emms-help] [PATCH] mpv player
Petteri Hintsanen
2017-09-16 14:39:22 UTC
Permalink
Hello,

the attached patch adds support for mpv (http://mpv.io)
It is mostly copy-paste from emms-player-mplayer.el and
emms-player-simple.el

The main difference from mplayer is that mpv has local socket IPC
instead of stdin slave mode. Therefore the code generates a temporary
socket file for each player invocation, and carefully tries to remove
that file after player exits. A simpler version could use a fixed
socket file, maybe via defcustom, but then concurrent mpv processes
would get mixed up. I am not sure if that rather theoretical risk
warrants the complexity, though.

regards,
Petteri
Yoni Rabkin
2017-09-16 15:37:34 UTC
Permalink
Post by Petteri Hintsanen
Hello,
the attached patch adds support for mpv (http://mpv.io)
It is mostly copy-paste from emms-player-mplayer.el and
emms-player-simple.el
Thank you for doing this; we want to provide this in time for the next
release (4.4, slated for November).

Which version of mpv is currently being widely distributed? I know that
previous versions (for instance the version I have) don't yet support
the --input-ipc-server command. This also means that at the moment I
can't test this patch.

It would be good to check for the version and raise a error if the mpv
version is too old. I would also be happy for a documentation patch
which, among other things, describes what is the minimum version of mpv
that would work.

There is no need to support the older versions, as this is a problem
which will solve itself in time, and I think the --input-ipc-server
command is the way mpv will be moving forward.

The goal of all of this is to reduce frustration for people who will try
to use emms-player-mpv, but still have older versions of mpv for one
reason or another.
Post by Petteri Hintsanen
The main difference from mplayer is that mpv has local socket IPC
instead of stdin slave mode. Therefore the code generates a temporary
socket file for each player invocation, and carefully tries to remove
that file after player exits. A simpler version could use a fixed
socket file, maybe via defcustom, but then concurrent mpv processes
would get mixed up. I am not sure if that rather theoretical risk
warrants the complexity, though.
I would rather support the former over the latter, so the way you did it
is good.
Post by Petteri Hintsanen
---
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.
+
+
+;; 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.
+
+
+;; This provides a player that uses mpv (http://mpv.io). It supports
+;; pause and seeking.
+
+
+(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
--
"Cut your own wood and it will warm you twice"
Petteri Hintsanen
2017-09-16 19:59:24 UTC
Permalink
Post by Yoni Rabkin
Which version of mpv is currently being widely distributed? I know that
previous versions (for instance the version I have) don't yet support
the --input-ipc-server command. This also means that at the moment I
can't test this patch.
Unfortunately I have no idea which versions are being used. It seems
that mpv is a moving target, releasing new version every few months.
The project recommends to either build from sources, or use third party
distro packages instead of official distro packages.

This machine (Debian stable) has 0.23.0, which is relatively new. Well,
Debian 9 was released last June.

It looks like that in version 0.17.0 they changed the option from
--input-unix-socket to --input-ipc-server

https://github.com/mpv-player/mpv/releases/tag/v0.17.0

Does your version accept --input-unix-socket?

Of course I could add a check that if version is earlier than 0.17.0,
use --input-unix-socket, otherwise go with --input-ipc-server.
Post by Yoni Rabkin
I would also be happy for a documentation patch
which, among other things, describes what is the minimum version of mpv
that would work.
This is certainly doable.

Regards,
Petteri
Petteri Hintsanen
2017-09-18 12:40:32 UTC
Permalink
Hello,

Regarding old mpv versions: Ubuntu 14.04 has a fairly old version 0.3.4.
It does not support --ipc-unix-socket, but it does have --input-file,
which can be FIFO as well. I think that would be the best approach to
control mpv from EMMS: besides being simple file I/O, it would probably
work with virtually any mpv version in use.

The only problem now is that I cannot find any portable way to create
FIFOs in elisp (mpv does not create one but assumes an existing FIFO).
Any suggestions on how to do this? Or should I ask for advice on
emacs-help?

Thanks,
Petteri
Yoni Rabkin
2017-09-18 20:22:56 UTC
Permalink
Post by Petteri Hintsanen
Hello,
Regarding old mpv versions: Ubuntu 14.04 has a fairly old version 0.3.4.
It does not support --ipc-unix-socket, but it does have --input-file,
which can be FIFO as well. I think that would be the best approach to
control mpv from EMMS: besides being simple file I/O, it would probably
work with virtually any mpv version in use.
Yes, that's the version I have on Trisquel.
Post by Petteri Hintsanen
The only problem now is that I cannot find any portable way to create
FIFOs in elisp (mpv does not create one but assumes an existing FIFO).
Any suggestions on how to do this? Or should I ask for advice on
emacs-help?
Nothing comes off of the top of my head.

Since it's possible to install Guix with a newer version of mpv even on
older distros, I would recommend not supporting older versions unless
you have time to spare.

I'll look into the FIFO issue when I have time.

Thanks!
Post by Petteri Hintsanen
Thanks,
Petteri
_______________________________________________
Emms-help mailing list
https://lists.gnu.org/mailman/listinfo/emms-help
--
"Cut your own wood and it will warm you twice"
Petteri Hintsanen
2017-09-18 21:49:34 UTC
Permalink
Post by Yoni Rabkin
Since it's possible to install Guix with a newer version of mpv even on
older distros, I would recommend not supporting older versions unless
you have time to spare.
Well the actual change is trivial, so if there is an easy way to use
FIFO, I'd like to go with that. I'll also try to fix a new patch
including texinfo soon, so that you can test and include it into the
next release if you wish.

mpv's socket IPC has one advantage though: it is duplex, which might
open up some interesting possibilities like asking for stream info etc.
But that is future work anyway.
Post by Yoni Rabkin
I'll look into the FIFO issue when I have time.
Thanks. I also posted a question to gnu.emacs.help.

regards,
Petteri
Petteri Hintsanen
2017-09-28 20:01:46 UTC
Permalink
Hello all,

Regarding the mpv patch, I don't think it makes sense to pursue it any
further. Namely, there is already a quite solid implementation
available at

https://github.com/momomo5717/emms-player-simple-mpv

It is also available from MELPA via package.el.

I've been using it for some time now, and it works very well. Besides
having tons of features, it has a particularly nice property of reusing
the same mpv process, while my patch kills mpv when switching between
playlist entries. This causes irritating clicks on playback, at least
on my system.

The code is licensed under GPL3. I have no idea how difficult it would
be to incorporate emms-player-simple-mpv to EMMS proper, though.

Thanks,
Petteri.
Yoni Rabkin
2017-09-28 20:30:01 UTC
Permalink
Understood.

I don't have a github account. If you have a github account, can you
please ask the author to contact me, or get their email so that I can
write to them about it?
Post by Petteri Hintsanen
Hello all,
Regarding the mpv patch, I don't think it makes sense to pursue it any
further. Namely, there is already a quite solid implementation
available at
https://github.com/momomo5717/emms-player-simple-mpv
It is also available from MELPA via package.el.
I've been using it for some time now, and it works very well. Besides
having tons of features, it has a particularly nice property of reusing
the same mpv process, while my patch kills mpv when switching between
playlist entries. This causes irritating clicks on playback, at least
on my system.
The code is licensed under GPL3. I have no idea how difficult it would
be to incorporate emms-player-simple-mpv to EMMS proper, though.
Thanks,
Petteri.
--
"Cut your own wood and it will warm you twice"
Pierre Neidhardt
2017-11-26 16:54:18 UTC
Permalink
Post by Yoni Rabkin
I don't have a github account. If you have a github account, can you
please ask the author to contact me, or get their email so that I can
write to them about it?
Was this ever brought forward?

Here are the e-mails of the authors:

;; Authors: ZHANG Weiyi <***@gmail.com>,
;; Alex Kost <***@gmail.com>
Yoni Rabkin
2017-11-26 16:58:40 UTC
Permalink
Post by Pierre Neidhardt
Post by Yoni Rabkin
I don't have a github account. If you have a github account, can you
please ask the author to contact me, or get their email so that I can
write to them about it?
Was this ever brought forward?
mpv integration is currently happening, albeit not on this list (as per
the developers request).

We'll see it in the git repo Real Soon Now (TM).
--
"Cut your own wood and it will warm you twice"
Petteri Hintsanen
2017-11-26 19:05:35 UTC
Permalink
Post by Yoni Rabkin
mpv integration is currently happening, albeit not on this list (as per
the developers request).
We'll see it in the git repo Real Soon Now (TM).
Very good, thanks for your efforts.

Petteri
ZHANG Weiyi
2017-11-27 16:51:06 UTC
Permalink
Post by Yoni Rabkin
Post by Pierre Neidhardt
Post by Yoni Rabkin
I don't have a github account. If you have a github account, can you
please ask the author to contact me, or get their email so that I can
write to them about it?
Was this ever brought forward?
mpv integration is currently happening, albeit not on this list (as per
the developers request).
We'll see it in the git repo Real Soon Now (TM).
Hi, I'm the author of emms-player-mpv [1]. It's good to hear that EMMS will
add mpv support. As emms-player-mpv is licensed under GPL 3, feel free to
merge it.

I notice that you discussed unix socket. My project uses FIFO instead. If you
prefer unix socket, check emms-player-simple-mpv [2].

[1]: https://github.com/dochang/emms-player-mpv
[2]: https://github.com/momomo5717/emms-player-simple-mpv
Yoni Rabkin
2017-11-27 16:57:24 UTC
Permalink
Post by ZHANG Weiyi
Post by Yoni Rabkin
Post by Pierre Neidhardt
Post by Yoni Rabkin
I don't have a github account. If you have a github account, can you
please ask the author to contact me, or get their email so that I can
write to them about it?
Was this ever brought forward?
mpv integration is currently happening, albeit not on this list (as per
the developers request).
We'll see it in the git repo Real Soon Now (TM).
Hi, I'm the author of emms-player-mpv [1]. It's good to hear that EMMS will
add mpv support. As emms-player-mpv is licensed under GPL 3, feel free to
merge it.
thank you
Post by ZHANG Weiyi
I notice that you discussed unix socket. My project uses FIFO instead. If you
prefer unix socket, check emms-player-simple-mpv [2].
[1]: https://github.com/dochang/emms-player-mpv
[2]: https://github.com/momomo5717/emms-player-simple-mpv
We are planning on merging emms-player-simple-mpv project since it will
be the way mpv will work going forward (as far as I know.)
--
"Cut your own wood and it will warm you twice"
Yoni Rabkin
2018-04-13 18:37:24 UTC
Permalink
It seems no one like to display the cover. Maybe enabling the option is a
better choice.
Anyone can easily change `emms-player-mpv-parameters', so I think we are
already there.

They just need to remember to either define their own before
`define-emms-simple-player' creates it, or modify the existing one
after.
--
"Cut your own wood and it will warm you twice"
Loading...