Search code examples
imagevideoffmpegframe-ratex264

vframes option ignored in ffmpeg?


I have a directory that contains 2001 PNG files. I can convert all of the frames to an mp4 video using ffmpeg and the following command:

ffmpeg -framerate 60 -start_number 0 \
-i pic.comp2.%07d.png -c:v libx264 -r 30 \
-pix_fmt yuv420p input1ia.mp4

This works fine. However, I am creating a more complicated application that needs to read only the first 1020 files in the directory (specifically 0 thru 1019). Some googling around led me to the -vframes option. My problem is -- it seems to get ignored or at least interpreted differently than I expect.

My modified command looks like:

ffmpeg -framerate 60 -start_number 0 \
-i pic.comp2.%07d.png -vframes 1020 -c:v libx264 
-r 30 -pix_fmt yuv420p input1.mp4

It seems like many other people doing the same thing as me do not encounter this issue. So I did some more digging. I tried changing vframes from 1020 to -vframes 20, and this seemed to work properly. So now I am thinking it might be some kind of mismatch between -framerate and -r?

The full resultant video is 33 sec long... which makes sense mathematically.

 1 sec
 ---------   x  2001 frames = 33.35 seconds
 60 frames

That's why I thought that specifying ~1/2 of the PNGs as the 'end point' would result in a video of the first ~16-17 seconds. But I always get the full length video from using the -vframes option.

I assume my input to -vframes must be incorrect mathematically, since a small number of frames seems to work. However, I do not understand why.

The most educated guess I can seem to make is that it is reading the PNGs as 60fps (-framerate), but the -r makes the output video 30fps or something? However, then I would assume that the full output video would not be 33 seconds long.


Solution

  • When the input and output rates don't match, ffmpeg drops or duplicate frames as per a regular scheme to achieve the output rate. So, for an input rate of 60 and an output rate of 30, half the frames are dropped. With the vframes option, 1020 frames at a output rate of 30 should produce a video of duration 1020/30 = 34 seconds.

    To achieve what you want, use the t option

    ffmpeg -framerate 60 -start_number 0 -t 17 \
    -i pic.comp2.%07d.png -c:v libx264 -r 30 \
    -pix_fmt yuv420p input1ia.mp4
    

    where 17 is number of frames to be used / input rate