Crop Video Using Time Variables in FFmpeg

Cropping a video dynamically based on playback time allows you to create effects like panning, tracking, and smooth transitions without third-party video editors. In FFmpeg, this is achieved using the native crop video filter combined with internal evaluation variables like t (current timestamp in seconds) and n (current frame number). This guide demonstrates the syntax, core variables, and real-world command examples for animating crop coordinates over time.

The Crop Filter Syntax

The standard FFmpeg crop filter takes four primary parameters:

crop=w:h:x:y
  • w: Output width.
  • h: Output height.
  • x: Horizontal position of the top-left corner of the crop area.
  • y: Vertical position of the top-left corner of the crop area.

While w and h generally remain static to prevent stream-level dimension mismatches, the x and y offsets are evaluated per frame. This makes them capable of evaluating mathematical expressions that change as playback progresses.

Key Dynamic Variables

FFmpeg exposes several built-in variables inside crop filter expressions:

  • t: The current presentation timestamp in seconds.
  • n: The sequential index of the current input frame (starting at 0).
  • in_w or iw: Input video width.
  • in_h or ih: Input video height.
  • out_w or ow: Output crop width.
  • out_h or oh: Output crop height.

Example 1: Linear Pan Across the Video

To move the crop window horizontally from left to right at a constant speed, multiply t by a velocity value (pixels per second):

ffmpeg -i input.mp4 -vf "crop=1280:720:'t*100':0" -c:a copy output.mp4

In this command:

  • The cropped resolution is fixed at 1280x720.
  • The horizontal coordinate x advances by 100 pixels for every second of video (t*100).
  • The vertical coordinate y remains fixed at 0.

To prevent the crop box from moving beyond the edge of the source video, wrap the expression with min():

ffmpeg -i input.mp4 -vf "crop=1280:720:'min(t*100, in_w-out_w)':0" -c:a copy output.mp4

Example 2: Oscillating (Back and Forth) Pan

You can use trigonometric functions like sin() or cos() to create a looping, pendulum-style movement:

ffmpeg -i input.mp4 -vf "crop=1280:720:'(in_w-out_w)/2 + ((in_w-out_w)/2)*sin(t)':0" -c:a copy output.mp4

Here, sin(t) fluctuates between -1 and 1 based on elapsed seconds, causing the horizontal crop frame to oscillate smoothly across the entire width of the input frame.


Example 3: Conditional Movement Based on Time Windows

You can shift crop positions only during specific segments of the video using the if() and between() functions.

To hold the crop box at x=0 for the first 5 seconds, move it to x=300 between seconds 5 and 10, and center it afterward:

ffmpeg -i input.mp4 -vf "crop=1280:720:'if(lt(t,5), 0, if(between(t,5,10), 300, (in_w-out_w)/2))':0" -c:a copy output.mp4

Important Practical Considerations

  1. Quoting Expressions: Always enclose expressions containing mathematical symbols or variable names in single quotes inside the filter string (e.g., 'min(t*50, in_w-out_w)') to prevent the shell from interpreting operators or commas.
  2. Dimension Parity: Many video codecs (such as H.264/AVC with yuv420p pixel format) require even dimensions. When dynamically computing offsets, ensure resulting coordinates stay valid, or enforce even values using trunc(expr/2)*2.
  3. Static Dimensions: The w and h parameters should remain constant. If you need dynamic zooming (changing width and height over time), use the zoompan filter instead of crop.