jaseg / python-mpv

Python interface to the awesome mpv media player
https://git.jaseg.de/python-mpv.git
Other
543 stars 68 forks source link

Add support for asynchronous commands #136

Closed trin94 closed 2 years ago

trin94 commented 3 years ago

For embedding python-mpv into native toolkits it might be beneficial to dispatch commands asynchronously. Especially while using libmpv (with render api) this reduces frame drops significantly (for example while moving the mouse).

Additionally, 'celluloid' (former gnome-mpv) does it that way, too :smiley: https://github.com/celluloid-player/celluloid/blob/5e40fdf96af2204348e2df42538ec47176702259/src/celluloid-model.c#L853
https://github.com/celluloid-player/celluloid/blob/5e40fdf96af2204348e2df42538ec47176702259/src/celluloid-mpv-wrapper.c#L49

There are still some issues: the event queue overflows (after seeking extensively for instance)

I've created a minimal working example to reproduce the issue: https://github.com/trin94/python-mpv-async-commands-wip

trin94 commented 3 years ago

So, I've had a look into it and it seems that things are working fine now.

Asynchronous commands can be invoked like the following:

mpv.command_async("keydown", "MOUSE_BTN" + str(0), callback=lambda error, data: print(error, data))
"""
Same as mpv_command, but run the command asynchronously.
Once the command ran, the callback will be invoked, if provided.
The first argument of the callback will be a boolean value.
It will be set to True, if there was an error, False else.
The second argument of the callback depends on the command.
"""

Note: I could not confirm whether the data returned by mpv gets successfully delegated to the callback function as I don't know any command that returns a value :sweat_smile: At least above line prints out (0 None) in my case, so it does not crash at least :smile:

Please also look carefully whether my implementation is correct. I don't know any C so I might have missed something :smiley:

trin94 commented 3 years ago

Alright, I once again force pushed and updated the default error handler :+1:

Let me know what else needs to be changed :wink: :smile:

jaseg commented 2 years ago

I have merged this with commit 8d448d4 tacked on so the command methods return futures. Now you can use either callbacks, or rely on the futures, or even use both (since the return value from the callback ends up in the future). As part of this, I have also now changed the default command method to use libmpv's node interface instead of the string-command one and introduced keyword arguments. This now allows use of e.g. the osd_overlay input command.

jaseg commented 2 years ago

Thank you very much for the code!