mpv
mpv copied to clipboard
Python Scripting Support [RFC]
Dear mpv community,
I and @8lurry are excited to introduce Python scripting support for mpv through python-embed. With this PR merged, you can use Python for scripting in mpv just how you can use Lua/JS for scripting currently. And I am sure that Python will bring numerous benefits to mpv as a scripting language like:
- Rich Scripting Capabilities: Python's clean and expressive syntax, dynamic typing, and rich standard library make it easy to write and maintain scripts for mpv. With Python, users can customize mpv's behavior, automate repetitive tasks, implement complex logic, and create interactive interfaces, opening up new possibilities for personalization and creativity.
- Wide Range of Libraries: Python has a vast ecosystem of libraries for various purposes, such as multimedia processing, image manipulation, text processing, machine learning, networking, and more. By incorporating Python scripting into mpv, users can take advantage of these libraries to extend mpv's functionality, add new features, and integrate with other tools and services.
- Large Community and Active Development: Python has a massive community of developers and users, with a vast ecosystem of packages, documentation, forums, and resources. By introducing Python scripting support for mpv, we can tap into this community's knowledge, expertise, and enthusiasm, fostering collaboration, innovation, and continuous improvement.
Some People who script mpv are using Lua to act as bridge between mpv and Python. And with Python scripting, this will stop.
We have solved Python-embed's threading issue currently thanks to @8lurry. And when we get per interpreter-GIL in Python 3.12 (https://peps.python.org/pep-0684/), it can be improved even further making the implementation analogous to Lua/Mujs implementations.
With this PR, you can run Python scripts in mpv but we still need to map many mpv functions to Python (We will be updating them in upcoming commits in PR). This PR acts as POC for time being.
We are seeking Feedback on this PR and hope to get this merged within mpv.
CC: @avih , @sfan5 , @Dudemanguy
i have some concerns regarding add python Scripting Support just like JavaScript
look like i need to do more research
Would the per interpreter-GIL in the upcoming python version allow for the elimination of a lot of the python-specific logic that's in this current implementation and let it behave more like lua/js do?
@Dudemanguy I hope so.
To an end user It shouldn't seem anything different to any other scripts (js/lua) although the underlying implementation is different.
@Dudemanguy , FYI, this version of it will work with older python nicely maybe down to python3.3.
Well if python 3.12 makes it possible to solve some of the technical challenges with embedding python in mpv, I'd think it'd be better to make that the minimum version. That's not to say that the current implementation is bad, but it'd definitely be better if python could just be yet another scripting backend. Plus it's only about a month until python 3.12 releases.
Python 3.12 is 6 months away. I don't think that waiting for Python 3.12 should block this PR.
Oh my mistake. I thought it was next month for some reason.
There are some existing issues with lower level threads (threads created from the scope outside of python). On such a thread python loses its I/O wrappers (and god knows what else). These problems will still exist in 3.12. But the isolation proposed in pep-0684 can be done from the python context. In my opinion and in performance-wise, there'd be hardly any difference between the two (that is if the former approach was doable).
This sounds very interesting! Could you share a sample script?
I imagine this could pave the way for a variety of scripts, including ones to easily modify the UI/UX, like context menus, and make mpv scripting more accessible to casual users
@versedwildcat , it's still a work in progress. We have just developed a working solution to some problems that we had with embedding python on mpv. We are still a step away from getting you this feature. mpv client API hooks still need to be mapped to python functions. I am working on some part of it as I am replying to you. Thank you for your patience.
I've converted this PR to a draft for now until it's ready for review-for-merge.
Hello guys, Long time! I had been away long since. Picked up my incomplete work on this thread, and managed to run this gist: https://gist.github.com/8lurry/a57d61acfd9aa1f120446f8c3d982f97 successfully. I'd love to see you guys have tried it out. @Dudemanguy @varbhat @LaserEyess
Tried it on win11, ran into this issue:
python: could not load client. discarding: testfile.
python: no active client found.Could not load python (null)
and if I quit after that I run into assertion failed:
I've built it using python-embedded 3.11.4. VapourSynthPython as an example works fine with this build.
Also occasionally run into this:
mpv.com --msg-level=python=trace
python: Loading python scripts...
python: (testfile) loading binding b
(crash)
@DeadSix27 , the issues you've mentioned should go away now. I hope to see, all the test cases passing. ;)
@DeadSix27 , the issues you've mentioned should go away now. I hope to see, all the test cases passing. ;)
Github said this pr has conflicts with master branch. Can you resolved it?This will makes it easier for us to merge and test locally.Thanks
@zhongfly , There you have it.
@8lurry
python: could not load client. discarding: testfile.
python: no active client found.
python: Could not load python (null)
Same error's still.. any idea?
EDIT: Sometimes I encounter this one:
python: illegal client. does not have an 'mpv' instance (use: from mpvclient import mpv). discarding: testfile.
python: no active client found.
python: Could not load python (null)
I'm using your example script, it definitely has the import.
@8lurry I also build it with python-embedded 3.11.4. I try this very simple script:
from mpvclient import mpv
mpv.info("Python script work!")
mpv crash after script run. Log:
...
[ 0.030][d][python] Loading python scripts...
...
[ 229.939][i][python] (python-test) Python script work!
gdb:
Thread 11 "mpv/python (python)" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 5268.0x5044]
0x00007ff6d34cde5a in script_log.lto_priv ()
(gdb) where
#0 0x00007ff6d34cde5a in script_log.lto_priv ()
#1 0x00007ff8306109e6 in python311!_PyObject_MakeTpCall () from D:\mpv-python\python311.dll
#2 0x00007ff830614548 in python311!PyObject_Vectorcall () from D:\mpv-python\python311.dll
#3 0x00007ff830615da4 in python311!_PyEval_EvalFrameDefault () from D:\mpv-python\python311.dll
#4 0x00007ff83067f196 in python311!PyIter_Send () from D:\mpv-python\python311.dll
#5 0x00007ff830637568 in python311!PyList_AsTuple () from D:\mpv-python\python311.dll
Build file can be download here: https://github.com/zhongfly/mpv-winbuild/actions/runs/5745111914
@DeadSix27
python: could not load client. discarding: testfile. python: no active client found. python: Could not load python (null)
^ This may come if your client (testfile.py) is not valid. (i.e. testfile.py has SyntaxError or something)
python: illegal client. does not have an 'mpv' instance (use: from mpvclient import mpv). discarding: testfile. python: no active client found. python: Could not load python (null)
^ It won't come if you have "from mpvclient import mpv" on it.
@8lurry syntax is 100% correct and the import is also correct.
EDIT: Shouldn't mpv notify if the syntax is wrong including traceback?
Also same error as zhong:
Thread 9 "mpv/python (python)" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 5644.0x3fdc]
0x00007ff67f5e6333 in handle_log ()
(gdb) bt
#0 0x00007ff67f5e6333 in handle_log ()
#1 0x00007fff438509e6 in python311!_PyObject_MakeTpCall () from C:\Python311\python311.dll
#2 0x00007fff43854548 in python311!PyObject_Vectorcall () from C:\Python311\python311.dll
#3 0x00007fff43855da4 in python311!_PyEval_EvalFrameDefault () from C:\Python311\python311.dll
#4 0x00007fff438bf196 in python311!PyIter_Send () from C:\Python311\python311.dll
#5 0x00007fff43877568 in python311!PyList_AsTuple () from C:\Python311\python311.dll
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
@DeadSix27 , Could you try it again with doing the following changes?
- Un-comment (reactivate) this line:/player/python/defaults.py#L169:
# self.enable_client_message()
- And comment-out (deactivate) the block inside the for loop here:/player/python/mpv_main_event_loop.py#L89:
for client in self.clients.values():
if client.has_binding():
self.enable_client_message()
break
And afterwards let me know if the issue persists.
@DeadSix27 , Could you try it again with doing the following changes?
- Un-comment (reactivate) this line:/player/python/defaults.py#L169:
# self.enable_client_message()
- And comment-out (deactivate) the block inside the for loop here:/player/python/mpv_main_event_loop.py#L89:
for client in self.clients.values(): if client.has_binding(): self.enable_client_message() breakAnd afterwards let me know if the issue persists.
I have tried this,but same issue.This fix not work.
@zhongfly , @DeadSix27 , Would you get me the complete log when you run it (please be sure to set the log level to 'debug').
@zhongfly , @DeadSix27 , Would you get me the complete log when you run it (please be sure to set the log level to 'debug').
The logs have little relevant information,I have set msg-level=all=trace
mpv.log
If I tried to run mpv.info twice,mpv will crash after first one.
from mpvclient import mpv
mpv.info("Python script start!") # mpv crash after here
mpv.info("Python script end!")
Build file can be download here: https://github.com/zhongfly/mpv-winbuild/actions/runs/5745111914
@zhongfly, compile it on a windows system instead.
Build file can be download here: https://github.com/zhongfly/mpv-winbuild/actions/runs/5745111914
@zhongfly, compile it on a windows system instead.
Cross compiling is the go to method, it should work via that and that should be the main interest, I'm sure @zhongfly agrees.
It says here, mingw works with python versions upto 3.4. See: https://wiki.python.org/moin/WindowsCompilers#GCC_-MinGW-w64.28x86.2C_x64.29
It says here, mingw works with python versions upto 3.4. See: https://wiki.python.org/moin/WindowsCompilers#GCC_-MinGW-w64.28x86.2C_x64.29
Both python wiki and mingw are out of date. The latest version of python works well with mingw-w64, see: https://packages.msys2.org/base/mingw-w64-python.
Syntax errors now display fine, still same issues as before though, sometimes it tells me mpv hasn't been imported, sometimes it runs the prints in a script and then just crashes just like before.
EDIT: can you make it more verbose?: [ 0.192][e][python] could not load client. discarding: testfile. [ 0.282][e][python] illegal client. does not have an 'mpv' instance (use: from mpvclient import mpv). discarding: testfile2.
Why could it not load the client testfile and testfile2 has this content:
# import os
from mpvclient import mpv
# from pathlib import Path
print("hi")
mpv.info("test")