Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 9th December 2017, 10:45   #1  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
How to load other scripts as sources?

I got a usage question.

I got three script:
1. Script A: (loading a source; A.vpy)
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
# Loading F:\TestClips&Co\Test-AC3-5.1.avi using FFMS2
clip = core.ffms2.Source(source="F:/TESTCL~1/TEST-A~1.AVI",cachefile="H:/Output/avi_54a4199c1a3d3b1476ea1d15dc267332_4827.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg")
# Making sure input color range is set to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# Output
clip.set_output()
2. Script B: (loading another source; output will have same resolution as A; B.vpy)
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
# Loading F:\TestClips&Co\Test-AC3-5.1.avi using FFMS2
clip = core.ffms2.Source(source="F:/TESTCL~1/TEST-A~1.AVI",cachefile="H:/Output/avi_54a4199c1a3d3b1476ea1d15dc267332_4827.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg")
# Making sure input color range is set to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# Color Adjustment
clip = core.std.Levels(clip=clip, gamma=1.50)
# Output
clip.set_output()
3. Script combined (which should combine the two script and do some additional stuff; combined.vpy)
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()
original = ... # no idea on how to load A
filtered = ... # no idea on how toload B
# doing something with the two clips,.. for example stacking them
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
I know I could all this inside one script, but the point here is for me to learn how to read external scripts as sources which can not be edited. So content of A.vpy and B.vpy doesn't really matter, since I can't influence them, but I know they got the same resolution.

My problem is I have no idea how to load another vpy script as a video source.

