How to create a full length video from images with FFmpeg? - image

I have more than a thousand images that I want to transform into a 3 minutes video. I tried using this line ffmpeg -r 30 -i "E:/White-box-Cartoonization/test_code/cartoonized_images/$flower%03d.bmp" -c:v libx264 -pix_fmt yuv420p out.mp4 it worked but creates only a 5 seconds video. What do I need to do to turn it into a full length 3 minutes video?

If you have 1250 images and want an output duration of 180 seconds:
ffmpeg -framerate 1250/180 -i input%03d.bmp -c:v libx264 -vf format=yuv420p output.mp4
This example results in a frame rate of 6.94. Some players can't handle such low frame rates. If your player does not like it then add the -r output option to make a normal output frame rate. ffmpeg will duplicate the frames but the output will look the same.
ffmpeg -framerate 1250/180 -i input%03d.bmp -c:v libx264 -vf format=yuv420p -r 25 output.mp4

For 3 minutes of video at 30 frames per second (-r parameter) you'd need 30*60*3 images: 5400 images.
Your source parameter specifies there would be only 3 digits, so you have a maximum of 1000 source images:
$flower%03d.bmp => $flower000.bmp .. $flower999.bmp
1000 images at 30 frames per second should give about 30 seconds of video ... if you actually have $flowerxxx.bmp files.
You might need a 4th digit in there somewhere.
$flower%04d.bmp

Related

ffmpeg how to show each frame for 1 second?

I have a video, recorded at 7 fps. It's 17 seconds long and has 122 frames.
I want to keep all frames but show them 1 per second, I want the same video to last 122 seconds. I don't want to lose information, but I also don't want the file size to increase.
How can I do that? All the ffmpeg options I see change the frame rate but keep the duration or create/drop frames.
You want to slow down your video without reincoding your video to (possibly) keep the file size. You must strip the timestamps by exporting the video to a raw bitstream format:
ffmpeg -i input.mp4 -map 0:v -c:v copy -bsf:v h264_mp4toannexb raw.h264
and than remux it with:
ffmpeg -fflags +genpts -r 1 -i raw.h264 -c:v copy output.mp4
-r 1 sets the framerate to 1.

Timelapse (1/6 fps) from slo-mo (240 fps) with ffmpeg

I recorded slo-mo video on an iPhone SE (2) by mistake instead of timelapse.
I know there's a lot of answers to this question here, but I'm trying again and again and always something's wrong (like a video that has a correct total no. of frames, but lasts 3 hours and is basically a freeze :D )
My recent command was
ffmpeg -i IMG_2174.MOV -vf framestep=1440,setpts=N/120/TB -c:v libx264
-preset slow -crf 22 -an -r 30 IMG_2174.timelapse.MOV
but it resulted in a one-second-long video, so way over-timelapsed. Should be several seconds IINM. The source video is 30 minutes long #240fps, 17GB.
Thx.
This command seems to do the trick:
ffmpeg -i IMG_2174.MOV -vf framestep=1440,setpts=N/30/TB -c:v libx264 -preset slow -crf 22 -an -r 30 IMG_2174.timelapse.MOV
Here is the explanation for OP's self-answer.
ffmpeg -i IMG_2174.MOV
-vf framestep=1440,setpts=N/30/TB
-r 30 -c:v libx264 -preset slow -crf 22 -an IMG_2174.timelapse.MOV
Given input video at 240 fps cfr:
framestep=1440 keep every 1440th frame, yielding 240/1440 = 1/6 fps
setpts=N/30/TB speeds up the video by x180 (30 / 1/6)
-r 30 output option: match the new pts interval set above
For a vfr video, framestep=1440 likely results in incorrect timing (though on the average correct). For such video, replace the framestep filter with fps=1/6 filter so it picks the frames based on pts rather than frame count.
[edit note: iPhone's slo-mo recording does keep 240fps cfr so the OP's solution is 100% correct, edited down just to mention a vfr-correct approach]

Create time lapse video from other video

