├── LICENSE ├── README.md └── mpvSockets.lua /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Wis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mpvSockets 2 | creates a socket for each instance of mpv started, name of the socket is based on the process ID of the mpv instance. 3 | 4 | dangling sockets for crashed or killed mpv processes is an issue, i'm not sure if this script should handle/remove them or the clients/users, or both. 5 | 6 | # Installation 7 | Download the single script file to your mpv-scripts-directory 8 | ## Linux / unixes: 9 | ``` bash 10 | your_mpv_config_dir_path="$HOME/.config/mpv"; 11 | curl "https://raw.githubusercontent.com/wis/mpvSockets/master/mpvSockets.lua" --create-dirs -o "$your_mpv_config_dir_path/scripts/mpvSockets.lua" 12 | ``` 13 | 14 | ## Windows (untested) 15 | powershell: 16 | ``` powershell 17 | Invoke-WebRequest -OutFile "$env:LOCALAPPDATA\mpv\scripts\mpvSockets.lua" "https://raw.githubusercontent.com/wis/mpvSockets/master/mpvSockets.lua" 18 | ``` 19 | 20 | # Usage, with Mpv's [JSON IPC](https://github.com/mpv-player/mpv/blob/master/DOCS/man/ipc.rst) 21 | ## Linux / unixes (unix sockets): 22 | a script that pauses all running mpv instances: 23 | bash: 24 | ``` bash 25 | #!/bin/bash 26 | for i in $(ls /tmp/mpvSockets/*); do 27 | echo '{ "command": ["set_property", "pause", true] }' | socat - "$i"; 28 | done 29 | # Socat is a command line based utility that establishes two bidirec-tional byte streams and transfers data between them. 30 | # available on Linux and FreeBSD, propably most unixes. you can also use 31 | ``` 32 | 33 | ## Windows (named pipes): 34 | quote from https://mpv.io/manual/stable/#command-prompt-example 35 | > Unfortunately, it's not as easy to test the IPC protocol on Windows, since Windows ports of socat (in Cygwin and MSYS2) don't understand named pipes. In the absence of a simple tool to send and receive from bidirectional pipes, the echo command can be used to send commands, but not receive replies from the command prompt. 36 | > 37 | > Assuming mpv was started with: 38 | > 39 | > `mpv file.mkv --input-ipc-server=\\.\pipe\mpvsocket` 40 | > You can send commands from a command prompt: 41 | > 42 | > `echo show-text ${playback-time} >\\.\pipe\mpvsocket` 43 | To be able to simultaneously read and write from the IPC pipe, like on Linux, it's necessary to write an external program that uses overlapped file I/O (or some wrapper like .NET's NamedPipeClientStream.) 44 | 45 | powershell client writer and reader (untested): 46 | ``` powershell 47 | # socat.ps1 48 | # usage: socat.ps1 49 | $sockedName = args[0] 50 | $message = args[1] 51 | 52 | $npipeClient = new-object System.IO.Pipes.NamedPipeClientStream('.', $socketName, [System.IO.Pipes.PipeDirection]::InOut, [System.IO.Pipes.PipeOptions]::None, [System.Security.Principal.TokenImpersonationLevel]::Impersonation) 53 | 54 | $pipeReader = $pipeWriter = $null 55 | try { 56 | $npipeClient.Connect() 57 | $pipeReader = new-object System.IO.StreamReader($npipeClient) 58 | $pipeWriter = new-object System.IO.StreamWriter($npipeClient) 59 | $pipeWriter.AutoFlush = $true 60 | 61 | $pipeWriter.WriteLine($message) 62 | 63 | while (($data = $pipeReader.ReadLine()) -ne $null) { 64 | $data 65 | } 66 | } 67 | catch { 68 | "An error occurred that could not be resolved." 69 | } 70 | finally { 71 | $npipeClient.Dispose() 72 | } 73 | ``` 74 | -------------------------------------------------------------------------------- /mpvSockets.lua: -------------------------------------------------------------------------------- 1 | -- mpvSockets, one socket per instance, removes socket on exit 2 | 3 | local utils = require 'mp.utils' 4 | 5 | local function get_temp_path() 6 | local directory_seperator = package.config:match("([^\n]*)\n?") 7 | local example_temp_file_path = os.tmpname() 8 | 9 | -- remove generated temp file 10 | pcall(os.remove, example_temp_file_path) 11 | 12 | local seperator_idx = example_temp_file_path:reverse():find(directory_seperator) 13 | local temp_path_length = #example_temp_file_path - seperator_idx 14 | 15 | return example_temp_file_path:sub(1, temp_path_length) 16 | end 17 | 18 | tempDir = get_temp_path() 19 | 20 | function join_paths(...) 21 | local arg={...} 22 | path = "" 23 | for i,v in ipairs(arg) do 24 | path = utils.join_path(path, tostring(v)) 25 | end 26 | return path; 27 | end 28 | 29 | ppid = utils.getpid() 30 | os.execute("mkdir " .. join_paths(tempDir, "mpvSockets") .. " 2>/dev/null") 31 | mp.set_property("options/input-ipc-server", join_paths(tempDir, "mpvSockets", ppid)) 32 | 33 | function shutdown_handler() 34 | os.remove(join_paths(tempDir, "mpvSockets", ppid)) 35 | end 36 | mp.register_event("shutdown", shutdown_handler) 37 | --------------------------------------------------------------------------------