Selur's Little Message Board

Full Version: Encoding with Vapoursynth + Avisynth
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
Is it possible to run an encoding with both Vapoursynth scripts and Avisynth scripts ?

By the way, I actually only need to use one Avisynth custom script (which doesn't work in custom Vapoursynth script)

Thank you
afaik: No.
You can use Avisynth filters in Vapoursynth, but to use an Avisynth script it would need to be rewritten to Vapousynth.
What are you trying to do?

Cu Selur
OK... I'll get straight to the point then. I want to replace problematic frames (with black hole / circle, like perforation) with their duplicate counterpart.

Here is the script :
Code:
# Charge le plugin FFMS2
LoadPlugin("C:\Program Files (x86)\AviSynth+\plugins64+\ffms2.dll")
# Source vidéo
video = FFVideoSource("C:\Users\Admin\Desktop\FILM 3 - ETAPE 3 - DAVINCI.mkv")
# Fonction pour remplacer des frames spécifiques
function ReplaceFrames(clip source, int start1, int end1, int start2, int end2) {
    # Extraire les segments à garder
    segment1 = source.Trim(0, start1 - 1)
    segment2 = source.Trim(start2, end2)
    segment3 = source.Trim(end1 + 1, source.FrameCount - 1)
   
    # Assembler les segments
    return segment1 ++ segment2 ++ segment3
}
# Remplacement des frames 43125 à 43129 par 43120 à 43124
video = ReplaceFrames(video, 43125, 43129, 43120, 43124)
# Remplacement des frames 43301 à 43304 par 43275 à 43278
video = ReplaceFrames(video, 43301, 43304, 43275, 43278)
# Remplacement de la frame 22261 par 22257
video = ReplaceFrames(video, 22261, 22261, 22257, 22257)
# Remplacement de la frame 22262 par 22257
video = ReplaceFrames(video, 22262, 22262, 22257, 22257)
# Remplacement de la frame 22263 par 22256
video = ReplaceFrames(video, 22263, 22263, 22256, 22256)
# Remplacement de la frame 22264 par 22258
video = ReplaceFrames(video, 22264, 22264, 22258, 22258)
# Remplacement de la frame 22437 par 22441
video = ReplaceFrames(video, 22437, 22437, 22441, 22441)
# Remplacement de la frame 22438 par 22442
video = ReplaceFrames(video, 22438, 22438, 22442, 22442)
# Remplacement de la frame 22439 par 22443
video = ReplaceFrames(video, 22439, 22439, 22443, 22443)
# Remplacement de la frame 22440 par 22444
video = ReplaceFrames(video, 22440, 22440, 22444, 22444)

# Remplacement de la frame 22454 par 22453
video = ReplaceFrames(video, 22454, 22454, 22453, 22453)

# Retourner le résultat final
return video
Porting:
Code:
function ReplaceFrames(clip source, int start1, int end1, int start2, int end2) {
    # Extraire les segments à garder
    segment1 = source.Trim(0, start1 - 1)
    segment2 = source.Trim(start2, end2)
    segment3 = source.Trim(end1 + 1, source.FrameCount - 1)
  
    # Assembler les segments
    return segment1 ++ segment2 ++ segment3
}
to Vapoursynth should be easy.
Should be:
Code:
def ReplaceFrames(clip: vs.VideoNode, start1: int, end1: int, start2: int, end2: int)  -> vs.VideoNode:
    # Extraire les segments à garder
    segment1 = source.Trim(0, start1 - 1)
    segment2 = source.Trim(start2, end2)
    segment3 = source.Trim(end1 + 1, source.num_frames - 1)
  
    # Assembler les segments
    return segment1 + segment2 + segment3
}
So you could save that in a file named replaceframes.py (in your 'Hybrid/64bit/vsscripts'-folder) and then use it in a custom section through:
Code:
import replaceframes

