0

I would like to create stop motion video from original video. The logic is take frame at specified interval. And play the video with specified playback rate.

For example,
The original video duration is 114.048 seconds.
The output video playback rate 5 times faster than source video.
Take each frame at the interval of 1 seconds. so the final video duration should be (22.81 = 114.048/1*0.2) seconds

Below is the screenshot of demoenter image description here

For this I need ffmpeg code

ffmpeg -r 1 -i D:\21-03-2018\15305154945b39d026a18da.mp4 D:\21-03-2018\output.mp4

Praveen Tamil
  • 822
  • 7
  • 19

3 Answers3

1

Use

ffmpeg -i in.mp4 -vf "select='trunc(t)-trunc(prev_selected_t)',setpts=0.2*PTS" -an out.mp4
Gyan
  • 63,018
  • 7
  • 100
  • 141
0

I did this by following code

ffmpeg -i D:\21-03-2018\15305154945b39d026a18da.mp4 -an -vf "select='isnan(prev_selected_t)+gte(t-prev_selected_t,1)',setpts=0.20*PTS" D:\21-03-2018\output.mp4

Praveen Tamil
  • 822
  • 7
  • 19
0

I would like to elaborate on the code of the answer already given by Gyan with my interpretation of the documentation and the trials I have done.

ffmpeg -i in.mp4 -vf "select='trunc(t)-trunc(prev_selected_t)',setpts=0.2*PTS" -an out.mp4

Analyzing this from back to front

  • Stream Selection / Audio Options

    • The -an option ,detailed here, skips the inclusion of audio stream to the output

      • Since the video is the only part processed and reduced in length if ffmpeg attempts to mix in unprocessed audio of longer length, the resulting video will be the length of the longer of the two.
  • Video Filters -vf "...."

    • The setpts filter, documentation here, and a brief explanation by Gyan aswell, here. Only changes the speed of the output video.

      • You can view the multiplier as setpts=(<input_speed>/<output_speed>)*PTS

        • a number greater than 1 would mean that output is slower than the input and vice-versa.

          • 0.2 is 1/5 so the output video is 5 times faster than the input.
    • The select filter, documented here, processes frame by frame and defines to either discard the frame or send it to the output as the result of an evaluated expression.

      • The expression defined in the code 'trunc(t)-trunc(prev_selected_t)' takes:
        • t : The PTS of the filtered video frame, expressed in seconds.
        • prev_selected_t : The PTS of the last previously selected video frame, expressed in seconds.
        • tuncates them, removes the decimal part, subtracts that, which results in something different to zero if the frames processed are from different seconds in the video.
          • Following this equation, it will select the first frame from each second and discard the rest.
            • This is equivalent to "Take a frame every second from the original Video"

Different Clip rates

trunc(x) - trunc(x_{-1}) evaluates to something different than zero on the cross of every integer. If you increase or decrease the number of integers in your sample space you will have more or less resulting frames. Since t and prev_selected_t represent seconds of each frame, you can multiply this representation to map those seconds to more or less integers and thereby getting different sample/clip rates.

  • 0.2s : 'trunc(5*t)-trunc(5*prev_selected_t)'
  • 0.4s : 'trunc(2.5*t)-trunc(2.5*prev_selected_t)'
  • 0.6s : 'trunc((5/3)*t)-trunc((5/3)*prev_selected_t)'
  • 0.8s : 'trunc(1.25*t)-trunc(1.25*prev_selected_t)'
  • 1.5s : 'trunc(0.667*t)-trunc(0.667*prev_selected_t)'
  • 5.0s : 'trunc(0.2*t)-trunc(0.2*prev_selected_t)'
  • ...

You are not limited to the function trunc() here you can find other examples using other functions ,as Praveen Tamil has proposed in his answer.

A list and brief explanations of the functions evaluated in the expression definition can be found here

Thanks to Gyan for presenting this filter, helped me discover better ffmpeg.

Hope my brief explanation helps understand for possible further tweaking of the code ;)

Pau Coma Ramirez
  • 2,621
  • 1
  • 15
  • 18