A collection of bash scripts to allow easier and programmatic interaction with mpv
sockets
When launching mpv
, one can use --ipc-socket
(or set the property in your mpv.conf
) to launch mpv
with the one socket, but I tend to have lots of instances of mpv
open. One for a video I'm watching, another for some album I'm listening to, another for a playlist...
If you use the one IPC socket, whenever a new instance of mpv
is launched, the old instance gets disconnected. The mpv
wrapper script creates a unique IPC socket for each mpv
instance launched at /tmp/mpvsockets
.
mpv-active-sockets
removes any inactive (leftover socket files from instances which have been quit) mpv
sockets, and lists active mpv
sockets
mpv-communicate
is a basic socat
wrapper to send commands to the IPC server. (sends all additional arguments to the socket described by the first argument)
To illustrate:
If I have two instances of mpv
open:
$ mpv-active-sockets
/tmp/mpvsockets/1643226338072141025
/tmp/mpvsockets/1643226355764534189
To get metadata from the oldest (sockets are sorted by spawn time, so head
gets the oldest) launched mpv
instance:
$ mpv-communicate "$(mpv-active-sockets | head -n 1)" '{ "command": ["get_property", "metadata"] }' | jq
{
"data": {
"title": "Roundabout",
"album": "Fragile",
"genre": "Progressive Rock",
"track": "01/9",
"disc": "1/1",
"artist": "Yes",
"album_artist": "Yes",
"date": "1972"
},
"request_id": 0,
"error": "success"
}
mpv-get-property
interpolates the second argument into the get_property
command
syntax, but is practically no different from mpv-communicate
$ mpv-get-property "$(mpv-active-sockets)" path # this works if there's only one instance of mpv active
Music/Yes/Yes - Fragile/01 - Roundabout.mp3
mpv-currently-playing
is a mpv-get-property
wrapper that gets information about the currently playing mpv instance. If there are multiple sockets, prints multiple lines, with one for each socket.
By default that will print the full path of the song that's currently playing, but you can provide the --socket
flag to print the sockets instead.
Lots of scripts here use mpv-currently-playing
internally, as interacting with the currently playing mpv
instance is pretty useful.
-
mpv-play-pause
: toggles the currently playingmpv
between playing/paused. It keeps track of which sockets were recently paused - if a socket can be resumed, it does that; else, tries to look for another pausedmpv
instance to resume. -
mpv-song-description
: constructs a description from themetadata
:
$ mpv-song-description
Yellow Submarine - The Beatles (Revolver)
mpv-next-song
: goes to the next song, by sending theplaylist-next
command:
mpv-communicate $(mpv-currently-playing --socket | tail -n1) '{ "command": ["playlist-next"] }'
-
mpv-seek
: moves forward/backward a few seconds in the currently playing media -
mpv-quit-latest
: quit the currently playingmpv
instance:
mpv-communicate $(mpv-currently-playing --socket | tail -n1) 'quit'
To list currently paused mpv
instances:
$ diff -y --suppress-common-lines <(mpv-currently-playing --socket) <(mpv-active-sockets) | grep -oP '(\/tmp\/mpvsockets\/\d+)'
I bind lots of these scripts to keybindings, so I can easily play/pause and skip songs without switching to the terminal with mpv
running; search for mpv
in my config file
There are lots of properties/commands one can send to mpv
, see mpv --list-properties
and these (1, 2) for reference.
Dependencies: mpv
, socat
, jq
, sed
, (fzf
for mpv-quit-pick
)
To install this, clone and copy all the scripts somewhere onto your $PATH
:
git clone https://github.com/purarue/mpv-sockets
cd ./mpv-sockets
make
That puts them in ~/.local/bin
I put the directory that the mpv
wrapper script is installed into on my $PATH
before /usr/bin
, so the wrapper script intercepts calls that would typically call the mpv
binary. In my shell profile, like:
PATH="${HOME}/.local/bin:${PATH}"
export PATH
You could alternatively rename the mpv
wrapper script here to something like mpvs
and then run mpvs
instead of mpv
when you want unique sockets.
This checks /usr/bin/mpv
, /bin/mpv
and /usr/local/bin/mpv
for the mpv
binary. If your mpv
isn't at one of those locations, you can set the MPV_PATH
variable in your shell profile:
export MPV_PATH=/home/user/bin/mpv
You can set the MPV_SOCKET_DIR
environment variable to spawn sockets in a directory other than /tmp/mpvsockets
, this uses the TMPDIR
environment variable if it's set instead of /tmp
To automate the manual git clone
/cd
/make
, you could instead use bpkg
:
bpkg install -g purarue/mpv-sockets
Or basher
:
basher install purarue/mpv-sockets
Note that in this case the basher bin
has to appear before the mpv
binary, see my config as an example (I install basher in $XDG_DATA_HOME
, by default it places itself in ~/.basher
)
I run mpv-history-daemon
in the background, which polls for new sockets at /tmp/mpvsockets
, grabbing file info, metadata, and whenever I play/pause/skip anything playing in mpv
. That creates a local JSON scrobbling history for mpv
, which I send up to my_feed, as well as to a websocket-based currently playing server
1598956534118491075|1598957274.3349547|mpv-launched|1598957274.334953
1598956534118491075|1598957274.335344|working-directory|/home/username/Music
1598956534118491075|1598957274.3356173|playlist-count|12
1598956534118491075|1598957274.3421223|playlist-pos|2
1598956534118491075|1598957274.342346|path|Masayoshi Takanaka/Masayoshi Takanaka - Alone (1988)/02 - Feedback's Feel.mp3
1598956534118491075|1598957274.3425295|media-title|Feedback's Feel
1598956534118491075|1598957274.3427346|metadata|{'title': "Feedback's Feel", 'album': 'Alone', 'genre': 'Jazz', 'album_artist': '高中正義', 'track': '02/8', 'disc': '1/1', 'artist': '高中正義', 'date': '1981'}
1598956534118491075|1598957274.342985|duration|351.033469
1598956534118491075|1598957274.343794|resumed|{'percent-pos': 66.85633}
1598956534118491075|1598957321.3952177|eof|None
1598956534118491075|1598957321.3955588|mpv-quit|1598957321.395554
Ignoring error: [Errno 32] Broken pipe
Connected refused for socket at /tmp/mpvsockets/1598956534118491075, removing dead socket file...
/tmp/mpvsockets/1598956534118491075: writing to file...