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.mp4How it works:
[0:v]setpts=2*PTS[v]: Slows the input video down by a factor of 2.atempo=0.5: Slows down the audio speed to 50%.asetpts=2*PTS: Scales the audio timestamps by 2 to align with the new video length.-map "[v]" -map "[a]": Outputs the newly processed video and audio streams.
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.mp4How it works:
setpts=4*PTS: Multiplies the video timestamps by 4 (0.25x speed).atempo=0.5,atempo=0.5: Chains two half-speed filters together to achieve a quarter-speed effect (\(0.5 \times 0.5 = 0.25\)).asetpts=4*PTS: Multiplies the audio timestamps by 4 to match the 4x video slowdown.
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