Open sosie-js opened 3 years ago
Hi there,
I'm not sure how the mpv binary's commandline parser for file URLs works, but I think it is possible that it works differently to how loadfile
handles paths. The following seems to work for me, using the vapoursynth
video filter:
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug')
player.loadfile('tests/test.webm', vf='vapoursynth=vpy_test.py')
player.wait_for_playback()
vpy_test.py
:
#!/usr/bin/env python
import vapoursynth as vs
core = vs.get_core()
core.std.AddBorders(video_in, 10, 10, 20, 20).set_output()
Note that on my archlinux setup, I had to use a custom mpv build to get vapoursynth support, as the one from the arch package repo doesn't have it built-in.
Vielen Dank Herr neinseg, I didn't was aware about these extra params. Concerning using a vs filter, I am not sure it usefull as we can uses vpy direct as video source. Using backend 'pyvspipempv' renders but it is impossible to go back in the stream
import mpv
import subprocess
script_path='vpy_test.py'
player = mpv.MPV(config=True)
@player.python_stream('foo')
def reader():
with open('log.txt', 'ab+') as out:
p = subprocess.Popen(['/usr/bin/vspipe '+script_path+' - --y4m' ], shell=True, stdout=subprocess.PIPE)
std_out, std_error = p.communicate()
# Write to the file
if std_error:
out.write( std_error )
yield std_out
player.play('python://foo')
player.wait_for_playback()
Ah, I now understand what you're trying to do!
That's an interesting use of python streams. The reason seek does not work in this case is that vspipe simply outputs raw frame data. mpv does not store old frames, since that would be a very large amount of data.
The following works for me:
#!/usr/bin/env python3
import mpv
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug')
player.loadfile('vpy_test.py', demuxer_lavf_format='vapoursynth')
player.wait_for_playback()
vpy_test.py
:
#!/usr/bin/env python
import vapoursynth as vs
core = vs.get_core()
clip = core.ffms2.Source("tests/test.webm")
clip.set_output()
Note that according to this mpv issue, libavformat does not load vapoursynth scripts by default. Instead, you have to explicitly pass that --demuxer-lavf-format
parameter through libmpv.
With this solution, seeking works since vapoursynth is handled by ffmpeg itself.
Fun fact: you can even directly feed vapoursynth python code through python-mpv, no need for a second file:
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug', loop=True)
@player.python_stream('vps-test')
def reader():
yield b'''
#!/usr/bin/env python
import vapoursynth as vs
core = vs.get_core()
clip = core.ffms2.Source("tests/test.webm")
clip.set_output()
'''
player.loadfile('python://vps-test', demuxer_lavf_format='vapoursynth')
player.wait_for_playback()
Over on my secret development repo you can even have a sneak preview of an upcoming very experimental convenience function that pipes a python function straight into vapoursynth using python-mpv, like this:
player = mpv.MPV(vo='x11')
# EXPERIMENTAL CODE, FEATURE NOT YET MERGED
@player.vapoursynth_stream()
def vps_test(filename):
import vapoursynth as vs
core = vs.get_core()
clip = core.ffms2.Source(filename)
clip.set_output()
vps_test("tests/test.webm")
player.wait_for_playback()
/\ /\ ^ o ^ .\ \/. it smells the python-mpv-vsedit, ja/nein-seg isn't it?
Moreover it is a gate to handle any unhandled protocols . If this is multiplatform then we reached the graal, Danke schon Herr neinseg
In fact I can't use your library in your case which is in non stream (backend 'pyvspipempv' that uses libmpv too works, it's crazy!), something is broken
I have tested with the debug flag
import mpv
script_path='vpy_test.py'
try:
#config=True,
player = mpv.MPV(vo='x11', handler=print, loglevel='debug')
#player.play("file://"+script_path) # FAILS unrecognized file format (reason 4), even if config is set
# 'mpv --demuxer-lavf-format=vapoursynth script_path' works like a charm
player.loadfile(script_path, demuxer_lavf_format='vapoursynth')
player.wait_for_playback()
except NameError as err:
print("Name error: {0}".format(err))
except: # catch *all* exceptions
e = sys.exc_info()[0]
logging.error( "<p>Player Error: %s</p>" % e )
and especially with vo='X11', I get at least an error message
ERROR: <p>Player Error: <class 'AttributeError'></p>
when Inspecting with debugger it crashes directly in init on the first line of self.handle = _mpv_create()
I compiled from the sources mpv, my libmpv.so discovered by your script version is 1.109 with python 3.9.4 ,
mpv 0.33.0-209-gf2afae55e9 Copyright © 2000-2020 mpv/MPlayer/mplayer2 projects
built on Sun Jul 4 14:32:32 CEST 2021
FFmpeg library versions:
libavutil 56.70.100
libavcodec 58.134.100
libavformat 58.76.100
libswscale 5.9.100
libavfilter 7.110.100
libswresample 3.9.100
FFmpeg version: n4.4-78-g031c0cb0b4
The AttributeError
is because of a tiny mistake in one line of your script. In this line:
player = mpv.MPV(vo='x11', handler=print, loglevel='debug')
handler
should be log_handler
like this:
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug')
Oh..thanks ^^'
Now after launching
python3 -m pdb run.py pylibmpv version.vpy
I get stuck with
> /python-mpv-vapoursynth-preview/run.py(2)<module>()
-> from vspreview import main
(Pdb) cont
Using backend 'pylibmpv' for playing '/python-mpv-vapoursynth-preview/version.vpy'
debug cplayer Run command: loadfile, flags=64, args=[url="/python-mpv-vapoursynth-preview/version.vpy", flags="replace", options="demuxer-lavf-format=vapoursynth"]
debug ytdl_hook loading @ytdl_hook.lua
debug stats reading options for stats
debug stats script-opts/stats.conf not found.
debug stats lua-settings/stats.conf not found.
debug cplayer Run command: define-section, flags=64, args=[name="input_stats", contents="i script-binding stats/display-stats\nI script-binding stats/display-stats-toggle\n", flags="default"]
debug cplayer Run command: enable-section, flags=64, args=[name="input_stats", flags="allow-hide-cursor+allow-vo-dragging"]
debug cplayer Run command: define-section, flags=64, args=[name="input_forced_stats", contents="", flags="force"]
debug cplayer Run command: enable-section, flags=64, args=[name="input_forced_stats", flags="allow-hide-cursor+allow-vo-dragging"]
debug auto_profiles loading mp.defaults
debug ytdl_hook reading options for ytdl_hook
debug ytdl_hook script-opts/ytdl_hook.conf not found.
debug ytdl_hook lua-settings/ytdl_hook.conf not found.
debug console reading options for console
debug console script-opts/console.conf not found.
debug console lua-settings/console.conf not found.
debug osd/libass ASS library version: 0x1501000 (runtime 0x1501000)
v osd/libass libass API version: 0x1501000
v osd/libass libass source: commit: 0.15.1-15-gd75ac2411ac52b5f5039f54962c6b5dba6b53b5a
debug auto_profiles loading @auto_profiles.lua
v osd/libass Shaper: FriBidi 1.0.5 (SIMPLE) HarfBuzz-ng 2.3.1 (COMPLEX)
v osd/libass Setting up fonts...
v osd/libass Using font provider fontconfig
v osd/libass Done.
debug auto_profiles Exiting...
v cplayer Done loading scripts.
debug global config path: 'watch_later' -> '-'
debug global config path: 'watch_later' -> '-'
v cplayer Setting option 'demuxer-lavf-format' = 'vapoursynth' (flags = 16)
v cplayer Running hook: ytdl_hook/on_load
v ytdl_hook ytdl:// hook
v ytdl_hook not a ytdl:// url
debug cplayer Run command: define-section, flags=64, args=[name="input_console", contents="", flags="default"]
debug cplayer Run command: enable-section, flags=64, args=[name="input_console", flags="allow-hide-cursor+allow-vo-dragging"]
debug cplayer Run command: define-section, flags=64, args=[name="input_forced_console", contents="", flags="force"]
debug cplayer Run command: enable-section, flags=64, args=[name="input_forced_console", flags="allow-hide-cursor+allow-vo-dragging"]
v bdmv/bluray Opening /python-mpv-vapoursynth-preview/version.vpy
v file Opening /python-mpv-vapoursynth-preview/version.vpy
debug file resize stream to 131072 bytes, drop 0 bytes
debug file Stream opened successfully.
v demux Trying demuxers for level=normal.
debug demux Trying demuxer: disc (force-level: normal)
debug demux Trying demuxer: edl (force-level: normal)
debug demux Trying demuxer: cue (force-level: normal)
debug demux Trying demuxer: rawaudio (force-level: normal)
debug demux Trying demuxer: rawvideo (force-level: normal)
debug demux Trying demuxer: mkv (force-level: normal)
debug demux Trying demuxer: lavf (force-level: normal)
v lavf Found 'vapoursynth' at score=100 size=0 (forced).
cplayer Gui does not appear, is there a special option to do so?
I mean it may require equivalents as in ~/.config/mpv/config
file
[builtin-pseudo-gui]
terminal=no
force-window=yes
idle=once
[pseudo-gui]
player-operation-mode=pseudo-gui
I have tried it and your code works on my system. Here are the scripts I used to test it. At the end of the post is a screenshot of the output I get and the log output.
#!/usr/bin/env python3
import mpv
import functools
import sys
import pickle
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug')
player.loadfile('vpy_test2.py', demuxer_lavf_format='vapoursynth')
player.wait_for_playback()
vpy_test2.py
:
import vapoursynth as vs
from vapoursynth import core
import json
#Python equivalent of package.path = package.path .. ";" ..script_dir.. rel_path
def includepath(rel_path=""):
import os
# Import scripts folder
script_dir = os.path.dirname(__file__)
dir=os.path.join(script_dir, rel_path)
import sys
sys.path.append(os.path.abspath(dir))
includepath()
from pprint import pprint
#print(core.version())
width=800
height=600
clip=core.std.BlankClip(width=width,height=height,format=vs.YUV420P8)
clip=core.text.FrameNum(clip,7,2)
clip=core.text.Text(clip,core.version(),9,2)
msg="Add the two lines to ~/.config/mpv/config:"+chr(13)+"[extension.vpy]"+chr(13)+"demuxer-lavf-format=vapoursynth"
format=clip[0].format
clip_infos = {
'Width': clip.width,
'Height': clip.height,
'Frames': clip. num_frames,
'FPS': clip.fps,
'Format Name': format.name, #'YUV420P8'
'Color Family': format.color_family, #'YUV'
'Alpha': 'No',
'Sample Type': format.sample_type , #'Integer',
'Bits': format.bits_per_sample,
'SubSampling W': format.subsampling_w,
'SubSampling H': format.subsampling_h,
'Planes': format.num_planes
}
clip=core.text.Text(clip, "Frame informations:"+chr(13)+chr(13)+"Video:"+chr(13)+str(clip.width)+"x"+str(clip.height),4,2)
#clip=core.text.Text(clip, json.dumps(clip_infos, indent=4),5,1)
clip=core.text.Text(clip,"To play directly vapoursynth files,"+msg,1,2)
try:
env = get_current_environment()
with env.use():
# Do stuff inside this env.
#pprint(env)
dummy=0
#import web_pdb; web_pdb.set_trace()
except Exception:
try:
env = vpy_current_environment()
with env.use():
# Do stuff inside this env.
#pprint(env)
dummy=0
#import web_pdb; web_pdb.set_trace()
except Exception:
env = globals()
#pprint(env)
dummy=0
#import web_pdb; web_pdb.set_trace()
import mvsfunc as mvf
clip = mvf.ToYUV(clip,matrix = "709", css = "420", depth = 8)
#http://www.vapoursynth.com/doc/pythonreference.html#slicing-and-other-syntactic-sugar
#hide video trick, reduce to the min in time, shortcut for clip = clip.std.Trim(first=1, last=2)
#clip = clip[1:2]
#clip = core.resize.Bicubic(clip, width=10,height=10)
clip.set_output()
``` debug cplayer Run command: loadfile, flags=64, args=[url="vpy_test2.py", flags="replace", options="demuxer-lavf-format=vapoursynth"] [9/1803]debug ytdl_hook loading @ytdl_hook.lua debug auto_profiles loading @auto_profiles.lua debug stats loading @stats.lua debug console loading @console.lua debug auto_profiles Exiting... debug ytdl_hook reading options for ytdl_hook debug ytdl_hook script-opts/ytdl_hook.conf not found. debug ytdl_hook lua-settings/ytdl_hook.conf not found. debug stats reading options for stats debug stats script-opts/stats.conf not found. debug stats lua-settings/stats.conf not found. debug console reading options for console debug console script-opts/console.conf not found. debug console lua-settings/console.conf not found. v cplayer Done loading scripts. debug global config path: 'watch_later' -> '-' debug global config path: 'watch_later' -> '-' v cplayer Setting option 'demuxer-lavf-format' = 'vapoursynth' (flags = 16) v cplayer Running hook: ytdl_hook/on_load v ytdl_hook ytdl:// hook debug cplayer Run command: define-section, flags=64, args=[name="input_stats", contents="i script-binding stats/display-stats\nI script-binding stats/display-stats-toggle\n", flags="default"] v ytdl_hook not a ytdl:// url debug cplayer Run command: enable-section, flags=64, args=[name="input_stats", flags="allow-hide-cursor+allow-vo-dragging"] debug osd/libass ASS library version: 0x1500000 (runtime 0x1501000) v osd/libass libass API version: 0x1501000 v osd/libass libass source: commit: 0.15.1-0-g5447214643eacef71776350e779adf4b6c07bb3b-dirty v osd/libass Shaper: FriBidi 1.0.10 (SIMPLE) HarfBuzz-ng 2.8.2 (COMPLEX) v osd/libass Setting up fonts... v osd/libass Using font provider fontconfig v osd/libass Done. debug cplayer Run command: define-section, flags=64, args=[name="input_forced_stats", contents="", flags="force"] debug cplayer Run command: enable-section, flags=64, args=[name="input_forced_stats", flags="allow-hide-cursor+allow-vo-dragging"] v ifo_dvdnav Opening vpy_test2.py debug cplayer Run command: define-section, flags=64, args=[name="input_console", contents="", flags="default"] v bdmv/bluray Opening vpy_test2.py debug cplayer Run command: enable-section, flags=64, args=[name="input_console", flags="allow-hide-cursor+allow-vo-dragging"] v file Opening vpy_test2.py debug file resize stream to 131072 bytes, drop 0 bytes debug cplayer Run command: define-section, flags=64, args=[name="input_forced_console", contents="", flags="force"] debug cplayer Run command: enable-section, flags=64, args=[name="input_forced_console", flags="allow-hide-cursor+allow-vo-dragging"] debug file Stream opened successfully. v demux Trying demuxers for level=normal. debug demux Trying demuxer: disc (force-level: normal) debug demux Trying demuxer: edl (force-level: normal) debug demux Trying demuxer: cue (force-level: normal) debug demux Trying demuxer: rawaudio (force-level: normal) debug demux Trying demuxer: rawvideo (force-level: normal) debug demux Trying demuxer: mkv (force-level: normal) debug demux Trying demuxer: libarchive (force-level: normal) debug demux Trying demuxer: lavf (force-level: normal) v lavf Found 'vapoursynth' at score=100 size=0 (forced). debug ffmpeg/demuxer vapoursynth: VS format YUV420P8 -> pixfmt yuv420p v lavf avformat_find_stream_info() finished after 2227 bytes. v demux Detected file format: vapoursynth (libavformat) v cplayer Opening done: vpy_test2.py v find_files Loading external files in . v cplayer Running hook: ytdl_hook/on_preloaded v lavf select track 0 info cplayer (+) Video --vid=1 (wrapped_avframe 800x600) v vo/x11/x11 X11 opening display: 172.30.128.1:0 debug vo/x11/x11 X11 running at 5280x2560 ("172.30.128.1:0" => remote display) debug vo/x11/x11 Detected wm supports NetWM. debug vo/x11/x11 Detected wm supports ABOVE state. debug vo/x11/x11 Detected wm supports BELOW state. v vo/x11/x11 Display 0 (default): [0, 0, 5280, 2560] @ 0.000000 FPS v vo/x11 selected visual: 33 warn vo/x11 Warning: this legacy VO has bad performance. Consider fixing your graphics drivers, or not forcing the x11 VO. v vd Container reported FPS: 0.000000 v vd Codec list: v vd wrapped_avframe - AVPacket to AVFrame passthrough v vd Opening decoder wrapped_avframe v vd No hardware decoding requested. v vd Using software decoding. v vd Detected 12 logical cores. v vd Requesting 13 threads for decoding. v vd Selected codec: wrapped_avframe (AVPacket to AVFrame passthrough) v vf User filter list: v vf (empty) v cplayer Starting playback... v vd Using software decoding. v vd Decoder format: 800x600 [0:1] yuv420p auto/auto/auto/auto/auto CL=unknown v vf [in] 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 v vf [userdeint] 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 v vf [userdeint] (disabled) v vf [autorotate] 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 v vf [autorotate] (disabled) v vf [convert] 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 v vf [convert] (disabled) v vf [out] 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 info cplayer VO: [x11] 800x600 yuv420p v cplayer VO: Description: X11 (software scaling) v vo/x11 reconfig to 800x600 yuv420p bt.709/bt.709/bt.1886/limited/display SP=1.000000 CL=mpeg2/4/h264 debug vo/x11 screen size: 1440x2520 warn vo/x11 Shared memory not supported warn vo/x11 Reverting to normal Xlib v vo/x11 Not using SHM. warn vo/x11 Shared memory not supported warn vo/x11 Reverting to normal Xlib v vo/x11 Not using SHM. v vo/x11 Using mp format: bgr0 v vo/x11 Window size: 800x600 (Borders: l=0 t=0 r=0 b=0) v vo/x11 Video source: 800x600 (1:1) v vo/x11 Video display: (0, 0) 800x600 -> (0, 0) 800x600 v vo/x11 Video scale: 1.000000/1.000000 v vo/x11 OSD borders: l=0 t=0 r=0 b=0 v vo/x11 Video borders: l=0 t=0 r=0 b=0 v vo/x11 using 9 threads for scaling v vo/x11 Using zimg. v vo/x11 Using mp format: bgr0 v vo/x11 Window size: 800x600 (Borders: l=0 t=0 r=0 b=0) v vo/x11 Video source: 800x600 (1:1) v vo/x11 Video display: (0, 0) 800x600 -> (0, 0) 800x600 v vo/x11 Video scale: 1.000000/1.000000 v vo/x11 OSD borders: l=0 t=0 r=0 b=0 v vo/x11 Video borders: l=0 t=0 r=0 b=0 v cplayer first video frame after restart shown debug cplayer starting video playback v cplayer playback restart complete @ 0.000000, audio=eof, video=playing v vo/x11/x11 Disabling screensaver. ```
hum, your example is confusing for two reasons,
$ sudo pip3 install mpv
[sudo] Mot de passe de sosie :
Collecting mpv
Downloading mpv-0.1.tar.gz (6.2 kB)
Using legacy 'setup.py install' for mpv, since package 'wheel' is not installed.
Installing collected packages: mpv
Running setup.py install for mpv ... done
Successfully installed mpv-0.1
Maybe you did not seen I gave a hint by providing my secret hijack and magic includepath from my secret service ^o^
#Python equivalent of package.path = package.path .. ";" ..script_dir.. rel_path
def includepath(rel_path=""):
import os
# Import scripts folder
script_dir = os.path.dirname(__file__)
dir=os.path.join(script_dir, rel_path)
import sys
sys.path.append(os.path.abspath(dir))
includepath()
if you do not do so be sure your travel will have flight problems:
Here is what I have with mpv-0.1
```python
$ python3 -m pdb vpy_test2.py
> /tests/python-mpv-vapoursynth-preview/vpy_test2.py(3)<module>()
-> import mpv
(Pdb) cont
Exception in callback MPV.__init__.<locals>.mpv_event_extractor() at /usr/local/lib/python3.9/site-packages/mpv.py:276
handle: <Handle MPV.__init__.<locals>.mpv_event_extractor() at /usr/local/lib/python3.9/site-packages/mpv.py:276>
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/mpv.py", line 254, in _event_generator
raise StopIteration()
StopIteration
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/asyncio/events.py", line 80, in _run
self._context.run(self._callback, *self._args)
File "/usr/local/lib/python3.9/site-packages/mpv.py", line 278, in mpv_event_extractor
for event in _event_generator(self.handle):
RuntimeError: generator raised StopIteration
Traceback (most recent call last):
File "/usr/local/lib/python3.9/pdb.py", line 1705, in main
pdb._runscript(mainpyfile)
File "/usr/local/lib/python3.9/pdb.py", line 1573, in _runscript
self.run(statement)
File "/usr/local/lib/python3.9/bdb.py", line 580, in run
exec(cmd, globals, locals)
File "<string>", line 1, in <module>
File "/python-mpv-vapoursynth-preview/vpy_test2.py", line 3, in <module>
import mpv
File "/usr/local/lib/python3.9/site-packages/mpv.py", line 302, in __init__
_mpv_set_option_string(self.handle, k.replace('_', '-').encode(), istr(v).encode())
File "/usr/local/lib/python3.9/site-packages/mpv.py", line 174, in wrapper
ErrorCode.raise_for_ec(func, *args)
File "/usr/local/lib/python3.9/site-packages/mpv.py", line 59, in raise_for_ec
raise ex(ec, *args)
AttributeError: ('mpv option does not exist', -5, <MpvHandle object at 0x7f0e6e725bc0>, b'log-handler', b'<built-in function print>')
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /usr/local/lib/python3.9/site-packages/mpv.py(59)raise_for_ec()
-> raise ex(ec, *args)
So before import mpv (looking for the first mpv.py in the path) , to ensure it will use your last mpv.py, aside vpy_test2.py and vpy_test2.vpy
we call the magic includepath()
i teleported in the vpy_test2.py.
And now python3 vpy_test2.vpy works MONSIEUR! (APPLAUDE)
So what happens? Why python3 run.py pylibmpv vpy_test2.vpy
gaves me a black screen? it smell a problem of path...
first script have to be named 'vpy_test2.py' whereas second is a vapoursynth one , so has to be renamed from 'vpy_test2.py' to 'vpy_test2.vpy' meaning player.loadfile('vpy_test2.vpy', demuxer_lavf_format='vapoursynth') instead
You could also rename it, I am just not used to vapoursynth conventions and it seems vapoursynth itself does not care: The file loaded just fine.
$ sudo pip3 install mpv
The pip package is called python-mpv
, not just mpv
. The mpv
pip package is a very old copy of my one, but is not owned by me. I will try to contact them so they can perhaps take down that outdated copy.
So what happens? Why python3 run.py pylibmpv vpy_test2.vpy gaves me a black screen? it smell a problem of path...
Could you please post the full terminal output of that here? Like, from how you call it to the very last line it outputs?
Could you also please try the code I posted in this post and tell me what happens? That would help narrow down if the issue is somewhere in the python code or the libmpv installation. You can just paste the python test code in the first snipped into a python shell.
Dear neinseg, I have pushed the relevant files:
https://github.com/sosie-js/python-mpv-vapoursynth-preview/blob/master/vpy_test2.py https://github.com/sosie-js/python-mpv-vapoursynth-preview/blob/master/tests/vpy_test2.vpy this produced after renaming the log file: log_topgun-mission_accomplished.txt
and
https://github.com/sosie-js/python-mpv-vapoursynth-preview/blob/master/vspreview/main.py this produced an empty file, I have to copy/paste as CTRL-C does not work (terminal locked) log_topgun-mission_failed.txt
Guess what? it's simply making mpv unstable.. I grouped all the code in one file run.py (Goldman version)
and then trigger it multiples times python3 run.py pylibmpv version.vpy
to crash or abort the process randomly.
FFmpeg secret bridge works as well ; https://gist.github.com/sosie-js/d4a63f16bda4589176ed19bb6b4f2eab
hacking it to lavf such as ffmpeg -f vapoursynth -filter_complex "movie='vpy_test2.vpy'[in1];[in1][out]" -loglevel fatal -hide_banner -nostdin -f yuv4mpegpipe -strict -1 -pix_fmt yuv420p - | mpv -,
no :-(
run.py: - includes backend pyrawpipempv, ie your hacky vapoursynth code injection to mpv through a pipe (sucks, froze on the black screen, do no crash like than pylibmpv) https://github.com/sosie-js/python-mpv-vapoursynth-preview/blob/master/vspreview/main.py
Now I restricted the test to libmpv backend. The suprize is that this command python3 version_pylibmpv.py version.vpy
triggers all files test.webm, the .py , then the wished version;vpy without rendering it to finish on , "no file.mpv" black screen.
with version_pylibmpv.py aside version pylibmpv of https://github.com/sosie-js/python-mpv-vapoursynth-preview/
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import logging
import os
from pathlib import * #Path
import sys
import mpv
import functools
import pickle
import argparse
from argparse import ArgumentParser
import vapoursynth as vs
version='JJGoldmanPlus'
backend='pylibmpv'
script_path=''
folder = Path(__file__).parent
script_path=str(folder.joinpath(script_path))
def install_custom_log():
logging.basicConfig(format='{asctime}: {levelname}: {message}',
style='{', level=logging.DEBUG)
logging.Formatter.default_msec_format = '%s.%03d'
def create_parser():
parser = ArgumentParser(
description="Specify the vapoursynth with script_path to use"
)
parser.add_argument('script_path', help='Path to Vapoursynth script',
type=Path, nargs='?')
return parser
def main():
install_custom_log()
check_versions()
args = create_parser().parse_args()
if args.script_path is None:
print('python-mpv-vapoursynth-preview ('+version+' version) require argument, -h for help')
sys.exit(1)
script_path = args.script_path.absolute() #dont follow links like resolve()
if not script_path.exists():
print('Script path is invalid.')
sys.exit(1)
#convert pathlib.PosixPath to str so script_path.encode() will work
script_path=str(script_path)
print(version+" use backend '"+backend + "' for playing '"+script_path+"'")
def check_versions() -> bool:
from pkg_resources import get_distribution
from platform import python_version
failed = False
if sys.version_info < (3, 9, 0, 'final', 0):
logging.warning('VSPreview is not tested on Python versions prior to 3.9, but you have {} {}. Use at your own risk.'
.format(python_version(), sys.version_info.releaselevel))
failed = True
#if get_distribution('PyQt5').version < '5.15':
# logging.warning('VSPreview is not tested on PyQt5 versions prior to 5.15, but you have {}. Use at your own risk.'
# .format(get_distribution('PyQt5').version))
# failed = True
if vs.core.version_number() < 53:
logging.warning('VSPreview is not tested on VapourSynth versions prior to 53, but you have {}. Use at your own risk.'
.format(vs.core.version_number()))
failed = True
return not failed
def score(loglevel, component, message):
score='[{}] {}: {}'.format(loglevel, component, message)
print(score)
scores.write(score+chr(13))
main()
try:
with open('log_topgun.txt', 'a+') as scores:
scores.write("----- game starts with "+__file__+"---"+chr(13))
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug', player_operation_mode='pseudo-gui', input_default_bindings=True, input_vo_keyboard=True)
#scripts='debug.lua', script_opts='debug-scriptpath='+script_path) #config=True,
#player.play("file://"+script_path) # FAILS unrecognized file format (reason 4), even if config is s
player.loadfile(script_path, demuxer_lavf_format='vapoursynth')
player.wait_for_playback()
scores.write("----- game over ---"+chr(13))
except NameError as err:
print("Name error: {0}".format(err))
except: # catch *all* exceptions
e = sys.exc_info()[0]
logging.error( "<p>Player Error: %s</p>" % e )
Python or libmpv stack overflow leading to search for fie in the path what do you think about it?
Hello Jaseg,
I tried to make you library work directly with vapoursynth but with no success. With vspipe or directly with mpv standalone it works.
It simply output nothing when I use your library can you have a look at my repository
python-mpv-vapoursynth-preview
and disable the failsafe mode in vspreview/main.py ?Thanks in advance. SoSIE