API Reference¶
Powerpoint-like transitions implemented in VapourSynth.
All transitions, unless explicitly stated,
start with a pure frame from clipa
, or generally the first clip.
The transition ends with a pure frame from clipb
,
or generally the second clip.
If specified, the transition will be frames
long.
If not given (or given 0
), the transition will be the entire length of the shortest clip given.
The frames
parameter cannot excede the number of frames in either clip.
All transitions, unless explicitly stated,
consume frames from both clips in the same way.
As the transition progresses, frames from the end of the first clip
and from the start of the second clip are consumed simultaneously.
Frame 0 of the transition, although purely clipa
,
consumes the first frame from clipb
.
As an example, two 5-frame clips are faded,
with the frame numbers for clipa
on the left,
and for clipb
on the right.
The next example starts with a 15-frame long black clip, and a 10-frame long white clip. The transition lasts 4 frames. (Frames 12, 13, 14, 15 from the first clip are consumed concurrently with frames 1, 2, 3, 4 from the second clip). Notice how only frames 13 and 14 seem to be involved in the transition, as the first and last frames are pure frames from their respective clip.
For a 24-fps clip, specifying frames=24
will make the transition last a full second.
However, since the first and last frame of the transition
are purely from clipa
/ clipb
respectively,
frames=26
will give a visually one second long transition.
Enums and Constants¶
Non-directional Transitions¶
Linear Transitions
fade(hero[:96], dweebs[:96], frames=48).set_output()
-
vs_transitions.
fade_to_black
(src_clip, frames=None)[source]¶ Simple convenience function to
fade()
a clip to black.frames will be the number of frames consumed from the end of the src_clip during the transition. The first frame of the transition will be the first frame of the src_clip, while the last frame of the transition will be a pure black frame.
If frames is not given, will fade to black over the entire duration of the src_clip.
fade_to_black(dweebs[:96], frames=36).set_output()
-
vs_transitions.
fade_from_black
(src_clip, frames=None)[source]¶ Simple convenience function to
fade()
a clip into view from black.frames will be the number of frames consumed from the start of the src_clip during the transition. The first frame of the transition will be a pure black frame, while the last frame of the transition will be the last frame of the src_clip.
If frames is not given, will fade in over the entire duration of the src_clip.
fade_from_black(dweebs[:96], frames=36).set_output()
-
vs_transitions.
pixellate
(clipa, clipb, frames=None, lowest_target_w=2, lowest_target_h=2)[source]¶ Pixellate using rescales and aggressively fade at the center.
For large clips (width x height), the effect might not be too noticeable until the transition is near the middle point. This is due to bicubic downscales and point re-upscales at very high percentages of the original dimensions not being noticeably different.
Due to the way pixellation progress is calculated, the transition must be at least 4 frames long.
Longer transitions paired with larger target dimensions will cause the pixellation effect to appear to pause towards the center of the transition.
- Parameters
lowest_target_w (
Optional
[int
]) – An integer that determines the minimum width target to downscale to. By specifyingNone
, or by specifying the width of the source clips, the clips will not be scaled in the x or width direction, making this only pixellate vertically.lowest_target_h (
Optional
[int
]) – An integer that determines the minimum height target to downscale to. By specifyingNone
, or by specifying the height of the source clips, the clips will not be scaled in the y or height direction, making this only pixellate horizontally.
pixellate(hero[:84], dweebs[:84], frames=36).set_output()
Note
It’s recommended that you keep the pixellation effect limited to about 2 seconds long.
Any longer than that and the transition will yield unwanted effects towards the middle point.
Changing the target downscale dimensions is also not recommended.
Using None
or the source clip dimensions will yield interesting but generally terrible results.
Non-linear Transitions
-
vs_transitions.
poly_fade
(clipa, clipb, frames=None, exponent=1)[source]¶ Cross-fade clips according to a curve.
- Parameters
exponent (
int
) –An integer in the range from 1-5 (inclusive) where 1 represents a parabolic curve, 2 represents a quartic curve, and higher powers more resembling an tight ease-in-out function with constant speed for most of the transition.
An exponent of
1
is probably most useful, as higher exponents tend towards a constant speed and therefore are almost indistinguishable from a normalfade()
.
red = core.std.BlankClip(format=vs.RGB24, color=[255, 0, 0], length=96, width=320, height=40)
blue = core.std.BlankClip(format=vs.RGB24, color=[0, 0, 255], length=96, width=320, height=40)
div = core.std.Merge(red, blue, weight=0.5).resize.Point(height=2)
normal_fade = fade(blue, red, 96) + fade(red, blue, 96)
poly1 = poly_fade(blue, red, 96) + poly_fade(red, blue, 96)
poly2 = poly_fade(blue, red, 96, exponent=2) + poly_fade(red, blue, 96, exponent=2)
poly5 = poly_fade(blue, red, 96, exponent=5) + poly_fade(red, blue, 96, exponent=5)
core.std.StackVertical([normal_fade, div, poly1, div, poly2, div, poly5]).set_output()
Directional Transitions¶
Simple Transitions
-
vs_transitions.
wipe
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ A moving directional fade.
Similar to a
fade()
, but with a moving mask. The direction will be the direction the fade progresses towards. (i.e. the second clip begins fading in from the opposite given direction, and the first clip begins fading out starting from the opposite given direction, progressing towards direction)Uses a pure white to black gradient for the fade. If possible, uses numpy to generate the mask. If the numpy module is not found, falls back to a slower and possibly less accurate approach using lists and the
ctypes
module for writing to a VapourSynth frame.
wipe(hero[:84], dweebs[:84], frames=60).set_output()
Warning
This is broken (vs/zimg bug with full/limited range grayscale clips as of vs R52 // zimg 3.0)
-
vs_transitions.
linear_boundary
(clipa, clipb, clipa_movement, clipb_movement, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ Generalized boundary moving function for a linear transition between two stacked clips.
clipa can either slide out of view (having its size unchanged) or be squeezed to nothing from its original size. clipb can either slide into view (having its size unchanged) or be expanded from nothing to its full size. The boundary between the two clips moves towards direction.
The parameter clipa_movement can be
MiscConstants.SLIDE
orMiscConstants.SQUEEZE
. The parameter clipb_movement can beMiscConstants.SLIDE
orMiscConstants.EXPAND
.See
push()
,slide_expand()
,squeeze_slide()
, orsqueeze_expand()
for simpler aliases in the same form as most other linear, directional transitions.
-
vs_transitions.
push
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ Second clip pushes first clip off of the screen.
The first clip moves off of the screen moving towards the given direction.
Alias for
linear_boundary()
withclipa_movement=SLIDE
andclipb_movement=SLIDE
.
push(hero[:84], dweebs[:84], frames=60).set_output()
-
vs_transitions.
slide_expand
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ First clip slides out of view, while second clip expands into view from nothing.
clipa slides off of the screen towards direction. clipb expands into view from the opposite side of the given direction.
Alias for
linear_boundary()
withclipa_movement=SLIDE
andclipb_movement=EXPAND
.
slide_expand(hero[:96], dweebs[:96], frames=84).set_output()
-
vs_transitions.
squeeze_slide
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ First clip squeezes into nothing, while second clip slides into view.
clipa gets compressed off of the screen towards direction. clipb slides into view from the opposite side of the given direction.
Alias for
linear_boundary()
withclipa_movement=SQUEEZE
andclipb_movement=SLIDE
.
squeeze_slide(hero[:96], dweebs[:96], frames=84).set_output()
-
vs_transitions.
squeeze_expand
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ First clip squeezes into nothing, while second clip expands into view from nothing.
clipa gets compressed off of the screen towards direction. clipb expands into view from the opposite side of the given direction.
Alias for
linear_boundary()
withclipa_movement=SQUEEZE
andclipb_movement=EXPAND
.
squeeze_expand(hero[:96], dweebs[:96], frames=84).set_output()
-
vs_transitions.
cube_rotate
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>, exaggeration=0)[source]¶ Mimics a cube face rotation by adjusting the speed at which the
squeeze_expand()
boundary moves.Cube face containing clipa rotates away from the viewer in projected 3-D space towards direction.
- Parameters
exaggeration (
int
) – An integer between 0 and 100 (inclusive) representing how much the effect of the cosine wave should be exaggerated. 0 corresponds to a mathematically correct projection of a 90 degree rotation offset by 45 degrees. 100 corresponds to a fitted cosine wave.
For an explanation for the exaggeration effect, see the following video. The green (circle) is moving with an exaggeration of 0, representing a 2-D projection of the rotating cube face. The blue (cross) is moving with an exaggeration of 100, which is simply just a cosine wave.
For an exaggeration of 0, the initial and final velocities are pi/4 (0.785x)
,
and the velocity at the middle is pi / (2 * sqrt2) (1.11x)
(relative to the linear transition).
For an exaggeration of 100, the initial and final velocities are 0
,
and the velocity at the middle is pi/2 (1.571x)
(relative to the linear transition).
cube_rotate(hero[:96], dweebs[:96], frames=84).set_output()
cube_rotate(hero[:96], dweebs[:96], frames=84, exaggeration=100).set_output()
-
vs_transitions.
cover
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ Second clip slides in and covers the first clip which stays in place.
clipb slides into frame towards direction covering clipa.
cover(hero[:84], dweebs[:84]).set_output()
-
vs_transitions.
reveal
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ First clip slides out of view exposing second clip that stays in place.
clipa slides out of frame towards direction revealing clipb.
reveal(hero[:84], dweebs[:84]).set_output()
-
vs_transitions.
curtain_cover
(clipa, clipb, frames=None, axis=<Direction.HORIZONTAL: 'horizontal'>)[source]¶ Second clip comes into view from both directions split along the given axis covering the first clip in place.
clipb splits and moves inwards along the given axis.
If axis is given as
Direction.HORIZONTAL
, the clips must have an even integer width. If axis is given asDirection.VERTICAL
, the clips must have an even integer height.
curtain_cover(hero[:84], dweebs[:84]).set_output()
-
vs_transitions.
curtain_reveal
(clipa, clipb, frames=None, axis=<Direction.HORIZONTAL: 'horizontal'>)[source]¶ First clip splits apart to reveal the second clip in place.
clipa splits and moves apart along the given axis.
If axis is given as
Direction.HORIZONTAL
, the clips must have an even integer width. If axis is given asDirection.VERTICAL
, the clips must have an even integer height.
curtain_reveal(hero[:84], dweebs[:84]).set_output()
-
vs_transitions.
peel
(clipa, clipb, frames=None, direction=<Direction.LEFT: 'left'>)[source]¶ First clip peels away revealing the second clip beneath.
Both clips remain in place during the transition. The boundary between clips moves towards direction.
peel(hero[:84], dweebs[:84], frames=56).set_output()