Open dennyh opened 3 years ago
The "pythonic" way to do this through python-mpv's interfaces I think would be to register two key press handlers that notify your interaction thread through a condition object from python's threading module. Here's some (untested) code as a starting point:
import threading
cond = threading.Condition()
key = None
@player.on_key_press("a")
def on_a():
nonlocal key
key = 'a'
with cond:
cond.notify()
@player.on_key_press("b")
def on_b():
nonlocal key
key = 'b'
with cond:
cond.notify()
with cond:
cond.wait(timeout=None)
on_a.unregister_mpv_key_bindings()
on_b.unregister_mpv_key_bindings()
print(f'User pressed {key}')
Execution will stop at cond.wait
until either callback fires. The callbacks are called on python-mpv's internal event handler thread, so they will work even while the thread that created them is waiting in cond.wait
.
Thanks for the help! This was what I was looking for.
When trying this out I did notice something I am unsure if it is intended behavior.
import threading
import mpv
def wait_a_or_b(player: mpv.MPV) -> str:
cond = threading.Condition()
key = None
@player.on_key_press("a")
def on_a():
nonlocal key
key = 'a'
with cond:
cond.notify()
@player.on_key_press("b")
def on_b():
nonlocal key
key = 'b'
with cond:
cond.notify()
with cond:
cond.wait(timeout=None)
on_a.unregister_mpv_key_bindings()
on_b.unregister_mpv_key_bindings()
return key
player = mpv.MPV(input_default_bindings=False, input_vo_keyboard=True, osc=True, volume=10)
# Register a keybinding
@player.on_key_press("r")
def my_r_binding():
pass
player.loop = True
player.play("ThreeEditions.mkv")
player.wait_until_playing()
keyPressed = wait_a_or_b(player) # <----
#print(f'User pressed {keyPressed}')
my_r_binding.unregister_mpv_key_bindings() # <----
input("Press enter to continue...")
This code runs fine and does what is expected. However, if we comment out my_r_binding.unregister_mpv_key_bindings()
and hits the last row input("Press enter to continue...")
it throws exeptions. If we also comment out the call to wait_a_or_b then no exceptions are thrown.
This also happens if input is switched for time.sleep.
exception:
Exception inside python-mpv event loop:
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\mpv.py", line 881, in _loop
self._message_handlers[target](*args)
File "C:\Python38\lib\site-packages\mpv.py", line 1550, in _handle_key_binding_message
self._key_binding_handlers[binding_name](key_state, key_name, key_char)
KeyError: 'py_kb_d09505b79a7d8a10'
Oh, that looks like a bug. I'll try to reproduce this and commit a fix.
Let me know if you need any more input from me.
On another note:
The docstring of observe_property
in mpv.py mentions the unregister_mpv_properties
attribute. I think this is meant to be unobserve_mpv_properties
as it is defined in property_observer
.
How would I get my script to wait for one of two key presses in mpv? I want to wait for the user to press one of two keys and then do things based on what key was pressed.
Currently I have hacked together a an ugly way of waiting for keypresses using wait_for_event and on_key_press sending some text to the osd.
You might be able to tell I am fairly new to python.