# Remplacement des frames 43125 à 43129 par 43120 à 43124
clip = replaceFrames.ReplaceFrames(clip, 43125, 43129, 43120, 43124)
# Remplacement des frames 43301 à 43304 par 43275 à 43278
clip = replaceFrames.ReplaceFrames(clip, 43301, 43304, 43275, 43278)
# Remplacement de la frame 22261 par 22257
clip = replaceFrames.ReplaceFrames(clip, 22261, 22261, 22257, 22257)
# Remplacement de la frame 22262 par 22257
clip = replaceFrames.ReplaceFrames(clip, 22262, 22262, 22257, 22257)
# Remplacement de la frame 22263 par 22256
clip = replaceFrames.ReplaceFrames(clip, 22263, 22263, 22256, 22256)
# Remplacement de la frame 22264 par 22258
clip = replaceFrames.ReplaceFrames(clip, 22264, 22264, 22258, 22258)
# Remplacement de la frame 22437 par 22441
clip = replaceFrames.ReplaceFrames(clip, 22437, 22437, 22441, 22441)
# Remplacement de la frame 22438 par 22442
clip = replaceFrames.ReplaceFrames(clip, 22438, 22438, 22442, 22442)
# Remplacement de la frame 22439 par 22443
clip = replaceFrames.ReplaceFrames(clip, 22439, 22439, 22443, 22443)
# Remplacement de la frame 22440 par 22444
clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)
# Remplacement de la frame 22454 par 22453
clip = replaceFrames.ReplaceFrames(clip, 22454, 22454, 22453, 22453)
clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)

return clip
Got no time to test, but this should work.
One could also use https://github.com/Irrational-Encoding-W...emapFrames in a custom section.

Cu Selur
Thank you. However I had several issues, I guess they're basic (like core not defined, source not defined, module 'vapoursynth' has no attribute 'get_core', and others). Since it's only for one video I just run a second encoding with Avisynth custom script.


But to get back to the original topic, do you think it would be possible that Hybrid switches from Vapoursynth to Avisynth (or vice versa) during encoding, for example just before output is generated on the script, the video would be reloaded into an avisynth script and further filters would be applied ?
(03.09.2024, 04:16)Selur Wrote: [ -> ]You can use Avisynth filters in Vapoursynth

oh? i haven't seen the avisynth tab in ages and i'd like to use deflicker filters.
is there a way i can still activate the avisynth tab and filters to use them in vaporsynth?
https://forum.selur.net/thread-3835.html hast an example how Avisynth filters can be used.
No, there is no special gui support for this.

Cu Selur
Sorry, fixed the syntax for the replaceFrames.py
Code:
from vapoursynth import core
import vapoursynth as vs

def ReplaceFrames(clip: vs.VideoNode, start1: int, end1: int, start2: int, end2: int):
    # Extract segments to keep
    segment1 = clip[:start1]  # From the start to the frame before start1
    segment2 = clip[start2:end2 + 1]  # From start2 to end2
    segment3 = clip[end1 + 1:]  # From the frame after end1 to the end
  
    # Combine the segments
    return segment1 + segment2 + segment3

then call it in Hybrid under "Filtering->Vapoursynth->Custom->Insert before->ReplacBlackFrames"
Code:
import replaceFrames

# Remplacement des frames 43125 à 43129 par 43120 à 43124
clip = replaceFrames.ReplaceFrames(clip, 43125, 43129, 43120, 43124)
# Remplacement des frames 43301 à 43304 par 43275 à 43278
clip = replaceFrames.ReplaceFrames(clip, 43301, 43304, 43275, 43278)
# Remplacement de la frame 22261 par 22257
clip = replaceFrames.ReplaceFrames(clip, 22261, 22261, 22257, 22257)
# Remplacement de la frame 22262 par 22257
clip = replaceFrames.ReplaceFrames(clip, 22262, 22262, 22257, 22257)
# Remplacement de la frame 22263 par 22256
clip = replaceFrames.ReplaceFrames(clip, 22263, 22263, 22256, 22256)
# Remplacement de la frame 22264 par 22258
clip = replaceFrames.ReplaceFrames(clip, 22264, 22264, 22258, 22258)
# Remplacement de la frame 22437 par 22441
clip = replaceFrames.ReplaceFrames(clip, 22437, 22437, 22441, 22441)
# Remplacement de la frame 22438 par 22442
clip = replaceFrames.ReplaceFrames(clip, 22438, 22438, 22442, 22442)
# Remplacement de la frame 22439 par 22443
clip = replaceFrames.ReplaceFrames(clip, 22439, 22439, 22443, 22443)
# Remplacement de la frame 22440 par 22444
clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)
# Remplacement de la frame 22454 par 22453
clip = replaceFrames.ReplaceFrames(clip, 22454, 22454, 22453, 22453)
clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)

