FFmpeg Scroll Filter: Speed and Loop Guide

This guide demonstrates how to configure the scrolling speed and looping behavior using FFmpeg's built-in scroll video filter. You will learn the exact syntax for setting horizontal and vertical movement rates, understanding directional values, and managing continuous loops for text tickers, credits, or background animations.

Understanding the FFmpeg scroll Filter Syntax

The scroll filter shifts video frames horizontally, vertically, or both simultaneously. The basic syntax is:

ffmpeg -i input.mp4 -vf "scroll=horizontal=H_SPEED:vertical=V_SPEED" output.mp4

You can use either the full parameter names (horizontal, vertical) or their short aliases (h, v).

Configuring Scroll Speed

Speed in the scroll filter is determined in pixels per frame, not pixels per second. The value can be an integer or a floating-point number, and its sign controls the direction of the movement.

Horizontal Speed (horizontal or h)

  • Positive value (h=2): Shifts the frame to the left, causing the image to appear as though it is scrolling from right to left (standard news-ticker style).
  • Negative value (h=-2): Shifts the frame to the right, causing it to scroll from left to right.
  • Zero (h=0): No horizontal movement.

Example (scroll right to left at 3 pixels per frame):

ffmpeg -i input.mp4 -vf "scroll=horizontal=3" -c:a copy output.mp4

Vertical Speed (vertical or v)

  • Positive value (v=2): Shifts the frame upward, causing the image to scroll from bottom to top (standard end-credits style).
  • Negative value (v=-2): Shifts the frame downward, causing it to scroll from top to bottom.
  • Zero (v=0): No vertical movement.

Example (scroll bottom to top at 1.5 pixels per frame):

ffmpeg -i input.mp4 -vf "scroll=vertical=1.5" -c:a copy output.mp4

Calculating Pixels per Second

Because speed is measured per frame, the perceived speed depends on your video's frame rate (fps):

\[\text{Speed (pixels/frame)} = \frac{\text{Desired Speed (pixels/second)}}{\text{Video Frame Rate (fps)}}\]

For example, to scroll horizontally at 120 pixels per second on a 60 fps video:

\[120 / 60 = 2 \text{ pixels/frame}\]

ffmpeg -i input.mp4 -vf "scroll=h=2" output.mp4

Configuring Loop Options

The scroll filter features built-in, continuous edge-wrapping. As pixels move off one boundary of the frame, they immediately re-enter from the opposite side.

Native Wrapping

No extra filter flag is needed for the graphic itself to wrap; continuous looping of the visual canvas is enabled by default. If an image scrolls to the left, pixels exiting the left boundary seamlessly wrap around to the right edge.

Looping Static Images or Short Video Inputs

If your source file is shorter than the desired output duration, use the -stream_loop option prior to the input flag (-i):

ffmpeg -stream_loop -1 -i background.png -vf "scroll=h=2" -t 30 -pix_fmt yuv420p output.mp4
  • -stream_loop -1: Loops the input file infinitely.
  • -t 30: Limits the final output duration to 30 seconds.

Setting Initial Scroll Offsets

To set a specific starting offset for the loop rather than starting at (0,0), use the hpos (horizontal position) and vpos (vertical position) parameters. These accept a floating-point value between 0.0 and 1.0 representing a percentage of the frame dimensions:

ffmpeg -i input.mp4 -vf "scroll=h=2:hpos=0.5" output.mp4

This starts the horizontal scroll halfway across the width of the input frame.