Return to the Avisynth home page
All Avisynth scripting statements have one of these forms:
variable_name = expression
expression
return expression
end
In the first case, expression is evaluated and the result (which is always a video clip) is assigned to variable_name. In the second case, expression is evaluated and the result is assigned to the special variable last. In the third case, expression is evaluated and is used as the "return value" of the script--that is, the video clip that will be seen by the application which opens the AVS file. The fourth case is equivalent to return last.
A variable_name can be up to 50 characters long and can contain letters, digits, and underscores (_), but no other characters. The name cannot start with a digit.
An expression can have one of these forms:
variable_name
Function(args)
expression.Function(args)
expression1 + expression2
expression1 ++ expression2
In the first case, the value of the expression is the value of the variable (which must have previously been assigned to). In the second case, the value is the return value of the function (which will be some filter producing a video clip). The third case is an alternate syntax (called "OOP notation") which is equivalent to Function(args,expression). The fourth and fifth cases are equivalent to UnalignedSplice(expression1,expression2) and AlignedSplice(expression1,expression2) respectively.
The functions in Avisynth's scripting language are video filters. The syntax of the function call for each filter is shown in the filter's description. Functions can take up to sixty arguments (hope that's enough), and the return value is always a video clip. Functions always produce a new video clip and never modify an existing one.
Args is a list of function arguments separated by commas. The list can be empty. Each argument must be a text string, an integer, a floating-point number, or a video clip (that is, an expression). If the filter function expects a video clip as its last argument, and that argument is not supplied, then the clip in the special last variable will be used.
You can also make function calls without parentheses, e.g. FilterName arg1,arg2. The primary reason for this is to retain compatibility with old scripts. However, it's sometimes convenient to leave off the parentheses when there's no possibility of confusion.
A text string is surrounded either by "quotation marks" or by ``TeX-style quotes''. A text string can contain any character except the terminating quotation mark or double-apostrophe. If you need to put a quotation mark inside a string, use the TeX-style notation. Alternately, you can use Windows extended-ASCII curly-quotes instead of straight quotes to get around this limitation.
An integer is a string of digits, optionally with a + or - at the beginning. A floating-point number is a string of digits with a period (.) somewhere in it and an optional + or -. For example, +1. is treated as a floating-point number.
You can also enter a hexadecimal number by preceding it with a $. This is treated as an integer. Several filters use this notation for specifying colors. For example, $FF8800 is a shade of orange. This is the same as the notation used in HTML, except that HTML uses a # at the beginning instead of a $.
Each Avisynth statement must be on its own line. There is no provision for putting more than one statement on a single line or splitting a single statement across multiple lines.
Avisynth ignores anything from a # character to the end of that line. This can be used to add comments to a script.
Avisynth ignores case: aViSouRCe is just as good as AVISource.
AVISource("filename")
OpenDMLSource("filename")
AVIFileSource("filename")
WAVSource("filename")
AVISource takes a single argument, which is a file name in quotes, and reads in the file using either the Video-for-Windows "AVIFile" interface, or Avisynth's built-in OpenDML code (taken from VirtualDub). This filter can read any file for which there's an AVIFile handler. This includes not only AVI files but also WAV files, AVS (Avisynth script) files, and VDR (VirtualDub frameserver) files.
The AVISource filter examines the file to determine its type and passes it to either the AVIFile handler or the OpenDML handler as appropriate. In case you have trouble with one or the other handler, you can also use the OpenDMLSource and AVIFileSource filters, which force the use of one or the other handler. Either handler can read ordinary (<2GB) AVI files, but only the OpenDML handler can read larger AVI files, and only the AVIFile handler can read other file types like WAV, VDR and AVS.
Because the AVIFile interface supports WAV files, I added WAVSource as an alias for AVIFileSource.
Examples:
AVISource("d:\capture.avi") # C programmers note: backslashes not doubled
AVISource("c:/capture/00.avi") # forward slashes work too
AVISource("f:\soundtrack.wav") # this works
WAVSource("f:\soundtrack.wav") # so does this
SegmentedAVISource("base-filename"[,...])
The SegmentedAVISource filter automatically loads up to 100 avi files per argument (using AVISource) and splices them together (using UnalignedSplice). If "d:\filename.ext" is passed as an argument, the files d:\filename.00.ext, d:\filename.01.ext and so on through d:\filename.99.ext will be loaded. Any files in this sequence that don't exist will be skipped.
DirectShowSource("filename")
DirectShowSource reads filename using DirectShow, the same multimedia playback system which Windows Media Player uses. It can read most formats which Media Player can play, including MPEG, MP3, and QuickTime, as well as AVI files that AVISource doesn't support (like DV type 1, or files using DirectShow-only codecs). Try reading AVI files with AVISource first, and if that doesn't work then try this filter instead.
ASF currently doesn't work.
IPCSource("name")
IPCSource opens a communication channel with an Avisynth-compatible frame server running in another process on the same machine. IPC stands for "inter-process communication." The only frame server you can connect to currently is the Premiere export plugin. I probably should have made Avisynth's frame server compatible with VirtualDub's, but at least for now it's not. You can open VDR files with AVISource.
Blackness(duration,clip)
The Blackness filter produces a pitch-black, silent video clip of the specified duration (in frames). The clip passed as an argument is used as a template for frame rate, image size, and so on.
Version()
The Version filter generates a 512x32 pixel, 15fps, 10-second, RGB-format video clip with a short version and copyright statement in orange 24-point Arial text.
HorizontalReduceBy2(clip)
VerticalReduceBy2(clip)
ReduceBy2(clip)
HorizontalReduceBy2 reduces the horizontal size of each frame by half, and VerticalReduceBy2 reduces the vertical size by half. Chain them together (in either order) to reduce the whole image by half. You can also use the shorthand ReduceBy2, which is the same as HorizontalReduceBy2 followed by VerticalReduceBy2.
The filter kernel used is (1/4,1/2,1/4), which is the same as in VirtualDub's "2:1 reduction (high quality)" filter. This avoids the aliasing problems that occur with a (1/2,1/2) kernel. VirtualDub's "resize" filter uses a third, fancier kernel for 2:1 reduction, but I experimented with it and found that it actually produced slightly worse-looking MPEG files--presumably because it sharpens edges slightly, and most codecs don't like sharp edges.
If your source video is interlaced, the VerticalReduceBy2 filter will deinterlace it as a side-effect. If you plan to produce output video in a size like 320x240, I recommend that you capture at full interlaced vertical resolution (320x480) and use VerticalReduceBy2. You will get much better-looking output. My Huffyuv utility will compress captured video about 2:1, losslessly, so you can capture 320x480 in about the same space as it used to take to capture 320x240. (If your disk has the capacity and throughput to support it, you can even capture at 640x480 and use both HorizontalReduceBy2 and VerticalReduceBy2. But this won't improve the quality as much, and if you have to go to MotionJPEG to achieve 640x480, you're probably better off with Huffyuv at 320x480.)
BilinearResize(target-width,target-height,clip)
BilinearResize(source-left,source-top,source-width,source-height,target-width,target-height,clip)
The BilinearResize filter rescales the input video frames to an arbitrary new resolution. If you supply the optional source arguments, the result is the same as if you had applied Crop with those arguments to the clip before BilinearResize (except faster).
BilinearResize uses standard bilinear filtering and is almost identical to VirtualDub's "precise bilinear" resizing option. It's only "almost" because VirtualDub's filter seems to get the scaling factor slightly wrong, with the result that pixels at the top and right of the image get either clipped or duplicated. (This error is noticeable when expanding the frame size by a factor or two or more, but insignificant otherwise, so I wouldn't worry too much about it.)
Examples:
# Load a video file and resize it to 240x180 (from whatever it was before)
AVISource("video.avi").BilinearResize(240,180)
# Load a 720x480 (CCIR601) video and resize it to 352x240 (VCD), preserving the correct aspect ratio
AVISource("dv.avi").BilinearResize(8,0,704,480,352,240)
# Extract the upper-right quadrant of a 320x240 video and zoom it to fill the whole frame
BilinearResize(160,0,160,120,320,240)
BicubicResize([b,c,]target-width,target-height,clip)
BicubicResize([b,c,]source-left,source-top,source-width,source-height,target-width,target-height,clip)
BicubicResize is similar to BilinearResize, except that instead of a linear filtering function it uses the Mitchell-Netravali two-part cubic. The parameters b and c can be used to adjust the properties of the cubic. With b = 0 and c = 0.75 the filter is exactly the same as VirtualDub's "precise bicubic," and the results are identical except for the VirtualDub scaling problem mentioned above. The default is b = 1/3 and c = 1/3, which were the values recommended by Mitchell and Netravali as yielding the most visually pleasing results in subjective tests of human beings. Larger values of b and c can produce interesting op-art effects--for example, try b = 0 and c = -5.
If you are magnifying your video, you will get much better-looking results with BicubicResize than with BilinearResize. However, if you are shrinking it, you are probably just as well off, or even better off, with BilinearResize. Although VirtualDub's bicubic filter does produce better-looking images than its bilinear filter, this is mainly because the bicubic filter sharpens the image, not because it samples it better. Sharp images are nice to look at--until you try to compress them, at which point they turn nasty on you very quickly. The BicubicResize default doesn't sharpen nearly as much as VirtualDub's bicubic, but it still sharpens more than the bilinear. If you plan to encode your video at a low bitrate, I wouldn't be at all surprised if BilinearResize yields better quality.
Crop(left,top,width,height,clip)
CropBottom(count,clip)
Crop crops excess pixels off of each frame. If your source video has 720x480 resolution, and you want to reduce it to 352x240 for VideoCD, here's the correct way to do it:
# Convert CCIR601 to VCD, preserving the correct aspect ratio ReduceBy2 Crop(4,0,352,240)
YUY2 format only stores color information for every two pixels horizontally, so if you're processing in YUY2 mode, left and width must be even.
The alternative CropBottom syntax is useful for cropping garbage off the bottom of a clip captured from VHS tape. It removes count lines from the bottom of each frame.
AddBorders(left,top,right,bottom,clip)
AddBorders adds black borders around the image, with the specified widths (in pixels). YUY2 format only stores color information for every two pixels horizontally, so if you're processing in YUY2 mode, left and right must be even.
Be aware that many lossy compression algorithms don't deal well with solid-color borders, unless the border width happens to be a multiple of the block size (16 pixels for MPEG).
You can use this filter in combination with Crop to shift an image around without changing the frame size. For example:
# Shift a 352x240 image 2 pixels to the right Crop(0,0,350,240).AddBorders(2,0,0,0)
Levels(input_low,gamma,input_high,output_low,output_high,clip)
The Levels filter adjusts brightness, contrast, and gamma. The input_low and input_high parameters determine what input pixel values are treated as pure black and pure white; the output_low and output_high parameters determine the output values corresponding to black and white; and the gamma parameter controls the degree of nonlinearity in the conversion. To be precise, the conversion function is:
output = [(input - input_low) / (input_high - input_low)]1/gamma (output_high - output_low) + output_low
This is one of those filters for which it would really be nice to have a GUI. Since I can't offer a GUI (at least not in Avisynth's current form), I decided I could at least make this filter compatible with VirtualDub's. You should be able to take the numbers from VirtualDub's Levels dialog and pass them as parameters to the Levels filter and get the same results.
When processing data in YUY2 mode, Levels only gamma-corrects the luma information, not the chroma. Gamma correction is really an RGB concept, and I don't know how to do it properly in YUY2. However, if gamma = 1.0, the filter should have the same effect in RGB and YUY2 modes.
Examples:
# do nothing Levels 0,1,255,0,255 # gamma-correct image for display in a brighter environment Levels 0,1.3,255,0,255 # invert the image (make a photo-negative) Levels 0,1,255,255,0
Blur(amount,clip)
Sharpen(amount,clip)
These are simple 3x3-kernel blurring and sharpening filters. The largest allowable argument for Blur is about 1.58, which corresponds to an even 3x3-pixel blur. A value of 1.0 gets you a (1/4,1/2,1/4) kernel. If you want a large-radius Gaussian blur, I recommend chaining several copies of Blur(1.0) together. (Anybody remember Pascal's triangle?)
Negative arguments to Blur actually sharpen the image, and in fact Sharpen n is just an alias for Blur -n. The smallest allowable argument to Blur is -1.0, and the largest to Sharpen is 1.0.
SpatialSoften(radius,luma_threshold,chroma_threshold,clip)
TemporalSoften(radius,luma_threshold,chroma_threshold,clip)
The SpatialSoften and TemporalSoften filters remove noise from a video clip by selectively blending pixels. These filters can work miracles, and I highly encourage you to try them. But they can also wipe out fine detail if set too high, so don't go overboard. And they are very slow, especially with a large value of radius, so don't turn them on until you've got everything else ready.
SpatialSoften replaces each sample in a frame with the average of all nearby samples with differ from the central sample by no more than a certain threshold value. "Nearby" means no more than radius pixels away in the x and y directions. The threshold used is luma_threshold for the Y (intensity) samples, and chroma_threshold for the U and V (color) samples.
TemporalSoften is similar, except that it looks at the same pixel in nearby frames, instead of nearby pixels in the same frame. All frames no more than radius away are examined. This filter doesn't seem to be as effective as SpatialSoften.
I encourage you to play around with the parameters for these filters to get an idea of what they do--for example, try setting one of the three parameters to a very high value while leaving the others low, and see what happens. Note that setting any of the three parameters to zero will cause the filter to become a very slow no-op.
As of Avisynth v0.3, the SpatialSoften and TemporalSoften filters work only with YUY2 input. You can use the ConvertToYUY2 filter if your input is not in YUY2 format.
FixLuminance(intercept,slope,clip)
My VCR has the annoying habit of making the top of each frame brighter than the bottom. The purpose of this filter is to progressively darken the top of the image to compensate for this. If you've noticed a similar problem with your VCR, email me and I'll finish this explanation of how the filter works. Otherwise, you can pretend it doesn't exist.
This filter works only with YUY2 input.
Letterbox(top,bottom,clip)
Letterbox simply blackens out the top top and the bottom bottom scanlines of each frame. This has a couple of uses: one, it can eliminate stray video noise from the existing black bands in an image that's already letterboxed; two, it can eliminate the garbage lines that often appear at the bottom of the frame in captures from VHS tape.
The functionality of Letterbox can be duplicated with a combination of Crop and AddBorders, but Letterbox is faster and easier.
Generally, it's better to crop this stuff off using Crop or CropBottom than to hide it with Letterbox. However, in some cases, particularly if you're compressing to MPEG, it's better to use Letterbox because it lets you keep a standard frame size like 352x288 or 320x240. Some MPEG players get confused when the source video has a strange frame size.
Subtitle("text",x,y,first-frame,last-frame,"font-name",point-size[,text-color[,halo-color]],clip)
Subtitle("text",clip)
The Subtitle filter adds a single line of anti-aliased text to a range of frames. If you want more than one subtitle, or a subtitle that takes more than one line, you have to chain several Subtitle filters together. This filter is obviously unsuitable for anything more than occasional use. I use it occasionally.
The text color and halo color should be given as hexadecimal RGB values, as in HTML--except that they start with $ instead of #. (I was already using # to introduce a comment.)
The alternate, short form is useful when you don't really care what the subtitle looks like as long as you can see it--for example, when you're using StackVertical and its ilk to display several versions of a frame at once, and you want to label them to remember which is which.
This filter is used internally by Avisynth for the Version command and for reporting error messages, and the subtitling apparatus is also used by ShowFrameNumber.
PeculiarBlend(cutoff,clip)
This filter blends each frame with the following frame in a peculiar way. The portion of the frame below the (cutoff)th scanline is unchanged. The portion above the (cutoff-30)th scanline is replaced with the corresponding portion of the following frame. The 30 scan lines in between are blended incrementally to disguise the switchover.
You're probably wondering why anyone would use this filter. Well, it's like this. Most videos which were originally shot on film use the 3:2 pulldown technique which is described in the description of the Pulldown filter. But some use a much nastier system in which the crossover to the next frame occurs in the middle of a field--in other words, individual fields look like one movie frame on the top, and another on the bottom. This filter partially undoes this peculiar effect. It should be used after th before the Pulldown filter. To determine cutoff, examine a frame which is blended in this way and set cutoff to the number of the first scanline in which you notice a blend.
As of Avisynth v0.3, this filter works only with YUY2 input. You can use the ConvertToYUY2 filter if your input is not in YUY2 format.
ConvertToYUY2(clip)
ConvertToRGB(clip)
Avisynth can deal internally with two color formats, RGB and YUY2. These two filters convert between them. If the video is already in the specified format, it will be passed through unchanged.
As of Avisynth v0.3, the following filters do not support RGB input:
If you try to use any of these filters with RGB input, you will get an error. Putting ConvertToYUY2 just before the offending filter should resolve the problem. All Avisynth filters support YUY2 input.
In most cases, the ConvertToRGB filter should not be necessary. If Avisynth's output is in YUY2 format and an application expects RGB, the system will use the installed YUY2 codec to make the conversion. However, if there's no installed YUY2 codec, or if (as is the case with ATI's YUY2 codec) the codec converts from YUY2 to RGB incorrectly, you can use Avisynth's built-in filter to convert instead.
Huffyuv will act as the system YUY2 codec if there's no other codec installed, so if you install Huffyuv and uninstall all other YUY2 codecs, then you'll never need ConvertToRGB.
Example:
# There is a slight distortion caused by the conversion between YUV and RGB. # Let's see if we can see it. control = ConvertToYUY2() test = ConvertToYUY2(ConvertToRGB(ConvertToYUY2(ConvertToRGB(ConvertToYUY2(ConvertToRGB(control)))))) return Subtract(test,control)
AssumeFrameBased(clip)
AssumeFieldBased(clip)
Avisynth keeps track of whether a given clip is field-based or frame-based. If the clip is field-based is also keeps track of the parity of each field (that is, whether it's the top or the bottom field of a frame). If the clip is frame-based it keeps track of the dominant field in each frame (that is, which field in the frame comes first when they're separated).
However, this information isn't necessarily correct, because field information usually isn't stored in video files and Avisynth's source filters just guess at it. AssumeFrameBased and AssumeFieldBased let you tell Avisynth the correct type of a clip.
AssumeFrameBased throws away the existing information and assumes that the clip is frame-based, with the bottom (even) field dominant in each frame. (This happens to be what the source filters guess.) If you want the top field dominant, use ComplementParity afterwards.
AssumeFieldBased throws away the existing information and assumes that the clip is field-based, with the even-numbered fields being bottom fields and the odd-numbered fields being top fields. If you want it the other way around, use ComplementParity afterwards.
ComplementParity(clip)
If the input clip is field-based, ComplementParity changes top fields to bottom fields and vice-versa. If the input clip is frame-based, it changes each frame's dominant field (bottom-dominant to top-dominant and vice-versa).
SeparateFields(clip)
NTSC and PAL video signals are sequences of fields, but all capture cards that I'm aware of capture two fields at a time and interlace (or "weave") them into frames. So frame 0 in the capture file contains fields 0 and 1; frame 1 contains fields 2 and 3; and so on. SeparateFields takes a frame-based clip and splits each frame into its component fields, producing a new clip with twice the frame rate and twice the frame count. This is useful if you would like to use Trim and similar filters with single-field accuracy.
SeparateFields uses the field-dominance information in the source clip to decide which of each pair of fields to place first in the output. If it gets it wrong, use ComplementParity before SeparateFields. If it gets it really wrong, you may want to use AssumeFrameBased also.
This filter has no effect if the clip is already field-based.
Weave(clip)
Weave is the opposite of SeparateFields: it takes pairs of fields from the input video clip and combines them together to produce interlaced frames. The new clip has half the frame rate and frame count. Weave uses the frame-parity information in the source clip to decide which field to put on top. If it gets it wrong, use ComplementParity beforehand or SwapFields afterwards.
All Avisynth filters keep track of field parity, so Weave will always join the fields together in the proper order. If you want the other order, you'll have to use ComplementParity beforehand or SwapFields afterwards.
This filter has no effect if the clip is already frame-based.
DoubleWeave(clip)
If the input clip is field-based, the DoubleWeave filter operates like Weave, except that it produces double the number of frames: instead of combining fields 0 and 1 into frame 0, fields 2 and 3 into frame 1, and so on, it combines fields 0 and 1 into frame 0, fields 1 and 2 into frame 1, and so on. It does not change the frame rate or frame count.
If the input clip is frame-based, this filter acts just as though you'd separated it into fields with SeparateFields first.
Weave is actually just a shorthand for DoubleWeave followed by SelectEven.
Most likely you will want to use a filter like SelectOdd or Pulldown after using this filter, unless you really want a 50fps or 60fps video. It may seem inefficient to interlace every pair of fields only to immediately throw away half of the resulting frames. But actually, because Avisynth only generates frames on demand, frames that are not needed will never be generated in the first place.
If you're processing field-based video, like video-camera footage, you probably won't need this filter. But if you're processing NTSC video converted from film and you plan to use the Pulldown filter, you need to use DoubleWeave first. See the Pulldown filter for an explanation.
If you're processing PAL video converted from film, you don't need Pulldown, but you might want to use DoubleWeave in the following situation:
# Duplicate the functionality of the VirtualDub "PAL deinterlace" filter DoubleWeave SelectOdd
Bob(clip)
Bob(b,c,clip)
Bob takes a clip and bob-deinterlaces it. This means that it enlarges each field into its own frame by interpolating between the lines. The top fields are nudged up a little bit compared with the bottom fields, so the picture will not actually appear to bob up and down. However, it will appear to "shimmer" in stationary scenes because the interpolation doesn't really reconstruct the other field very accurately.
This filter uses BicubicResize to do its dirty work. You can use the second form above to tweak the values of b and c.
SwapFields(clip)
The SwapFields filter swaps image line 0 with line 1, line 2 with line 3, and so on, thus effectively swapping the two fields in an interlaced frame It's the same as SeparateFields.ComplementParity.Weave (and it's implemented that way).
Trim(first-frame,last-frame,clip)
Trim trims a video clip so that it includes only the frames first-frame through last-frame. The audio is similarly trimmed so that it stays synchronized. If you pass 0 for last-frame it means "end of clip." For example:
Trim(100,0) # delete the first 100 frames
AlignedSplice(clip1,clip2[,...])
UnalignedSplice(clip1,clip2[,...])
AlignedSplice and UnalignedSplice join two or more video clips end to end. The difference between the filters lies in the way they treat the sound track. UnalignedSplice simply concatenates the sound tracks without regard to synchronization with the video. AlignedSplice cuts off the first sound track or inserts silence as necessary to ensure that the second sound track remains synchronized with the video.
You should use UnalignedSplice when the soundtracks being joined were originally contiguous--for example, when you're joining files captured with AVI_IO. Slight timing errors may lead to glitches in the sound if you use AlignedSplice in these situations.
Avisynth's scripting language provides + and ++ operators as synonyms for UnalignedSplice and AlignedSplice respectively.
Example 1:
# Join segmented capture files to produce a single clip
UnalignedSplice(AVISource("capture1.avi"), AVISource("capture2.avi"), AVISource("capture3.avi"))
# or: AVISource("capture1.avi") + AVISource("capture2.avi") + AVISource("capture3.avi")
Example 2:
# Extract three scenes from a clip and join them together in a new order
AVISource("video.avi")
edited_video = Trim(2000,2500) ++ Trim(3000,3500) ++ Trim(1000,1500)
Dissolve(overlap,clip1,clip2[,...])
Dissolve is like AlignedSplice, except that the clips are combined with some overlap. The last overlap frames of the first video stream are blended progressively with the first overlap frames of the second video stream so that the streams fade into each other. The audio streams are blended similarly.
The term "dissolve" is sometimes used for a different effect in which the transition is pointwise rather than gradated. This filter won't do that.
Reverse(clip)
This filter makes a clip play in reverse. This is useful for watching people walk backwards while listening to hidden satanic messages.
FadeOut(number-of-frames,clip)
FadeOut2(number-of-frames,clip)
FadeOut and FadeOut2 cause the video stream to fade linearly to black at the end. The sound track (if present) also fades linearly to silence. The fading affects only the last number-of-frames frames of the video. The last frame of the video becomes almost-but-not-quite black. An additional perfectly black frame is added at the end, thus increasing the total frame count by one.
FadeOut2 works similarly, except that two black frames are added at the end instead of one. The only purpose of this is to work around a bug in Windows Media Player. All the WMP versions that I've tested fail to play the last frame of an MPEG file--instead, they stop on the next-to-last frame when playback ends. This leaves an unsightly almost-but-not-quite-black frame showing on the screen when the movie ends if you use FadeOut. FadeOut2 avoids this problem.
FadeOut(n,clip) is just a shorthand for Dissolve(n,clip,Blackness(n+1,clip)) (or n+2 instead of n+1 for FadeOut2). There is no corresponding FadeIn command, but you can get the same effect by reversing the arguments to Dissolve: Dissolve(n,Blackness(n+1,clip),clip).
SelectEven(clip)
SelectOdd(clip)
SelectEven makes an output video stream using only the even-numbered frames from the input. SelectOdd is its odd counterpart.
Since frames are numbered starting from zero, SelectEven actually selects the first, third, fifth,... frames by human counting conventions.
Pulldown(a,b,clip)
The Pulldown filter simply selects two out of every five frames of the source video. The frame rate is reduced to two-fifths of its original value. For example, Pulldown 0,2 selects frames 0, 2, 5, 7, 10, 12, and so on.
This filter is designed to be used after DoubleWeave, and its purpose is to recover the original frames of a movie that was converted to video using the 3:2 pulldown process.
The reason you need to use DoubleWeave first is that capture cards combine fields in the wrong way. In terms of fields, the 3:2 pulldown sequence is simply "A A B B B C C D D D ...", where "A" through "D" represent the original film frames. But the capture cards combine the fields into frames with no respect for the pulldown pattern, and you get this:
A B C D D (30fps) A B B C D
In this pattern frame C is never shown by itself. After DoubleWeave every pair of fields gets its own frame, so the video stream will begin like this:
A A B B C C D D D (60fps) A B B B B C C D D * * * *
Now each movie frame has at least one video frame to itself. At this point the Pulldown filter with arguments of 0,3 will select the frames marked with a *, and you'll get
A B C D (24fps) A B C D
... which is what you really want.
This is all very complicated to describe, but in practice undoing the pulldown is just a matter of inserting some boilerplate code. See the example below under ShowFiveVersions.
Pulldown(a,b) is implemented internally as SelectEvery(5,a,b).AssumeFrameBased.
Interleave(clip,clip[,...])
Interleave interleaves frames from several clips on a frame-by-frame basis, so for example if you give three arguments, the first three frames of the output video are the first frames of the three source clips, the next three frames are the second frames of the source clips, and so on.
SelectEvery(step-size[,offset1[,offset2[,...]]],clip)
SelectEvery is a generalization of filters like SelectEven and Pulldown. I think the easiest way to describe it is by example:
SelectEvery(2,0,clip) # identical to SelectEven(clip) SelectEvery(2,1,clip) # identical to SelectOdd(clip) SelectEvery(10,3,6,7,clip) # select frames 3,6,7,13,16,17,23,26,27... from source clip SelectEvery(9,clip) # select frames 0,9,18,27,... (second argument of 0 is assumed)
And how about this:
# Take a 24fps progressive input clip and apply 3:2 pulldown, # yielding a 30fps interlaced output clip AssumeFrameBased SeparateFields SelectEvery(8, 0,1, 2,3,2, 5,4, 7,6,7) Weave
FreezeFrame(first-frame,last-frame,source-frame,clip)
The FreezeFrame filter replaces all the frames between first-frame and last-frame with a copy of source-frame. The sound track is not modified. This is useful for covering up glitches in a video in cases where you have a similar glitch-free frame available.
DeleteFrame(frame,clip)
DeleteFrame deletes a single frame, given as an argument. The sound track is not modified, so if you use this filter too many times in a row you may get noticeable desynchronization.
If you want to delete a range of frames (a to b, say) along with the corresponding portion of the soundtrack, you can do it like this: Trim(0,a-1) ++ Trim(b+1,0).
DuplicateFrame(frame,clip)
DuplicateFrame is the opposite of DeleteFrame--it duplicates a single frame given as an argument. As with DeleteFrame, the sound track is not modified.
AudioDub(video-clip,audio-clip)
AudioDub takes the video stream from the first argument and the audio stream from the second argument and combines them into a single clip. If either track isn't available, it tries it the other way around, and if that doesn't work it returns an error. Example:
# Load capture segments from patched AVICAP32 which puts
# video in multiple AVI segments and audio in a WAV file
video = AVISource("capture1.avi") + AVISource("capture2.avi")
audio = WAVSource("capture.wav")
AudioDub(video, audio)
DelayAudio(seconds,clip)
DelayAudio delays the audio track by seconds seconds. Seconds can be negative and/or have a fractional part. Example:
# Play audio half a second earlier DelayAudio(-0.5)
Subtract(clip1,clip2)
Subtract produces an output clip in which every pixel is set according to the difference between the corresponding pixels in clip1 and clip2. More specifically, it sets each pixel to (50% gray) + (clip1 pixel) - (clip2 pixel). You can use Levels afterwards if you want to increase the contrast. For example:
# Make the differences between clip1 and clip2 blatantly obvious Subtract(clip1,clip2).Levels(127,1,129,0,255)
If you want to see the deltas between adjacent frames in a single clip, you can do it like this:
Subtract(clip.Trim(1,0),clip)
ShowFrameNumber(clip)
ShowFrameNumber draws text on every frame indicating what number Avisynth thinks it is. This is sometimes useful when writing scripts. If you apply additional filters to the clip produced by ShowFrameNumber, they will treat the text on the frame just as they would treat an image, so the numbers may be distorted by the time you see them.
StackHorizontal(clip1,clip2[,...])
StackVertical(clip1,clip2[,...])
StackHorizontal takes two or more video clips and displays them together in left-to-right order. The heights of the images and their color formats must be the same. Most other information (sound track, frame rate, etc) is taken from the first clip. StackVertical does the same, except from top to bottom. Examples:
# Compare frames with and without noise reduction StackVertical(last, last.SpatialSoften(2,3,6)) # a b # Show clips in variables a,b,c,d in a box like this: c d StackVertical(StackHorizontal(a,b),StackHorizontal(c,d))
ShowFiveVersions(clip1,clip2,clip3,clip4,clip5)
ShowFiveVersions takes five video streams and combines them in a staggered arrangement from left to right. The only use for this (that I can think of) is to help find the NTSC pulldown pattern. You can do this using code like this:
# View all five pulldown patterns at once
DoubleWeave()
# put a resizing filter here if necessary (see below)
a = Pulldown(0,2).Subtitle("0,2")
b = Pulldown(1,3).Subtitle("1,3")
c = Pulldown(2,4).Subtitle("2,4")
d = Pulldown(0,3).Subtitle("0,3")
e = Pulldown(1,4).Subtitle("1,4")
ShowFiveVersions(a,b,c,d,e)
This code displays the five pulldown patterns with some text identifying which is which. I then look through the movie and pick the pattern which avoids blending frames. (In ordinary pulldown, there will actually be two which work equally well. Look at the diagrams in the Pulldown filter section to see why.) If none of the five works, then you're dealing with one of the more perverse forms of pulldown and you might want to use PeculiarBlend.
By the way, if you're planning to capture at a high resolution and then scale down, as I recommend elsewhere, you should probably place the ReduceBy2 or BilinearResize or whatever just after the DoubleWeave statement in the code above. Before DoubleWeave it won't work correctly, and if you postpone it any further, ShowFiveVersions will produce a really big frame.
Animate(start-frame,end-frame,"filter",start-args,end-args)
Animate is a meta-filter which evaluates its parameter filter with continuously varying arguments. At frame start-frame and earlier, filter is evaluated with the arguments given by start-args. At frame end-frame and later, filter is evaluated with the arguments given by end-args. In between, the arguments are linearly interpolated for a smooth transition.
Filter must be enclosed in quotation marks, and the two nested argument lists are not parenthesized. Strings and video clips can't be interpolated, and therefore must be identical in the two argument lists. You can't use OOP notation or implicit last with this filter, even if the filter in the filter argument normally allows them.
This filter will not correctly handle a changing sound track, so I don't recommend its use with filters which modify the sound track. And for heaven's sake don't make the initial and final parameters yield a different output frame size.
The filter argument can even be Animate if you want quadratic rather than linear interpolation, but I'm not going to think about this too much because my head might explode.
Examples:
# Make a scrolling version of the "Version" video ver = Version() return Animate(0,149,"Crop", 0,0,64,32,ver, 448,0,64,32,ver) # Fade to white Animate(100,200,"Levels", 0,1,255,0,255,last, 0,1,255,255,255,last) # Do a gradual zoom into the center of a 320x240 video, starting at # 1:1 magnification in frame 100 and ending with 4:1 magnification # in frame 200 Animate(100,200, "BicubicResize", 0,0,320,240,320,240,last, 120,90,80,60,320,240,last) # Make the text "Hello, World!" zoom out from the center of a 320x240 video Animate(0,48,"Subtitle", "Hello, World!",160,120,0,99999,"Arial",0,last, "Hello, World!",25,130,0,99999,"Arial",48,last)