Match Audio to Slow Motion Video in FFmpeg with asetpts

When you slow down a video in FFmpeg using the setpts filter, the audio track does not automatically slow down with it, resulting in desynchronized audio and video. To fix this, you must apply the asetpts filter in combination with the atempo filter to stretch the audio duration and realign its presentation timestamps (PTS) with the slowed-down video. This article provides a straightforward guide and the exact FFmpeg commands needed to match your audio perfectly to slow-motion video.

Understanding the Filters: setpts, asetpts, and atempo

To create a slow-motion effect in FFmpeg, two adjustments must be made: 1. Video Speed: The setpts (Set Presentation Timestamp) filter changes the display speed of video frames. For example, setpts=2*PTS doubles the timestamps, making the video play at 0.5x speed (twice as slow). 2. Audio Speed & Timestamps: The atempo filter alters the actual speed of the audio without changing its pitch. The asetpts filter then adjusts the audio presentation timestamps to match the new video timeline.

Because changing the audio tempo also changes its duration, combining atempo and asetpts is necessary to ensure the container syncs both streams correctly.


Command for 2x Slow Motion (0.5x Speed)

To slow both video and audio down to half-speed (0.5x), you need to double the video PTS (2*PTS), cut the audio tempo in half (0.5), and double the audio PTS (2*PTS).

Run the following command in your terminal:

ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=2*PTS[v];[0:a]atempo=0.5,asetpts=2*PTS[a]" -map "[v]" -map "[a]" output.mp4

How it works:


Command for 4x Slow Motion (0.25x Speed)

The atempo filter in FFmpeg has a limitation: it only accepts values between 0.5 (half speed) and 2.0 (double speed). If you want to slow your video down to 0.25x speed (four times slower), you must chain multiple atempo filters together while setting your PTS multiplier to 4.

Run the following command:

ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=4*PTS[v];[0:a]atempo=0.5,atempo=0.5,asetpts=4*PTS[a]" -map "[v]" -map "[a]" output.mp4

How it works:


Custom Speed Formula

To calculate the values for any custom slow-motion speed, use this simple formula:

\[\text{PTS Multiplier} = \frac{1}{\text{Desired Speed Speed Factor}}\]

For example, if you want your video to run at 0.8x speed: * PTS Multiplier: \(1 / 0.8 = 1.25\) * Video Filter: setpts=1.25*PTS * Audio Filter: atempo=0.8,asetpts=1.25*PTS

The resulting command would be:

ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=1.25*PTS[v];[0:a]atempo=0.8,asetpts=1.25*PTS[a]" -map "[v]" -map "[a]" output.mp4