Pulsing Saturation Rhythmically with FFmpeg Hue

This article explains how to create a rhythmic, pulsing color saturation effect in a video using FFmpeg’s built-in hue filter. By pairing the filter's saturation parameter with dynamic mathematical expressions driven by time, you can automate cyclical oscillations in color intensity to sync with specific beats or visual rhythms.

Understanding the Filter Syntax

The hue filter in FFmpeg accepts mathematical expressions for its saturation parameter s. By binding this parameter to the timestamp variable t (current playback time in seconds), you can modulate saturation continuously throughout the clip.

A standard pulse relies on a sine wave function: sin(). Because sin() oscillates smoothly between -1 and 1, it is ideal for generating smooth, periodic pulses.

The basic formula for pulsing saturation is:

s = Baseline + Amplitude * sin(2 * PI * Frequency * t)
  • Baseline: The center saturation level (a value of 1 represents original saturation).
  • Amplitude: How far the saturation deviates above and below the baseline.
  • Frequency: The speed of the pulse in Hertz (cycles per second).
  • t: The current presentation timestamp in seconds.

The Basic Command

To oscillate the saturation between 0.2 (nearly black and white) and 1.8 (heavily saturated) at a rate of 1 cycle per second, use the following command:

ffmpeg -i input.mp4 -vf "hue=s='1 + 0.8*sin(2*PI*1*t)'" -c:a copy output.mp4

Syncing to a Specific BPM

To align the saturation pulse to music, convert beats per minute (BPM) into frequency in Hertz by dividing the BPM by 60:

\[\text{Frequency} = \frac{\text{BPM}}{60}\]

For a tempo of 120 BPM: \[\text{Frequency} = \frac{120}{60} = 2\text{ Hz}\]

The corresponding FFmpeg command is:

ffmpeg -i input.mp4 -vf "hue=s='1 + 0.8*sin(2*PI*2*t)'" -c:a copy output.mp4

Pulsing from Normal to Oversaturated

If you prefer the pulse to rise above normal saturation without dipping into desaturation, adjust the baseline and use the absolute value function abs() or an offset sine wave:

ffmpeg -i input.mp4 -vf "hue=s='1 + 1.5*abs(sin(PI*t))'" -c:a copy output.mp4

In this variation, the saturation starts at original intensity (1.0) and peaks sharply at 2.5 on every beat, providing a rhythmic, glowing accent.