Update python-mpv-jsonipc to v1.1.11
This commit is contained in:
parent
956ba07e0a
commit
532a991692
@ -31,7 +31,7 @@ function will be called for each inbound message.
|
|||||||
#### \_\_init\_\_
|
#### \_\_init\_\_
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
| __init__(ipc_socket, callback=None)
|
| __init__(ipc_socket, callback=None, quit_callback=None)
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the wrapper.
|
Create the wrapper.
|
||||||
@ -87,7 +87,7 @@ function will be called for each inbound message.
|
|||||||
#### \_\_init\_\_
|
#### \_\_init\_\_
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
| __init__(ipc_socket, callback=None)
|
| __init__(ipc_socket, callback=None, quit_callback=None)
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the wrapper.
|
Create the wrapper.
|
||||||
@ -175,7 +175,7 @@ Low-level interface to MPV. Does NOT manage an mpv process. (Internal)
|
|||||||
#### \_\_init\_\_
|
#### \_\_init\_\_
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
| __init__(ipc_socket, callback=None)
|
| __init__(ipc_socket, callback=None, quit_callback=None)
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the wrapper.
|
Create the wrapper.
|
||||||
@ -293,7 +293,7 @@ list is used. Not all commands may actually work when this fallback is used.
|
|||||||
#### \_\_init\_\_
|
#### \_\_init\_\_
|
||||||
|
|
||||||
``` python
|
``` python
|
||||||
| __init__(start_mpv=True, ipc_socket=None, mpv_location=None, log_handler=None, loglevel=None, ****kwargs)
|
| __init__(start_mpv=True, ipc_socket=None, mpv_location=None, log_handler=None, loglevel=None, quit_callback=None, ****kwargs)
|
||||||
```
|
```
|
||||||
|
|
||||||
Create the interface to MPV and process instance.
|
Create the interface to MPV and process instance.
|
||||||
@ -407,7 +407,7 @@ Remove callback to an MPV property change.
|
|||||||
|
|
||||||
Decorator to bind a callback to an MPV property change.
|
Decorator to bind a callback to an MPV property change.
|
||||||
|
|
||||||
@on\_key\_press(property\_name)
|
@property\_observer(property\_name)
|
||||||
def my\_callback(name, data):
|
def my\_callback(name, data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -441,7 +441,7 @@ Play the specified URL. An alias to loadfile().
|
|||||||
| terminate()
|
| terminate()
|
||||||
```
|
```
|
||||||
|
|
||||||
Terminate the connection to MPV and process (if started by this module).
|
Terminate the connection to MPV and process (if **start\_mpv** is used).
|
||||||
|
|
||||||
<a name=".python_mpv_jsonipc.MPV.command"></a>
|
<a name=".python_mpv_jsonipc.MPV.command"></a>
|
||||||
|
|
||||||
|
|||||||
@ -42,14 +42,16 @@ class WindowsSocket(threading.Thread):
|
|||||||
Data is automatically encoded and decoded as JSON. The callback
|
Data is automatically encoded and decoded as JSON. The callback
|
||||||
function will be called for each inbound message.
|
function will be called for each inbound message.
|
||||||
"""
|
"""
|
||||||
def __init__(self, ipc_socket, callback=None):
|
def __init__(self, ipc_socket, callback=None, quit_callback=None):
|
||||||
"""Create the wrapper.
|
"""Create the wrapper.
|
||||||
|
|
||||||
*ipc_socket* is the pipe name. (Not including \\\\.\\pipe\\)
|
*ipc_socket* is the pipe name. (Not including \\\\.\\pipe\\)
|
||||||
*callback(json_data)* is the function for recieving events.
|
*callback(json_data)* is the function for recieving events.
|
||||||
|
*quit_callback* is called when the socket connection dies.
|
||||||
"""
|
"""
|
||||||
ipc_socket = "\\\\.\\pipe\\" + ipc_socket
|
ipc_socket = "\\\\.\\pipe\\" + ipc_socket
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
self.quit_callback = quit_callback
|
||||||
|
|
||||||
access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
|
access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
|
||||||
limit = 5 # Connection may fail at first. Try 5 times.
|
limit = 5 # Connection may fail at first. Try 5 times.
|
||||||
@ -71,15 +73,21 @@ class WindowsSocket(threading.Thread):
|
|||||||
|
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self, join=True):
|
||||||
"""Terminate the thread."""
|
"""Terminate the thread."""
|
||||||
if self.socket is not None:
|
if self.socket is not None:
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
self.join()
|
if join:
|
||||||
|
self.join()
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
"""Send *data* to the pipe, encoded as JSON."""
|
"""Send *data* to the pipe, encoded as JSON."""
|
||||||
self.socket.send_bytes(json.dumps(data).encode('utf-8') + b'\n')
|
try:
|
||||||
|
self.socket.send_bytes(json.dumps(data).encode('utf-8') + b'\n')
|
||||||
|
except OSError as ex:
|
||||||
|
if len(ex.args) == 1 and ex.args[0] == "handle is closed":
|
||||||
|
raise BrokenPipeError("handle is closed")
|
||||||
|
raise ex
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Process pipe events. Do not run this directly. Use *start*."""
|
"""Process pipe events. Do not run this directly. Use *start*."""
|
||||||
@ -102,7 +110,8 @@ class WindowsSocket(threading.Thread):
|
|||||||
self.callback(json_data)
|
self.callback(json_data)
|
||||||
data = b''
|
data = b''
|
||||||
except EOFError:
|
except EOFError:
|
||||||
pass
|
if self.quit_callback:
|
||||||
|
self.quit_callback()
|
||||||
|
|
||||||
class UnixSocket(threading.Thread):
|
class UnixSocket(threading.Thread):
|
||||||
"""
|
"""
|
||||||
@ -111,14 +120,16 @@ class UnixSocket(threading.Thread):
|
|||||||
Data is automatically encoded and decoded as JSON. The callback
|
Data is automatically encoded and decoded as JSON. The callback
|
||||||
function will be called for each inbound message.
|
function will be called for each inbound message.
|
||||||
"""
|
"""
|
||||||
def __init__(self, ipc_socket, callback=None):
|
def __init__(self, ipc_socket, callback=None, quit_callback=None):
|
||||||
"""Create the wrapper.
|
"""Create the wrapper.
|
||||||
|
|
||||||
*ipc_socket* is the path to the socket.
|
*ipc_socket* is the path to the socket.
|
||||||
*callback(json_data)* is the function for recieving events.
|
*callback(json_data)* is the function for recieving events.
|
||||||
|
*quit_callback* is called when the socket connection dies.
|
||||||
"""
|
"""
|
||||||
self.ipc_socket = ipc_socket
|
self.ipc_socket = ipc_socket
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
self.quit_callback = quit_callback
|
||||||
self.socket = socket.socket(socket.AF_UNIX)
|
self.socket = socket.socket(socket.AF_UNIX)
|
||||||
self.socket.connect(self.ipc_socket)
|
self.socket.connect(self.ipc_socket)
|
||||||
|
|
||||||
@ -127,15 +138,22 @@ class UnixSocket(threading.Thread):
|
|||||||
|
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self, join=True):
|
||||||
"""Terminate the thread."""
|
"""Terminate the thread."""
|
||||||
if self.socket is not None:
|
if self.socket is not None:
|
||||||
self.socket.shutdown(socket.SHUT_WR)
|
try:
|
||||||
self.socket.close()
|
self.socket.shutdown(socket.SHUT_WR)
|
||||||
self.join()
|
self.socket.close()
|
||||||
|
self.socket = None
|
||||||
|
except OSError:
|
||||||
|
pass # Ignore socket close failure.
|
||||||
|
if join:
|
||||||
|
self.join()
|
||||||
|
|
||||||
def send(self, data):
|
def send(self, data):
|
||||||
"""Send *data* to the socket, encoded as JSON."""
|
"""Send *data* to the socket, encoded as JSON."""
|
||||||
|
if self.socket is None:
|
||||||
|
raise BrokenPipeError("socket is closed")
|
||||||
self.socket.send(json.dumps(data).encode('utf-8') + b'\n')
|
self.socket.send(json.dumps(data).encode('utf-8') + b'\n')
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@ -157,6 +175,8 @@ class UnixSocket(threading.Thread):
|
|||||||
json_data = json.loads(item)
|
json_data = json.loads(item)
|
||||||
self.callback(json_data)
|
self.callback(json_data)
|
||||||
data = b''
|
data = b''
|
||||||
|
if self.quit_callback:
|
||||||
|
self.quit_callback()
|
||||||
|
|
||||||
class MPVProcess:
|
class MPVProcess:
|
||||||
"""
|
"""
|
||||||
@ -236,21 +256,23 @@ class MPVInter:
|
|||||||
"""
|
"""
|
||||||
Low-level interface to MPV. Does NOT manage an mpv process. (Internal)
|
Low-level interface to MPV. Does NOT manage an mpv process. (Internal)
|
||||||
"""
|
"""
|
||||||
def __init__(self, ipc_socket, callback=None):
|
def __init__(self, ipc_socket, callback=None, quit_callback=None):
|
||||||
"""Create the wrapper.
|
"""Create the wrapper.
|
||||||
|
|
||||||
*ipc_socket* is the path to the Unix/Linux socket or name of the Windows pipe.
|
*ipc_socket* is the path to the Unix/Linux socket or name of the Windows pipe.
|
||||||
*callback(event_name, data)* is the function for recieving events.
|
*callback(event_name, data)* is the function for recieving events.
|
||||||
|
*quit_callback* is called when the socket connection to MPV dies.
|
||||||
"""
|
"""
|
||||||
Socket = UnixSocket
|
Socket = UnixSocket
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
Socket = WindowsSocket
|
Socket = WindowsSocket
|
||||||
|
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
self.quit_callback = quit_callback
|
||||||
if self.callback is None:
|
if self.callback is None:
|
||||||
self.callback = lambda event, data: None
|
self.callback = lambda event, data: None
|
||||||
|
|
||||||
self.socket = Socket(ipc_socket, self.event_callback)
|
self.socket = Socket(ipc_socket, self.event_callback, self.quit_callback)
|
||||||
self.socket.start()
|
self.socket.start()
|
||||||
self.command_id = 1
|
self.command_id = 1
|
||||||
self.rid_lock = threading.Lock()
|
self.rid_lock = threading.Lock()
|
||||||
@ -258,9 +280,9 @@ class MPVInter:
|
|||||||
self.cid_result = {}
|
self.cid_result = {}
|
||||||
self.cid_wait = {}
|
self.cid_wait = {}
|
||||||
|
|
||||||
def stop(self):
|
def stop(self, join=True):
|
||||||
"""Terminate the underlying connection."""
|
"""Terminate the underlying connection."""
|
||||||
self.socket.stop()
|
self.socket.stop(join)
|
||||||
|
|
||||||
def event_callback(self, data):
|
def event_callback(self, data):
|
||||||
"""Internal callback for recieving events from MPV."""
|
"""Internal callback for recieving events from MPV."""
|
||||||
@ -326,10 +348,10 @@ class EventHandler(threading.Thread):
|
|||||||
"""
|
"""
|
||||||
self.queue.put((func, args))
|
self.queue.put((func, args))
|
||||||
|
|
||||||
def stop(self):
|
def stop(self, join=True):
|
||||||
"""Terminate the thread."""
|
"""Terminate the thread."""
|
||||||
self.queue.put("quit")
|
self.queue.put("quit")
|
||||||
self.join()
|
self.join(join)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
"""Process socket events. Do not run this directly. Use *start*."""
|
"""Process socket events. Do not run this directly. Use *start*."""
|
||||||
@ -352,7 +374,8 @@ class MPV:
|
|||||||
Please note that if you are using a really old MPV version, a fallback command
|
Please note that if you are using a really old MPV version, a fallback command
|
||||||
list is used. Not all commands may actually work when this fallback is used.
|
list is used. Not all commands may actually work when this fallback is used.
|
||||||
"""
|
"""
|
||||||
def __init__(self, start_mpv=True, ipc_socket=None, mpv_location=None, log_handler=None, loglevel=None, **kwargs):
|
def __init__(self, start_mpv=True, ipc_socket=None, mpv_location=None,
|
||||||
|
log_handler=None, loglevel=None, quit_callback=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Create the interface to MPV and process instance.
|
Create the interface to MPV and process instance.
|
||||||
|
|
||||||
@ -361,6 +384,7 @@ class MPV:
|
|||||||
*mpv_location* is the location of MPV for *start_mpv*. (Default: Use MPV in PATH)
|
*mpv_location* is the location of MPV for *start_mpv*. (Default: Use MPV in PATH)
|
||||||
*log_handler(level, prefix, text)* is an optional handler for log events. (Default: Disabled)
|
*log_handler(level, prefix, text)* is an optional handler for log events. (Default: Disabled)
|
||||||
*loglevel* is the level for log messages. Levels are fatal, error, warn, info, v, debug, trace. (Default: Disabled)
|
*loglevel* is the level for log messages. Levels are fatal, error, warn, info, v, debug, trace. (Default: Disabled)
|
||||||
|
*quit_callback* is called when the socket connection to MPV dies.
|
||||||
|
|
||||||
All other arguments are forwarded to MPV as command-line arguments if *start_mpv* is used.
|
All other arguments are forwarded to MPV as command-line arguments if *start_mpv* is used.
|
||||||
"""
|
"""
|
||||||
@ -370,6 +394,7 @@ class MPV:
|
|||||||
self.property_bindings = {}
|
self.property_bindings = {}
|
||||||
self.mpv_process = None
|
self.mpv_process = None
|
||||||
self.mpv_inter = None
|
self.mpv_inter = None
|
||||||
|
self.quit_callback = quit_callback
|
||||||
self.event_handler = EventHandler()
|
self.event_handler = EventHandler()
|
||||||
self.event_handler.start()
|
self.event_handler.start()
|
||||||
if ipc_socket is None:
|
if ipc_socket is None:
|
||||||
@ -391,7 +416,7 @@ class MPV:
|
|||||||
else:
|
else:
|
||||||
raise MPVError("MPV process retry limit reached.")
|
raise MPVError("MPV process retry limit reached.")
|
||||||
|
|
||||||
self.mpv_inter = MPVInter(ipc_socket, self._callback)
|
self.mpv_inter = MPVInter(ipc_socket, self._callback, self._quit_callback)
|
||||||
self.properties = set(x.replace("-", "_") for x in self.command("get_property", "property-list"))
|
self.properties = set(x.replace("-", "_") for x in self.command("get_property", "property-list"))
|
||||||
try:
|
try:
|
||||||
command_list = [x["name"] for x in self.command("get_property", "command-list")]
|
command_list = [x["name"] for x in self.command("get_property", "command-list")]
|
||||||
@ -426,6 +451,14 @@ class MPV:
|
|||||||
if len(args) == 2 and args[0] == "custom-bind":
|
if len(args) == 2 and args[0] == "custom-bind":
|
||||||
self.event_handler.put_task(self.key_bindings[args[1]])
|
self.event_handler.put_task(self.key_bindings[args[1]])
|
||||||
|
|
||||||
|
def _quit_callback(self):
|
||||||
|
"""
|
||||||
|
Internal handler for quit events.
|
||||||
|
"""
|
||||||
|
if self.quit_callback:
|
||||||
|
self.quit_callback()
|
||||||
|
self.terminate(join=False)
|
||||||
|
|
||||||
def bind_event(self, name, callback):
|
def bind_event(self, name, callback):
|
||||||
"""
|
"""
|
||||||
Bind a callback to an MPV event.
|
Bind a callback to an MPV event.
|
||||||
@ -563,13 +596,13 @@ class MPV:
|
|||||||
def __del__(self):
|
def __del__(self):
|
||||||
self.terminate()
|
self.terminate()
|
||||||
|
|
||||||
def terminate(self):
|
def terminate(self, join=True):
|
||||||
"""Terminate the connection to MPV and process (if *start_mpv* is used)."""
|
"""Terminate the connection to MPV and process (if *start_mpv* is used)."""
|
||||||
if self.mpv_process:
|
if self.mpv_process:
|
||||||
self.mpv_process.stop()
|
self.mpv_process.stop()
|
||||||
if self.mpv_inter:
|
if self.mpv_inter:
|
||||||
self.mpv_inter.stop()
|
self.mpv_inter.stop(join)
|
||||||
self.event_handler.stop()
|
self.event_handler.stop(join)
|
||||||
|
|
||||||
def command(self, command, *args):
|
def command(self, command, *args):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='python-mpv-jsonipc',
|
name='python-mpv-jsonipc',
|
||||||
version='1.1.10',
|
version='1.1.11',
|
||||||
author="Ian Walton",
|
author="Ian Walton",
|
||||||
author_email="iwalton3@gmail.com",
|
author_email="iwalton3@gmail.com",
|
||||||
description="Python API to MPV using JSON IPC",
|
description="Python API to MPV using JSON IPC",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user