-> How does one load another script as a source? (I guess it is probably easy and I simply don't know how to approach the problem.)

Thanks!

Cu Selur
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 9th December 2017, 11:13   #2  |  Link
DJATOM
Registered User
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 68
The only thing I'm thinking that you can wrap your scripts as functions and import those scripts into combined ->
Quote:
original = scriptA.function()
filtered = scriptB.function()
...
Something like that.
__________________
Me on GitHub
DJATOM is offline   Reply With Quote
Old 9th December 2017, 11:18   #3  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
@DJTOM: Thanks for that idea, but it would require me to edit scriptA and scriptB, which I want to avoid if possible at all.
-> hoping someone knows a better way or can confirm that this is the only way.

Cu Selur
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 9th December 2017, 11:38   #4  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Ikea Chair
Posts: 1,625
This is an ugly solution I don't really approve of but you can do something like:

[CODE]import scripta
aclip = vs.get_output() #set when impoting the script

import scriptb
bclip = vs.get_output()

#obviously put your own set_output() last or use a nonzero index
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 9th December 2017, 11:58   #5  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Okay, struggling with the 'import part', I tried:
Code:
# Imports
import os
import sys
import vapoursynth as vs
core = vs.get_core()
scriptPath = 'h:/Output'
sys.path.append(os.path.abspath(scriptPath))
#import script A ('h:/Output/A.vpy')
import A
original = vs.get_output()
#import script B ('h:/Output/B.vpy')
import B
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
-> I'm unclear on how to specify that A.vpy/B.vpy should be imported, appending the path where the two scripts are located to the sys.path didn't work.
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 9th December 2017, 12:04   #6  |  Link
DJATOM
Registered User
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 68
It should work if all your scripts placed in the same dir. You don't need to adjust "path".
It might refuse to import if scripts named with 1 symbol, try more complex names.
__________________
Me on GitHub
DJATOM is offline   Reply With Quote
Old 9th December 2017, 12:12   #7  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Quote:
It should work if all your scripts placed in the same dir. You don't need to adjust "path".
It might refuse to import if scripts named with 1 symbol, try more complex names.
The scripts are all lying inside the same directory. (H:/Output)

I renamed 'A.vpy' to 'scriptA.vpy', 'B.vpy' to 'scriptB.vpy' and adjusted 'combined.vpy' to:
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()
#import script A (h:/Output/scriptA.vpy)
import scriptA
original = vs.get_output()
#import script B (h:/Output/scriptB.vpy)
import scriptB
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
Sadly that doesn't work either.
I get:
Code:
Failed to evaluate the script:
Python exception: No module named 'scriptA'

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 5, in <module>
    import scriptA
ModuleNotFoundError: No module named 'scriptA'
Cu Selur
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 9th December 2017, 12:14   #8  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Ikea Chair
Posts: 1,625
Obviously they need to have a .py extension to be found that way
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 9th December 2017, 12:18   #9  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Quote:
Obviously they need to have a .py extension to be found that way
Renaming 'scriptA.vpy' to 'scriptA.py', 'scriptB.vpy' to 'scriptB.py' and adjusting 'combined.vpy' to:
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()
#import script A (h:/Output/scriptA.py)
import scriptA
original = vs.get_output()
#import script B (h:/Output/scriptB.py)
import scriptB
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
gives me:
Code:
Failed to evaluate the script:
Python exception: No module named 'scriptA'

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 5, in <module>
    import scriptA
ModuleNotFoundError: No module named 'scriptA'
Cu Selur
__________________
Hybrid here in the forum, homepage
Selur is offline   Reply With Quote
Old 9th December 2017, 13:07   #10  |  Link
AzraelNewtype
Registered User
 
AzraelNewtype's Avatar
 
Join Date: Oct 2007
Posts: 122
Open a python console in that directory and see if you can import the scripts at all, even if you're not actually doing anything with them. PEP-8 very strongly discourages capitals in module names, but I just tested and they're not expressly forbidden. It's possible the context of whatever is running combined.vpy doesn't think the other two scripts are still in the PYTHONPATH? Of course, I see that you were manually adding the path before, but it looks like you stopped doing that shortly before you had the scripts named in such a way that python would ever find them. If they load safely in the command environment, try adding the path manipulation back in. If not, I'll actually be pretty confused.
AzraelNewtype is offline   Reply With Quote
Old 9th December 2017, 13:30   #11  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
I'm using a portable Python. (Sorry, should have mentioned that.)
So setting the script path is probably needed.
Using:
Code:
# Imports
import os
import sys
import vapoursynth as vs
core = vs.get_core()

scriptPath = 'h:/Output'
sys.path.append(os.path.abspath(scriptPath))

#import script A (h:/Output/scriptA.py)
import scriptA
original = vs.get_output()
#import script B (h:/Output/scriptB.py)
import scriptB
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
I get:
Code:
Failed to evaluate the script:
Python exception: Plugin G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll already loaded (com.vapoursynth.ffms2)

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 14, in <module>
    import scriptB
  File "h:\Output\scriptB.py", line 5, in <module>
    core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
  File "src\cython\vapoursynth.pyx", line 1722, in vapoursynth.Function.__call__ (src\cython\vapoursynth.c:35000)
vapoursynth.Error: Plugin G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll already loaded (com.vapoursynth.ffms2)
Seems like the importing itself does work that way. Hurray!

Problem now is that both scripts use the same source filter (ffms2.dll) and thus the second script crashes on the LoadPlugin-line, since the Plugin is already loaded.

So:
  • Is there a way to check whether a plugin is already loaded ? (won't help here since I don't want to edit the two scripts, but it might be helpful when I generate scripts)
  • Might be a good idea if LoadPlugin would not cause a crash but instead simply ignore the second 'loading'-attempt.

Seems like currently import isn't the right way.

Cu Selur
__________________
Hybrid here in the forum, homepage

Last edited by Selur; 9th December 2017 at 13:34.
Selur is offline   Reply With Quote
Old 9th December 2017, 13:48   #12  |  Link
DJATOM
Registered User
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 68
Quote:
Is there a way to check whether a plugin is already loaded
Yes, use hasattr().
__________________
Me on GitHub
DJATOM is offline   Reply With Quote
Old 9th December 2017, 14:01   #13  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Quote:
Yes, use hasattr().
So like this?
Code:
if not hasattr(core,'ffms2')
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
When I change scriptB to:
Code:
# Imports
import sys
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
if not hasattr(core, 'ffms2')
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
  
# Loading F:\TestClips&Co\Test-AC3-5.1.avi using FFMS2
clip = core.ffms2.Source(source="F:/TESTCL~1/TEST-A~1.AVI",cachefile="H:/Output/avi_54a4199c1a3d3b1476ea1d15dc267332_4827.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg")
# Making sure input color range is set to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# Color Adjustment
clip = core.std.Levels(clip=clip, gamma=1.50)
# Output
clip.set_output()
combined.vpy:
Code:
# Imports
import os
import sys
import vapoursynth as vs
core = vs.get_core()

scriptPath = 'h:/Output'
sys.path.append(os.path.abspath(scriptPath))

#import script A (h:/Output/scriptA.py)
import scriptA
original = vs.get_output()
#import script B (h:/Output/scriptB.py)
import scriptB
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
(still looking for a way to do this without changing scriptA and scriptB, but curious how this works)

fails with:
Code:
Failed to evaluate the script:
Python exception: 0

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 12, in <module>
    original = vs.get_output()
  File "src\cython\vapoursynth.pyx", line 179, in vapoursynth.get_output (src\cython\vapoursynth.c:6257)
KeyError: 0
No clue why this happens.

------------------
Correction seems like there was some cache which caused this, it already crashes with:
Code:
Failed to evaluate the script:
Python exception: invalid syntax (scriptB.py, line 6)

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 14, in <module>
    import scriptB
  File "h:\Output\scriptB.py", line 6
    if not hasattr(core, 'ffms2')
                                ^
SyntaxError: invalid syntax
, so that call needs to look like another way.


Cu Selur
__________________
Hybrid here in the forum, homepage

Last edited by Selur; 9th December 2017 at 14:07. Reason: Correction,..
Selur is offline   Reply With Quote
Old 9th December 2017, 14:12   #14  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Ikea Chair
Posts: 1,625
Quote:
Originally Posted by Selur View Post
So like this?
Code:
if not hasattr(core,'ffms2')
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
When I change scriptB to:
Code:
# Imports
import sys
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
if not hasattr(core, 'ffms2')
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
  
# Loading F:\TestClips&Co\Test-AC3-5.1.avi using FFMS2
clip = core.ffms2.Source(source="F:/TESTCL~1/TEST-A~1.AVI",cachefile="H:/Output/avi_54a4199c1a3d3b1476ea1d15dc267332_4827.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg")
# Making sure input color range is set to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# Color Adjustment
clip = core.std.Levels(clip=clip, gamma=1.50)
# Output
clip.set_output()
combined.vpy:
Code:
# Imports
import os
import sys
import vapoursynth as vs
core = vs.get_core()

scriptPath = 'h:/Output'
sys.path.append(os.path.abspath(scriptPath))

#import script A (h:/Output/scriptA.py)
import scriptA
original = vs.get_output()
#import script B (h:/Output/scriptB.py)
import scriptB
clip = vs.get_output()
# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHorizontal([original,clip])
# Output
stacked.set_output()
(still looking for a way to do this without changing scriptA and scriptB, but curious how this works)

fails with:
Code:
Failed to evaluate the script:
Python exception: 0

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 12, in <module>
    original = vs.get_output()
  File "src\cython\vapoursynth.pyx", line 179, in vapoursynth.get_output (src\cython\vapoursynth.c:6257)
KeyError: 0
No clue why this happens.

------------------
Correction seems like there was some cache which caused this, it already crashes with:
Code:
Failed to evaluate the script:
Python exception: invalid syntax (scriptB.py, line 6)

Traceback (most recent call last):
  File "src\cython\vapoursynth.pyx", line 1830, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:36860)
  File "H:\Output\combined.vpy", line 14, in <module>
    import scriptB
  File "h:\Output\scriptB.py", line 6
    if not hasattr(core, 'ffms2')
                                ^
