-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vapoursynth support #172
Comments
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 player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug')
player.loadfile('tests/test.webm', vf='vapoursynth=vpy_test.py')
player.wait_for_playback()
#!/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. 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()
#!/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 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() |
/\ _ /\ 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 when Inspecting with debugger it crashes directly in init I compiled from the sources mpv, my libmpv.so discovered by your script version is 1.109 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 player = mpv.MPV(vo='x11', handler=print, loglevel='debug')
player = mpv.MPV(vo='x11', log_handler=print, loglevel='debug') |
Oh..thanks ^^' Now after launching 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? [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()
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()
|
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.
The pip package is called
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 and https://github.com/sosie-js/python-mpv-vapoursynth-preview/blob/master/vspreview/main.py |
Guess what? it's simply making mpv unstable.. I grouped all the code in one file run.py (Goldman version) FFmpeg secret bridge works as well ; https://gist.github.com/sosie-js/d4a63f16bda4589176ed19bb6b4f2eab 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) |
Now I restricted the test to libmpv backend. The suprize is that this command #!/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
The text was updated successfully, but these errors were encountered: