Add support for string-array options
This commit is contained in:
parent
34ab0392c8
commit
03492ba394
1 changed files with 65 additions and 11 deletions
76
mpv.py
76
mpv.py
|
|
@ -46,7 +46,7 @@ else:
|
||||||
"mpv-devel or mpv-libs package. If you have libmpv around but this script can't find it, maybe consult "
|
"mpv-devel or mpv-libs package. If you have libmpv around but this script can't find it, maybe consult "
|
||||||
"the documentation for ctypes.util.find_library which this script uses to look up the library "
|
"the documentation for ctypes.util.find_library which this script uses to look up the library "
|
||||||
"filename.")
|
"filename.")
|
||||||
backend = CDLL(sofile)
|
backend = CDLL(sofile) #'/home/user/mpv/build/libmpv.so')
|
||||||
fs_enc = sys.getfilesystemencoding()
|
fs_enc = sys.getfilesystemencoding()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -366,6 +366,57 @@ _handle_gl_func('mpv_opengl_cb_uninit_gl', [],
|
||||||
def _ensure_encoding(possibly_bytes):
|
def _ensure_encoding(possibly_bytes):
|
||||||
return possibly_bytes.decode('utf-8') if type(possibly_bytes) is bytes else possibly_bytes
|
return possibly_bytes.decode('utf-8') if type(possibly_bytes) is bytes else possibly_bytes
|
||||||
|
|
||||||
|
def _mpv_coax_proptype(value, proptype=str):
|
||||||
|
""" Intelligently coax the given python value into something that can be understood as a proptype property """
|
||||||
|
if type(value) is bytes:
|
||||||
|
return value;
|
||||||
|
elif type(value) is bool:
|
||||||
|
return b'yes' if value else b'no'
|
||||||
|
elif proptype in (str, int, float):
|
||||||
|
return str(proptype(value)).encode('utf-8')
|
||||||
|
else:
|
||||||
|
raise TypeError('Cannot coax value of type {} into property type {}'.format(type(value), proptype))
|
||||||
|
|
||||||
|
def _make_node_str_list(l):
|
||||||
|
""" Take a list of python objects and make a MPV string node array from it.
|
||||||
|
|
||||||
|
As an example, the following python list:
|
||||||
|
|
||||||
|
.. code:: python
|
||||||
|
|
||||||
|
l = [ "foo", 23, false ]
|
||||||
|
|
||||||
|
will result in the following MPV node object:
|
||||||
|
|
||||||
|
.. code::
|
||||||
|
|
||||||
|
struct mpv_node {
|
||||||
|
.format = MPV_NODE_ARRAY,
|
||||||
|
.u.list = *(struct mpv_node_array){
|
||||||
|
.num = len(l),
|
||||||
|
.keys = NULL,
|
||||||
|
.values = struct mpv_node[len(l)] {
|
||||||
|
{ .format = MPV_NODE_STRING, .u.string = l[0] },
|
||||||
|
{ .format = MPV_NODE_STRING, .u.string = l[1] },
|
||||||
|
...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
char_ps = [ c_char_p(_mpv_coax_proptype(e, str)) for e in l ]
|
||||||
|
node_list = MpvNodeList(
|
||||||
|
num=len(l),
|
||||||
|
keys=None,
|
||||||
|
values=( MpvNode * len(l))( *[ MpvNode(
|
||||||
|
format=MpvFormat.STRING,
|
||||||
|
val=cast(pointer(p), POINTER(c_longlong)).contents) # NOTE: ctypes is kinda crappy here
|
||||||
|
for p in char_ps ]))
|
||||||
|
node = MpvNode(
|
||||||
|
format=MpvFormat.NODE_ARRAY,
|
||||||
|
val=addressof(node_list))
|
||||||
|
return char_ps, node_list, node, cast(pointer(node), c_void_p)
|
||||||
|
|
||||||
|
|
||||||
def _event_generator(handle):
|
def _event_generator(handle):
|
||||||
while True:
|
while True:
|
||||||
|
|
@ -920,25 +971,28 @@ class MPV(object):
|
||||||
|
|
||||||
def _set_property(self, name, value, proptype=str):
|
def _set_property(self, name, value, proptype=str):
|
||||||
ename = name.encode('utf-8')
|
ename = name.encode('utf-8')
|
||||||
if type(value) is bytes:
|
try:
|
||||||
_mpv_set_property_string(self.handle, ename, value)
|
if proptype is MpvFormat.NODE:
|
||||||
elif type(value) is bool:
|
if isinstance(value, (list, set, dict)):
|
||||||
_mpv_set_property_string(self.handle, ename, b'yes' if value else b'no')
|
_1, _2, _3, pointer = _make_node_str_list(value)
|
||||||
elif proptype in (str, int, float):
|
_mpv_set_property(self.handle, ename, MpvFormat.NODE, pointer)
|
||||||
_mpv_set_property_string(self.handle, ename, str(proptype(value)).encode('utf-8'))
|
else:
|
||||||
else:
|
_mpv_set_property_string(self.handle, ename, _mpv_coax_proptype(value, str))
|
||||||
raise TypeError('Cannot set {} property {} to value of type {}'.format(proptype, name, type(value)))
|
else:
|
||||||
|
_mpv_set_property_string(self.handle, ename, _mpv_coax_proptype(value, proptype))
|
||||||
|
except TypeError as e:
|
||||||
|
raise TypeError("Error setting MPV {} property {}".format(proptype, name)) from e
|
||||||
|
|
||||||
# Dict-like option access
|
# Dict-like option access
|
||||||
def __getitem__(self, name, file_local=False):
|
def __getitem__(self, name, file_local=False):
|
||||||
""" Get an option value """
|
""" Get an option value """
|
||||||
prefix = 'file-local-options/' if file_local else 'options/'
|
prefix = 'file-local-options/' if file_local else 'options/'
|
||||||
return self._get_property(prefix+name)
|
return self._get_property(prefix+name, proptype=MpvFormat.NODE)
|
||||||
|
|
||||||
def __setitem__(self, name, value, file_local=False):
|
def __setitem__(self, name, value, file_local=False):
|
||||||
""" Set an option value """
|
""" Set an option value """
|
||||||
prefix = 'file-local-options/' if file_local else 'options/'
|
prefix = 'file-local-options/' if file_local else 'options/'
|
||||||
return self._set_property(prefix+name, value)
|
return self._set_property(prefix+name, value, proptype=MpvFormat.NODE)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
""" Iterate over all option names """
|
""" Iterate over all option names """
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue