Skip to content

FFmpeg Video Slow Playback: My Learning Notes and Practical Tips

Hello, everyone who works with videos!

Have you ever encountered this situation: you want to use FFmpeg to slow down the playback speed of a video, for example, slow it down by half, so you can clearly see the details or follow along with something? Or, you have a bunch of pictures taken in sequence and want to combine them into a video, but you want it to play slowly instead of flashing by?

I've been pondering these issues recently and found that there are a few key points when using FFmpeg, especially when setting the speed and processing image sequences. I looked through some discussions on Reddit (like these two: How to slow down video and Image to video), combined with my own practice, and compiled this note.

This note does not talk about fancy "slow-motion effects", but focuses on how to use FFmpeg to slow down the video playback speed. We will also specifically explore a common question: Will the frame rate (FPS) of the video change when using setpts to reduce the speed? And how to extend the playback time without changing the (file-marked) FPS? Finally, we will also talk about when generating a video from pictures, how to set the somewhat confusing frame rate (-r) parameter correctly. Rest assured, I'm talking about basic and practical methods, applicable to Windows, Linux, and macOS, and I hope it can help you if you have the same needs.

Come, let's see how to make FFmpeg obediently "slow down"!


The Backstage of Video Slow Motion: How is Time Stretched?

To make a video play slowly, the core is to extend the display time of each frame, increasing the total duration of the entire video, thereby slowing down the playback speed. FFmpeg mainly achieves this by adjusting two things:

  1. Presentation Timestamp (PTS): Simply put, it tells the player at what point in the video this frame should be displayed.
  2. Frame Rate (FPS): The number of frames the video contains per second.

When I was reading everyone's discussions, I found that the main stumbling blocks were:

  • How to accurately control the slow-motion multiple of the video?
  • Will the FPS of the output video change after using setpts for slow motion?
  • How to handle audio synchronization when the video is slowed down?
  • When using images to synthesize video, what are the key points of the input and output frame rate (-r) settings?
  • Are there any pitfalls in using FFmpeg under different operating systems?

Below, we will solve these problems one by one.


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

To slow down the playback speed of an existing video file, the most direct method is to use the setpts filter (used through the -vf parameter). For example, to make the video play half as fast as the original:

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

  • So, will the FPS change? How to extend the playback time without changing the FPS?

    • Good question! setpts itself modifies the timestamp, and it doesn't directly modify the FPS metadata recorded in the video stream (e.g., 30fps).
    • Usually (default behavior): When you only use setpts and do not forcibly specify a new frame rate at the output end with -r, FFmpeg will often keep the FPS mark of the output video file consistent with the input video.
    • The result is: You will get a video file with double the duration, which has the same total number of frames as the original video, and the FPS displayed in the file information is also the same as the original (e.g., still 30fps).
    • So, this command ffmpeg -i input.mp4 -vf "setpts=2.0*PTS" output.mp4 itself has (in most cases) achieved your goal: extending the playback time while keeping the file-marked FPS unchanged. It achieves the slow-motion effect by making each frame display for a longer time, rather than by changing the frame rate standard of the video.
    • One thing to note: Although the FPS marked in the file has not changed, because the total duration has increased and the total number of frames has not changed, the number of new scenes seen per second is indeed reduced during actual viewing, which may feel less smooth than the original speed (but this is exactly the effect desired for slow playback).
  • Universality: This command is written the same on Windows, Linux, and macOS, which is very convenient.


Method 2: Handling Audio Synchronization (The Sound Needs to Slow Down Too)

Only slowing down the picture is usually not enough. If the video has sound, the sound also needs to slow down, otherwise, there will be audio-visual asynchrony. At this point, you need to add the atempo audio filter (used through 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 that the playback speed of the audio is reduced to 0.5 times the original (that is, half). In this way, the sound and picture can be kept consistent.
    • Additional explanation: The speed factor of the atempo filter must be between 0.5 and 100.0. If you want to slow down more than 0.5 times (such as 0.25 times), you need to use it continuously, such as -af "atempo=0.5,atempo=0.5".
  • Universality: Similarly, this command is also universal across all platforms.

Method 3: Creating Slow-Motion Videos from Image Sequences (Key to Understanding -r!)

This scenario is also very common: you have a series of images (e.g., img1.jpg, img2.jpg, ...), and you want to make them into a video, and you want this video to play 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):

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

    • Specifies the frame rate at which the final generated video file should be played. -r 30 means outputting a 30fps video.
    • It determines the specifications and smoothness of the output video. FFmpeg will calculate the total number of frames required based on the total duration adjusted by setpts (e.g., 10 images, input -r 1, setpts=2.0 after the target duration is 20 seconds) and this output frame rate (30fps), which is 20 * 30 = 600 frames. It will fill these 600 frames by repeating the original images (because setpts only changes the timestamp), ensuring that the output video meets the 30fps standard.
  • Working together: Input -r sets the base duration -> setpts adjusts the duration -> Output -r sets the final specifications and frame number filling method.

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


Method 4: Balancing Processing Speed and Output Quality

Video processing is time-consuming, which can be balanced through parameters:

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

Comprehensive 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: You can consider -c:v h264_nvenc (Nvidia) or -c:v h264_videotoolbox (Apple) to speed up.

Okay, this time we have explored in depth the method of FFmpeg implementing video "slow playback", and clarified the relationship between setpts and FPS. Key points review:

  1. Slowing down existing videos:
    • Use -vf "setpts=N*PTS" (N>1) to lengthen the video time.
    • This command usually keeps the FPS mark of the output file consistent with the input, while extending the playback time, which meets the requirement of "only slow down, do not change (mark) FPS".
    • Don't forget to use -af "atempo=1/N" (note the 0.5x speed limit) to handle audio synchronization.
  2. Synthesizing slow-motion videos from image sequences:
    • Input -r determines the time value of the image.
    • Output -r sets the playback frame rate of 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 file name patterns.
  4. Efficiency and quality: Adjust with -preset and -crf.