Skip to content

FFmpeg Video Slow Motion Playback: My Learning Notes and Practical Tips

Hello everyone working with videos!

Have you ever encountered a situation where you wanted to use FFmpeg to slow down a video's playback speed, say by half, to see details more clearly or to follow along with something? Or perhaps, you had a series of sequentially taken images and wanted to combine them into a video, but hoped it would play slowly instead of flashing by quickly?

I've been pondering these issues recently and found several key points when handling them with FFmpeg, especially regarding speed settings and image sequences. I browsed some discussions on Reddit (like these two: How to make a video slow down and Creating video from images), combined with my own practice, and compiled these notes.

This note doesn't cover fancy "slow-motion effects"; it practically discusses how to slow down video playback speed using FFmpeg. We will specifically explore a common question: When using setpts to slow down, does the video's frame rate (FPS) change? And how to only extend playback time without changing the (file's marked) FPS? Finally, we'll also talk about how to correctly set the sometimes confusing frame rate (-r) parameter when generating videos from images. Rest assured, the methods discussed are basic and practical, applicable on Windows, Linux, and macOS, hoping to help those with similar needs.

Let's see how to make FFmpeg obediently "slow down"!


Behind Video Slow Motion: How Is Time Stretched?

Slowing down video playback essentially means extending the display time of each frame, increasing the total video duration to achieve a slower playback speed. FFmpeg primarily achieves this by adjusting two things:

  1. Presentation Timestamp (PTS): Simply put, it tells the player at which point in the video this frame should be displayed.
  2. Frame Rate: How many frames per second the video contains.

From reading discussions, I noticed the main sticking points are:

  • How to accurately control the slow-down multiplier?
  • After slowing down with setpts, does the output video's FPS change?
  • How to handle audio to stay synchronized when the video slows down?
  • What's the key to setting input and output frame rates (-r) when creating videos from images?
  • Are there any pitfalls using FFmpeg on different operating systems?

Let's address these one by one.


Method 1: Slowing Down an Existing Video (Basic Operation, Including FPS Clarification)

To slow down the playback speed of an existing video file, the most direct method is using the setpts filter (via the -vf parameter). For example, to make the video play at half speed:

bash
ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" output.mp4
  • Explanation: -vf "setpts=2.0*PTS" is key. It tells FFmpeg to multiply the original presentation timestamp (PTS) of each frame by 2. Thus, content that originally took 1 second to play now takes 2 seconds, naturally halving the playback speed. It directly acts on timestamps, stretching the time interval between frames.

  • So, does FPS change? How to only extend playback time without changing FPS?

    • Good question! setpts itself modifies timestamps; it does not directly change the FPS metadata recorded in the video stream (e.g., 30fps).
    • Typically (default behavior): When you use only setpts and do not forcibly specify a new frame rate at the output using -r, FFmpeg often keeps the output video file's FPS marking consistent with the input video.
    • The result: You get a video file with doubled duration, containing the same total number of frames as the original, and the file info shows the same FPS as before (e.g., still 30fps).
    • Therefore, the command ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" output.mp4 itself (in most cases) achieves your goal: it extends playback time while keeping the file's marked FPS unchanged. It achieves the slow-motion effect by making each frame display longer, not by changing the video's frame rate standard.
    • One thing to note: Although the file's marked FPS doesn't change, because the total duration increases while the total frame count remains the same, the number of new frames seen per second during actual playback is indeed reduced, which might feel less smooth than the original speed (but this is the desired effect of slow motion).
  • Versatility: This command is written the same on Windows, Linux, and macOS, very convenient.


Method 2: Handling Audio Synchronization (Sound Must Slow Down Too)

Slowing down only the visuals is often insufficient; if the video has audio, the sound must also slow down, otherwise, it will go out of sync. This requires adding the atempo audio filter (via the -af parameter):

bash
ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" -af "atempo=0.5" output.mp4
  • Explanation: -af "atempo=0.5" means reducing the audio playback speed to 0.5 times the original (i.e., half speed). This keeps the sound synchronized with the video.
    • Additional note: The speed factor for the atempo filter must be between 0.5 and 100.0. To slow down beyond 0.5x (e.g., 0.25x), use it consecutively, like -af "atempo=0.5,atempo=0.5".
  • Versatility: Similarly, this command is also cross-platform.

Method 3: Creating Slow-Motion Video from Image Sequence (Focus on Understanding -r!)

This scenario is also common: you have a series of images (e.g., img1.jpg, img2.jpg, ...) and want to make them into a video, hoping it plays relatively slowly. Command example:

bash
ffmpeg -r 1 -i img%d.jpg -vf "setpts=2.0*PTS" -r 30 -c:v libx264 -pix_fmt yuv420p output.mp4

Understanding the two -r parameters here is key:

  • First -r (input -r 1):

    • Defines how long each input image represents by default when reading. -r 1 means each image occupies 1 second (input base frame rate 1fps). 10 images mean 10 seconds of base material duration.
    • It sets the time base for the input material.
  • Second -r (output -r 30):

    • Specifies at what frame rate the final generated video file should play. -r 30 means outputting a 30fps video.
    • It determines the specification and smoothness of the output video. FFmpeg calculates the total frames needed based on the adjusted total duration from setpts (e.g., 10 images, input -r 1, setpts=2.0 results in a target duration of 20 seconds) and this output frame rate (30fps), resulting in 20 * 30 = 600 frames. It fills these 600 frames by repeating the original images (since setpts only changes timestamps), ensuring the output video meets the 30fps standard.
  • Collaborative work: Input -r sets base duration -> setpts adjusts duration -> Output -r sets final specification and frame filling method.

  • Cross-platform notes: Windows recommends using %d to match numbered sequence filenames; Linux/macOS can use * but %d is safer.


Method 4: Balancing Processing Speed and Output Quality

Video processing can be time-consuming; parameters can be adjusted for balance:

  • Speed up processing: Use -preset ultrafast / fast, etc.
  • Control quality: Use -crf value (e.g., -crf 20).

Balanced example:

bash
ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" -af "atempo=0.5" -c:v libx264 -preset fast -crf 20 -c:a aac output.mp4
  • Hardware acceleration: Consider -c:v h264_nvenc (Nvidia) or -c:v h264_videotoolbox (Apple) to speed up.

Alright, this time we deeply explored methods for achieving "slow motion playback" with FFmpeg and specifically clarified the relationship between setpts and FPS. Key takeaways:

  1. Slowing down existing videos:
    • Use -vf "setpts=N*PTS" (N>1) to extend video time.
    • This command typically keeps the output file's FPS marking consistent with the input, while extending playback time, meeting the need for "slow playback only, without changing (marked) FPS".
    • Don't forget to use -af "atempo=1/N" (note the 0.5x speed limit) for audio synchronization.
  2. Creating slow-motion videos from image sequences:
    • Input -r determines the time value of the images.
    • Output -r sets the playback frame rate for the final video (recommended 25 or 30).
    • setpts is used to further adjust the overall playback speed.
  3. Cross-platform: Core commands are universal; pay attention to filename patterns.
  4. Efficiency and quality: Use -preset and -crf for adjustment.