SyntaxError: invalid syntax
, so that call needs to look like another way.


Cu Selur
1. Just catch the exception ffs
2. It's <current year> so autoload or die
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 9th December 2017, 14:22   #15  |  Link
DJATOM
Registered User
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 68
I'm using it to load videos with DGDecodeNV (that's the fastest video decoding method available on my PC), so my example below:
Quote:
from vapoursynth import core

def DGSource(*args):
if not hasattr(core.avs, 'DGSource'):
core.avs.LoadPlugin(r'D:\VS\AVSPlugins\DGDecodeNV.dll')
return core.avs.DGSource(args)
__________________
Me on GitHub
DJATOM is offline   Reply With Quote
Old 9th December 2017, 14:32   #16  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Quote:
Just catch the exception ffs
Changing scriptB to:
Code:
# Imports
import sys
import vapoursynth as vs
core = vs.get_core()
# Loading Plugins
try:
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
except: # catch all exceptions
   a = 1
 
# Loading F:\TestClips&Co\Test-AC3-5.1.avi using FFMS2
clip = core.ffms2.Source(source="F:/TESTCL~1/TEST-A~1.AVI",cachefile="H:/Output/avi_54a4199c1a3d3b1476ea1d15dc267332_4827.ffindex",format=vs.YUV420P8,alpha=False)
# making sure input color matrix is set as 470bg
clip = core.resize.Point(clip, matrix_in_s="470bg")
# Making sure input color range is set to TV (limited) range.
clip = core.std.SetFrameProp(clip=clip, prop="_ColorRange", intval=1)
# Color Adjustment
clip = core.std.Levels(clip=clip, gamma=1.50)
# Output
clip.set_output()
Seems to work.
Using 'except ffs:' instead of 'except:' give me 'Python exception: name 'ffs' is not defined', so better catch all exceptions since 'ffs' doesn't seem to be the name of the exception,..