Using avconv (or even ffmpeg, so I can use as a reference), how can I create a time lapse video by taking only anchor/reference frames from another video? Most information I find is on how to create a time lapse video by combining images, and I'd like to do it by extracting frames from a video. Say, if a video is 30 seconds long at 30 FPS, I'd like to take 60 out of those 900 frames (900/60 = every 15 seconds) to produce a 2 second video.
To take every 15th frame, use
ffmpeg -i in.mp4 -vf select='not(mod(n,15))',setpts=N/FRAME_RATE/TB out.mp4
Another method is to use the framestep filter
ffmpeg -i in.mp4 -vf framestep=15,setpts=N/FRAME_RATE/TB out.mp4
I had a H264 video from a camera and after lots of attempts found following command that produce 16x faster video with good result and 60 FPS (option -r) that is good for the YouTube timelapse
ffmpeg -i video.avi -r 60 -filter:v "setpts=0.0625*PTS" -vcodec libx264 -an timelapse.avi
You can check the result here https://www.youtube.com/watch?v=azhRqKQ7kCU
Since you are asking for 1/15 frame it will be 1/15 ~= 0.06667 with 30 FPS result video you will need command
ffmpeg -i video.avi -r 30 -filter:v "setpts=0.06667*PTS" -vcodec libx264 -an timelapse.avi

FFMPEG (windows7) can't get the output video to show more than 3 out of 10 jpgs

I have 10 jpg files (image0.jpg, image1.jpg, image2.jpg ... image9.jpg) and one .mp3 and I'm trying to create a video but I can't get it to show more than the first 3 images in the output.
I played with the output -r option and for example if I change it to 30 it shows all of them but very fast so the whole video plays for under a second.
This is my code:
ffmpeg -i image%d.jpg -i audio.mp3 -r 1 -c:v libx264 -tune stillimage -c:a aac -strict experimental -b:a 192k -r 1/5 -pix_fmt yuv420p -shortest out.mp4
What am I doing wrong ?
The image file demuxer by default uses a frame rate of 25 fps if you do not tell it otherwise. Since you used -r 1/5 as an output option the frame rate will be converted resulting in duplicated or, as in your case, dropped frames to compensate. To change this use -framerate as an input option (this is a private option of the image file demuxer):
ffmpeg -framerate 1/5 -i image%d.jpg output
Some crappy players may not like a "non-standard" frame rate, so you can add an output frame rate to change it while keeping the "timing" of the input:
ffmpeg -framerate 1/5 -i image%d.jpg -r 25 output

ffmpeg keyframe extraction

I have been trying to extract keyframes from video using ffmpeg 0.11.1 . So far all the commands I have tried do not extract keyframes but return all the frames ie 25fps*total time number of frames in the output.
I tried setting the keyint_min as 25 to make sure there is a amximum of 1 keyframe per second.
ffmpeg -vf select="eq(pict_type\,PICT_TYPE_I)" -g 250 -keyint_min 25 -i C:\test.mp4 -vsync 2 -f image2 C:\testTemp\thumbnails-%02d.jpeg
But still all the frames are returned.
Then i tried, to separate the keyframes by 20 seconds.
ffmpeg -i C:\test.mp4 -vf select='eq(pict_type\,I)*(isnan(prev_selected_t)+gte(t-prev_selected_t\,20))' -vsync 0 -f image2 C:\testTemp\%09d.jpg
Again same result, all the frames are returned.
What should I do?
In your first command you are using the filter as an input option. I don't know how ffmpeg will interpret that.
Try this:
ffmpeg -i C:\test.mp4 -vf select='eq(pict_type\,I)',setpts='N/(25*TB)' C:\testTemp\%09d.jpg
Change 25 to the frame rate of your source: 30000/1001 for NTSC video, 24000/1001 for NTSC film, 25 for PAL, etc.
Control output quality with the -q:v or -qscale:v option (just called -qscale in old ffmpeg). Range for mpeg* is 1-31 where 31 is the worst quality.
Next time remember that ffmpeg usage questions are to be asked at superuser.com since stackoverflow is specifically for programming.

Resources