Log in

View Full Version : Frame number based crop


Mr Alpha
22nd June 2016, 15:50
I have a vapoursynth script I use to compare pre- and post-encodes. It essentially crops away half och each and then stacks them vertically:


import vapoursynth as vs

core = vs.get_core()

old = core.ffms2.Source(source='input')
new = core.ffms2.Source(source='output')

old = core.text.Text(old, 'Old', 9)
new = core.text.Text(new, 'New', 3)

crop = old.height//2

old = core.std.CropRel(old, bottom=crop+2)
old = core.std.AddBorders(old, bottom=2)

new = core.std.CropRel(new, top=crop)

video = core.std.StackVertical([old, new])

video.set_output()


Now I wonder if there was a way to adjust the crop on per frame basis. Something like:

crop = n % (old.height - 2)

where n is the frame number.

I can't seem to figure out a good way to do this.

Myrsloik
22nd June 2016, 16:11
See the documentation for FrameEval for a more detailed explanation. I tested this script and it works.

import vapoursynth as vs
import functools

core = vs.get_core()

old = core.ffms2.Source(source='oldsource')
new = core.ffms2.Source(source='newsauce')

old = core.text.Text(old, 'Old', 9)
new = core.text.Text(new, 'New', 3)

def animator(n, clip1, clip2):
crop = (((n * 2) % (clip1.height - 2)) // 2) * 2

if crop >= clip1.height - 2:
return clip2
elif crop <= 2:
return clip1

old = core.std.CropRel(clip1, bottom=crop+2)
old = core.std.AddBorders(old, bottom=2)

new = core.std.CropRel(clip2, top=clip1.height - crop)
return core.std.StackVertical([old, new])

animated_clip = core.std.FrameEval(old, functools.partial(animator, clip1=old, clip2=new))
animated_clip.set_output()

Mr Alpha
22nd June 2016, 16:43
Oh nice! Thank you.