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.
Asked
Active
Viewed 1.7k times
2 Answers
39
To take every 15th frame, use the select filter
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
-
2Got different errors running both of these commands: "Missing ')' or too many args in 'mod(n'" and "Option 'framestep' not found" – odigity Feb 23 '17 at 03:16
-
5For the first error, you probably need to escape the comma, so `n\,15` and for the 2nd, recheck the command string. If you were using a very old ffmpeg (before framestep filter was added), it would have complained `no such filter` but you're getting an `option` error, which indicates a malformed command. Are you using it in a shell or wrapper? What's the exact string? – Gyan Feb 23 '17 at 05:56
-
I'm running Ubuntu 16.10 with ffmpeg 3.0.7, and I'm copying and pasting your two command lines verbatim, only changing the in and out filenames. – odigity Feb 23 '17 at 21:33
-
Run the commands with `-report` added. A log will be written. Link to that. – Gyan Feb 24 '17 at 04:54
-
1For large videos (2-3 plus hours), I found framestep was drastically faster than using the select filter. – David Aug 11 '17 at 01:05
-
Yes, select will evaluate each frame for a match. – Gyan Aug 11 '17 at 04:52
-
The first method works well but the framestep method above sets the output fps to 4 for me with a 60fps input. – juanitogan Aug 13 '18 at 23:08
-
5Yes, it resets the framerate. To avoid that, `-vf framestep=15,setpts=N/60/TB,fps=60` – Gyan Aug 14 '18 at 04:44
-
@Gyan -- Thank you, that did it. I tried similar things but wasn't getting it right. Didn't notice any speed improvements from the other method though. But that is probably more a factor of the compression I'm doing on the way out than the filter method (and a video too short to notice much). – juanitogan Aug 15 '18 at 22:57
-
2using `-vf framestep=15,setpts=N/60/TB,fps=60`, I get the appropriate playback speed. But the video keeps its original length, showing just the last frame for the remainder. How to trim the output to only the available frames at the given fps? – AdamAL Oct 27 '21 at 19:23
-
1@AdamAL happened to me too. It turned out it was caused by the presence of the audio stream that was left present in the container. Simply adding `-an` to drop the audio stream solved the issue. – Fryderyq Jan 11 '22 at 19:07
-
2@AdamAL using `-an` was not enough for me, I had to use `-vf framestep=15,setpts=N/60/TB -r 60`. Effectively, move the setting of fps from `-vf` to `-r`. Full command is `ffmpeg -an -i in.mp4 -vf framestep=15,setpts=N/60/TB -r 60 out.mp4`. – Paul Hiemstra May 03 '22 at 13:25
12
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

Kiryl
- 121
- 1
- 2
-
-
1@Jackie it should be the same. Just instead of typing in files ending in .avi, type in .mp4. – John Leuenhagen Feb 27 '23 at 23:57