1

I have a video file and I want to post-process it using AviSynth. Different parts of the movie require different filters to be used (noise reduction etc.). How can one use different filters for different parts of the input video?

What I once did is to trim the video into segments, apply different filters on them and then concatenate the segments back together. Something like this:

a = clip.Trim(0, 100).RemoveNoise("high")
b = clip.Trim(101, 200).RemoveNoise("low")
clip = a + b

Is there any other way to do this? I am asking, because the more segments you create, the more cumbersome the script becomes.

I've read that AviSynth+ supports arrays. So one might create an array with the frame indices and then build the final clip using a loop. Something like this:

original = last
segments = [ \
    [ 0,  100, "high"], \
    [101, 200, "low"] \
]
clip = BlankClip()
for (i = 0; i < segments.Size; ++i)
{
    clip += original.Trim(segments[i][0], segments[i][1]).RemoveNoise(segments[i][2])
}

This way one could create an array, holding the segments. But, it seems to me that despite this post here, AviSynth+ does not support arrays at the moment.

3 Answers 3

1

This can be done using the filter ClipClop. Here is an example script from the docs of the filter:

Avisource("D:\avs\test.avi")
ORG=Last

V1 = FFT3DFilter(Plane=0,Sigma=1.6)     # Light Luma
V2 = FFT3DFilter(Plane=0,Sigma=2.0)     # Med   Luma
V3 = FFT3DFilter(Plane=0,Sigma=4.0)     # High  Luma
V4 = FFT3DFilter(Plane=3,Sigma=1.6)     # Light Chroma
V5 = FFT3DFilter(Plane=3,Sigma=2.0)     # Med   Chroma
V6 = FFT3DFilter(Plane=3,Sigma=4.0)     # High  Chroma
V7 = FFT3DFilter(Plane=4,Sigma=1.6)     # Light Luma+Chroma
V8 = FFT3DFilter(Plane=4,Sigma=2.0)     # Med   Luma+Chroma
V9 = FFT3DFilter(Plane=4,Sigma=4.0)     # High  Luma+Chroma
V10= FlipHorizontal()                   # Flip-H
V11= FlipVertical()                     # Flip-V
V12= Invert()                           # Invert

NickNames ="""  # Psuedonyms for clips (clip index number)
    L0   = 1    # Light Luma
    L1   = 2    # Med   Luma
    L2   = 3    # High  Luma
    C0   = 4    # Light Chroma
    C1   = 5    # Med   Chroma
    C2   = 6    # High  Chroma
    LC0  = 7    # Light Luma + Chroma
    LC1  = 8    # Med   Luma + Chroma
    LC2  = 9    # High  Luma + Chroma
    FH   = 10   # Flip-H
    FV   = 11   # Flip-V
    INV  = 12   # Invert
"""

SCMD="""          # Clip editing commands in string, can also use commands in file
    C0  0,99      # Light Chroma frames @ 0 -> 99
    L0  100,-200  # Light Luma frames @ 100, 200 frames ie frames 100->299
    INV 300,399   # Invert 300->399
    L0  400,499   # Light Luma frames 400->499
    FH  500,599   # Flip-H 500->599
    LC2 600,699   # High Luma + Chroma
    C1  800       # Med Chroma, Single frame
    1   900,999   # Light Luma, We used the clip number instead of a NickName
    FV  1000,1099 # Flip-V
    LC1 2000,0    # Med   Luma + Chroma, 2000 -> lastframe
"""

SHOW=True

ClipClop(ORG,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,scmd=SCMD,nickname=NickNames,show=SHOW)

How to do it:

  1. You define different versions of the original clip (V1 - V12) using your desired filters.
  2. You can assign nicknames to those versions.
  3. You define the segments using the scmd parameter of the filter. Here you can define which frame ranges of the original clip should be replaced by which nicknamed versions.
0

You definitely need AVSLib (the extension library for AviSynth — very old but very stable library) with very nice documentation, as you may see by clicking my link.

It has many-many useful features — in your case arrays of clips and functions for manipulating them, of course.

(Downloaded .zip file / .exe installer includes the same HTML documentation in an off-line form.)

0

Now, after some period of time, there are versions of AviSynth+ 3.6+, which support arrays.

So you may still use the script from your answer, although with some fixes, mostly in your syntax (you used C/C++ syntax ;-)):

original = Last
segments = [ \
    [ 0,  100, "high"], \
    [101, 200, "low" ]  \
]
clip = original.Trim(0, -1)             # a "base" 1-frame clip - see note 1
for (i = 0, segments.ArraySize-1, 1)    # syntax different from C/C++ - see notes 2, 3 
{
    clip = clip + original.Trim(segments[i,0], segments[i,1]).RemoveNoise(segments[i,2])
}
clip = clip.Trim(1, 0)                  # remove a “base” 1-frame clip 

Notes:

  1. Instead of your BlankClip()
    (which is a pitch-black 10 seconds RGB32 clip, 640×480, 24 fps, 16 bit 44100 Hz mono)
    I "borrowed" the first frame of your original clip as a "base" clip:

    clip = original.Trim(0, -1)
    

    (0-frame clips are not allowed.)

  2. Syntax for for block is different from C/C++:

    • commas (,) instead of semicolons (;),
    • the 2nd “parameter” is not a condition, but simply the upper limit,
    • the 3nd “parameter” is not a repeatedly computed expression, but simply the step.
      (It may be omitted – the default step is 1).
  3. The correct name of the function is not Size(), but ArraySize():

    segments.ArraySize               # or segments.ArraySize()
    
  4. There is no += assignment operator in AviSynth, so I changed your

    clip += original.Trim(...)...
    

    to

    clip = clip + original.Trim(...)...
    
  5. Instead of using indexes in the form segments[i][k] (which is OK), I used a shorter form segments[i,k].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.