would create code like:
Code:
# Imports
import vapoursynth as vs
# getting Vapoursynth core
import sys
import os
core = vs.core
# Import scripts folder
scriptPath = 'F:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# loading plugins
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/LSmashSource/LSMASHSource.dll")
# defining beforeReplaceBlackFrames-function - START
def beforeReplaceBlackFrames(clip):
  import replaceframes
  
  # Remplacement des frames 43125 à 43129 par 43120 à 43124
  clip = replaceFrames.ReplaceFrames(clip, 43125, 43129, 43120, 43124)
  # Remplacement des frames 43301 à 43304 par 43275 à 43278
  clip = replaceFrames.ReplaceFrames(clip, 43301, 43304, 43275, 43278)
  # Remplacement de la frame 22261 par 22257
  clip = replaceFrames.ReplaceFrames(clip, 22261, 22261, 22257, 22257)
  # Remplacement de la frame 22262 par 22257
  clip = replaceFrames.ReplaceFrames(clip, 22262, 22262, 22257, 22257)
  # Remplacement de la frame 22263 par 22256
  clip = replaceFrames.ReplaceFrames(clip, 22263, 22263, 22256, 22256)
  # Remplacement de la frame 22264 par 22258
  clip = replaceFrames.ReplaceFrames(clip, 22264, 22264, 22258, 22258)
  # Remplacement de la frame 22437 par 22441
  clip = replaceFrames.ReplaceFrames(clip, 22437, 22437, 22441, 22441)
  # Remplacement de la frame 22438 par 22442
  clip = replaceFrames.ReplaceFrames(clip, 22438, 22438, 22442, 22442)
  # Remplacement de la frame 22439 par 22443
  clip = replaceFrames.ReplaceFrames(clip, 22439, 22439, 22443, 22443)
  # Remplacement de la frame 22440 par 22444
  clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)
  # Remplacement de la frame 22454 par 22453
  clip = replaceFrames.ReplaceFrames(clip, 22454, 22454, 22453, 22453)
  clip = replaceFrames.ReplaceFrames(clip, 22440, 22440, 22444, 22444)
  return clip
# defining beforeReplaceBlackFrames-function - END

# Import scripts
import validate
# Source: 'G:\TestClips&Co\files\test.avi'
# Current color space: YUV420P8, bit depth: 8, resolution: 640x352, frame rate: 25fps, scanorder: progressive, yuv luminance scale: limited, matrix: 470bg
# Loading G:\TestClips&Co\files\test.avi using LWLibavSource
clip = core.lsmas.LWLibavSource(source="G:/TestClips&Co/files/test.avi", format="YUV420P8", stream_index=0, cache=0, prefer_hw=0)
frame = clip.get_frame(0)
# setting color matrix to 470bg.
clip = core.std.SetFrameProps(clip, _Matrix=vs.MATRIX_BT470_BG)
# setting color transfer (vs.TRANSFER_BT601), if it is not set.
if validate.transferIsInvalid(clip):
  clip = core.std.SetFrameProps(clip=clip, _Transfer=vs.TRANSFER_BT601)
# setting color primaries info (to vs.PRIMARIES_BT470_BG), if it is not set.
if validate.primariesIsInvalid(clip):
  clip = core.std.SetFrameProps(clip=clip, _Primaries=vs.PRIMARIES_BT470_BG)
# setting color range to TV (limited) range.
clip = core.std.SetFrameProps(clip=clip, _ColorRange=vs.RANGE_LIMITED)
# making sure frame rate is set to 25fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)
# making sure the detected scan type is set (detected: progressive)
clip = core.std.SetFrameProps(clip=clip, _FieldBased=vs.FIELD_PROGRESSIVE) # progressive
clip = beforeReplaceBlackFrames(clip)
# adjusting output color from: YUV420P8 to YUV420P10 for NVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 25fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=25, fpsden=1)
# output
clip.set_output()
(see Vapoursynth Script Preview)

Cu Selur
Quote:But to get back to the original topic, do you think it would be possible that Hybrid switches from Vapoursynth to Avisynth (or vice versa) during encoding, for example just before output is generated on the script, the video would be reloaded into an avisynth script and further filters would be applied ?
You mean that Hybrid does a multipass encoding, first for example, it uses Avisynth to filter the source, saves the output into some lossless compressed file, then uses Vapoursynth to filter that output and encodes it to whatever output was chosen?
Sorry, no. Hybrid atm. does not support this, and rewriting Hybrid to do this seems too much work for the gain.

Cu Selur
Yes basically, because I think that's how it works between filters : reusing the last video and re-encoding it.
But if it's too complicated there's no need to bother, we just have to import the video again.