Fun with AVIsynth
I am making this document to demonstrate the power of FREE video tools. I am also just jotting down some ideas I want to share. Hopefully, these ideas will keep coming and this document will grow. I am still learning this tool, so I hope to be able to make more and more advanced scripts in the future.
If you plan to follow along, then you might as well go ahead and get the free software. First of all is VirtualDub, a great video capture tool, but also a very powerful video editor. Next is AVIsynth. Avisynth is very powerful, but misleading. It does not have a fancy GUI. In fact, it doesn't even have a command line interface. AVIsynth is a scripting language/frame server.
I also recommend getting a good text editor. I use Edit Plus, a very nice full featured shareware (with full functionality) text editor. You may also want to download my Edit Plus AVIsynth syntax file.
The ideas explored here are:
Synchronizing two videos from different angles
Inserting a clip over another clip
Swapping angles
Slow fade into another scene
The widescreen look
Anamorphic widescreen
Strobing
NTSC to PAL conversion
PAL to NTSC conversion
Slow motion
Okay, now for the fun. Let's say you recorded an event (wedding, concert, etc) from two angles and you want to make a new video that switches from one angle to the other. The first order of business is to sync up the two videos. This script below should take care of that.
Synchronizing two videos
Syncing up two videos requires the use of these functions: stackvertical/stackhorizontal, deleteframe, duplicateframe, trim. The principal is you display both videos side by side. Then view it in Virtual Dub and count the difference in frames between the two. Look for visual cues that you can use to synchronize the two videos by. Then you add a trim command to one of the clips and view it again. If you got it right, then they will be perfectly in sync. If the two clips somehow get out of sync while you play it (perhaps you dropped a frame upon capture), you can maintain synch by adding or deleting frames from one clip or the other.
# Note: Both clips should be same size and framerate
m1=avisource("angle1.avi").trim(5,0)
m2=avisource("angle2.avi")
m2=duplicateframe(m2,6021)
return stackvertical(m1,m2)
|
Now that the two clips are synched, you can do some other cool things...
Swapping angles
This function swaps angles by replacing frames from one video with frames from another video. The end result is a multi angle mix. These are hard cuts - no smooth transitions this time. We will experiment with that later on.
m1=avisource("angle1.avi").trim(5,0)
m2=avisource("angle2.avi")
# Movie is all one angle (for now)
movie=m1
# Now swap in some scenes from the other angle
movie=sceneinsert(movie,m2,1002,1536)
movie=sceneinsert(movie,m2,5001,7020)
return movie
function sceneinsert(clip a1, clip a2, int f1, int f2)
{
# a1=main movie, a2=angle2
segment=a2.trim(f1,f2)
return a1.trim(0,f1-1) + segment + a1.trim(f2+1,0)
}
|
A better way
This is probably a better way to do this multi-angle movie. Rather than stick a scene into another video over a range of frames, we just swap from one angle to the next. See if this code makes any sence.
m1=avisource("angle1.avi").trim(5,0)
m2=avisource("angle2.avi")
# Movie starts at angle-1, swaps to angle-2 at frame 1002,
# and back to angle-1 at frame 1536
movie=m1
movie=angle(movie,m2,1002)
movie=angle(movie,m1,1536)
return movie
function angle(clip a1, clip a2, int f)
{
# a1=main movie, a2=angle2
segment=a2.trim(f,0)
return a1.trim(0,f-1) + segment
}
|
Dissolving into another scene
You could also experiment with the dissolve command to smoothly transition from one to the other. Using the above approach, it is easy to modify it for dissolves. In fact, the same code can be used for hard cuts if you set the dissolve number to 0.
m1=avisource("angle1.avi").trim(5,0)
m2=avisource("angle2.avi")
# Movie start at angle-1, dissolves to angle2 at frame 1002,
# and hard cuts back to angle1 at frame 1536
movie=m1
movie=angle(movie,m2,1002,60) #two-second dissolve
movie=angle(movie,m1,1536,0) #hard cut
return movie
function angle(clip a1, clip a2, int f, int d)
{
# a1=main movie, a2=angle2, d=number of frames for dissolve
# make sure d is not too high
return dissolve(a1.trim(0,f+d), a2.trim(f,0), d)
}
|
The widescreen look
Here is a quick script which gives your 4x3 video the "widescreen" look. It is basically cropping 60 lines from the top and bottom and resizing the image. It takes advantage of the "overscan" area on your TV by using the part of the picture that is normally covered by the TV's bezel. It's simple in principle, but gets complicated due to the interlacing nature of video.
movie=avisource("angle1.avi") # clip os 720x480
movie=anamorphicwidescreen(movie)
return movie
function widescreen(clip m)
{
m=assumeTFF(m)
m=bob(m)
m=m.crop(0,40,720,-40)
m=m.bilinearresize(668,360).addborders(26,60,26,60)
m=m.separatefields.selectevery(2, 1)
return weave(m)
}
|
Anamorphic widescreen
Make it anamorphic widrescreen by not compressing it vertically. A 16x9 TV will stretch it horizontally for the correct aspect ratio of 1.78:1. This filter takes advantage ot the "overscan" area of the picture. It crops off 40 pixels from the top and bottom instead of 60. Then it reduces horizontal size by 26 pixels (which works out to 20 square pixels).
movie=avisource("angle1.avi") # clip os 720x480
movie=anamorphicwidescreen(movie)
return movie
function anamorphicwidescreen(clip m)
{
m=assumeTFF(m)
m=bob(m)
m=m.crop(0,40,720,-40)
m=m.bilinearresize(668,480).addborders(26,0,26,0)
m=m.separatefields.selectevery(2, 1)
return weave(m)
}
|
Strobing
Here's a wild one. This one sort of "strobes" the video. It's kind of a wierd special effect. Note that it has to convert it to progressive before it can work properly.
v=AVIsource("test.avi") # source is 30 fps interlaced at 720x480
return strobe(v,10)
# strobes video by duplicating frames. Number of duplications is 'i'.
function strobe(v,i)
{
i= i*2
f= framerate(v)
v= assumeTFF(v)
v= bob(v)
v= selectevery(v,i, 0)
return v.changeFPS(f)
}
|
PAL video to NTSC video
Sample script for converting European PAL (25i) video to American NTSC (29.97i) video.
function pal2ntsc(v)
{
last=v
#input TFF or BFF
assumeTFF
#assumeBFF
SmoothDeinterlace(doublerate=true)
#LanczosResize(720,480)
BilinearResize(720,480)
#ChangeFPS(59.94) # crisp but slightly jerky
ConvertFPS(59.94) # smoother but slightly blurry
SeparateFields
#output TFF or BFF
#SelectEvery(4,1,2) # TFF
SelectEvery(4,0,3) # BFF
Weave
return last
}
|
NTSC video to PAL video
Sample script for converting American NTSC (29.97i) video to European PAL (25i) video.
function ntsc2pal(clip v)
{
vw= width(v)
vh= height(v)
#input TFF or BFF
v=assumeTFF(v)
#v=assumeBFF(v)
#v=bob(v)
v=v.SmoothDeinterlace(doublerate=true) # alternate to bob
v=v.bicubicresize(vw,576)
#v=v.ChangeFPS(50) # crisp but slightly jerky
v=v.ConvertFPS(50) # smoother but slightly blurry
v=SeparateFields(v)
#output TFF or BFF
v=SelectEvery(v,4,1,2) # TFF
#v=SelectEvery(v,4,0,3) # BFF
v=Weave(v)
return v.assumefps(25)
}
|
Slow motion
Here are three methods for doing the slow motion effect. The theory is to first split the fields to progressive frames. That will give you 1/2 motion. Then slow down further by duplicating and blending frames.
v=AVIsource("test.avi") # source is 30 fps interlaced at 720x480
#return slowmo_50(v)
return slowmo_33(v)
#return slowmo_25(v)
# Aa Bb Cc Dd
# AA aa BB bb CC cc DD dd
function slowmo_50(clip v)
{
v=assumeTFF(v)
v=bob(v)
return v.assumefps(29.970)
}
# Aa Bb Cc Dd
# AA Aa aa BB Bb bb CC Cc cc DD Dd dd
function slowmo_33(clip v)
{
vi=v
v=assumeTFF(v)
v=bob(v)
v0=selectevery(v,2, 0)
v1=selectevery(v,2, 1)
n=interleave(v0,vi,v1)
return n.assumefps(29.970)
}
# Aa Bb Cc Dd
# AA Aa aa aB BB Bb bb bC CC Cc cc cD DD Dd dd dE
function slowmo_25(clip v)
{
v=assumeTFF(v)
v=bob(v)
v=interleave(v,v)
v0=selectevery(v,2, 0)
v1=selectevery(v,2, 1)
v1=deleteframe(v1,0)
vc=overlay(v0,v1, mode="blend", opacity=0.50)
n=interleave(v0,vc)
return n.assumefps(29.970)
}
|