Using:
Code:
if not hasattr(core.ffms2, 'Source'):
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
Also works.

-> Thanks for that, but the main problem remains: How to load external scripts as clips without modifying them?

Current solution would require to:
1. copy scripts to a temp-folder and change extension to .py
2. extend path to temp-folder (only needed when using portable Python)
3. adjusting scripts to avoid double plugin loading

Cu Selur
__________________
Hybrid here in the forum, homepage

Last edited by Selur; 9th December 2017 at 14:37.
Selur is offline   Reply With Quote
Old 9th December 2017, 15:56   #17  |  Link
Selur
Registered User
 
Selur's Avatar
 
Join Date: Oct 2001
Location: Germany
Posts: 5,301
Okay, the whole copying and renaming is not needed when using SourceFileLoader:
Code:
# Imports
import vapoursynth as vs
core = vs.get_core()

from importlib.machinery import SourceFileLoader
#import script A (h:/Output/scriptA.py)
SourceFileLoader('original', 'h:/Output/scriptA.vpy').load_module()
original = vs.get_output()

#import script B (h:/Output/scriptB.vpy)
SourceFileLoader('clip', 'h:/Output/scriptB.vpy').load_module()
clip = vs.get_output()

# processing
if original.format.id != clip.format.id:
 original = core.resize.Bicubic(original, format=clip.format.id)
stacked = core.std.StackHoarizontal([original,clip])
# Output
stacked.set_output()
Which I personally prefer over adding random paths to sys.path and having to rename files.

Adjusting the source to avoid double loading is still needed,...
Code:
if not hasattr(core, 'ffms2'):
  core.std.LoadPlugin(path="G:/Hybrid/vsfilters/SourceFilter/FFMS2/ffms2.dll")
(similar calls for all LoadPlugin-calls since LoadPlugin throws an error when trying to load a previously loaded plugin)

So in case LoadPlugin could be adjusted to not throw an error when trying to load an already loaded plugin my problem would be solved.
Since this is probably not happening any time soon: Is there another way around this?

Cu Selur
__________________
Hybrid here in the forum, homepage

Last edited by Selur; 9th December 2017 at 16:02.
Selur is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 02:55.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2017, vBulletin Solutions Inc.