This select filter should skip the first 5 frames:
$ ffmpeg -i input_file -vf select="gte(n\, 5)" ...
For timespan it's even easier. Here's how you skip the first 30 seconds:
$ ffmpeg -i input_file -ss 30 ...
To skip the first 30 seconds and keep the next 120 seconds of the original video, add -t:
$ ffmpeg -t input_file -ss 30 -t 120 ...
-ss time_off set the start time offset
-t duration record or transcode "duration" seconds of audio/video
Both -ss and -t take a time duration:
The following examples are all valid time duration:
5555 seconds
12:03:4512 hours, 03 minutes and 45 seconds
23.18923.189 seconds
None of these methods will be perfectly accurate due to the very mechanics of how video compression works (P and B frames can not stand on their own). ffmpeg will try to adjust accordingly:
Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and
-accurate_seekis enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when-noaccurate_seekis used, it will be preserved.
Refer to the ffmpeg documentation for more.
Answer from evilSnobu on Stack OverflowThis select filter should skip the first 5 frames:
$ ffmpeg -i input_file -vf select="gte(n\, 5)" ...
For timespan it's even easier. Here's how you skip the first 30 seconds:
$ ffmpeg -i input_file -ss 30 ...
To skip the first 30 seconds and keep the next 120 seconds of the original video, add -t:
$ ffmpeg -t input_file -ss 30 -t 120 ...
-ss time_off set the start time offset
-t duration record or transcode "duration" seconds of audio/video
Both -ss and -t take a time duration:
The following examples are all valid time duration:
5555 seconds
12:03:4512 hours, 03 minutes and 45 seconds
23.18923.189 seconds
None of these methods will be perfectly accurate due to the very mechanics of how video compression works (P and B frames can not stand on their own). ffmpeg will try to adjust accordingly:
Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position. When transcoding and
-accurate_seekis enabled (the default), this extra segment between the seek point and position will be decoded and discarded. When doing stream copy or when-noaccurate_seekis used, it will be preserved.
Refer to the ffmpeg documentation for more.
ffmpeg -i {videofile} -vf select=gte(n\,{skip}) -c:v libx264 -c:a aac {outfile}
Where {skip} = number of frames to skip at atart.
Unlike previous solution, there's no loss in quality here.
I am making a script that applies a filter to every N-th frame of the video to gather some metrics about the stream.
Now I am using the framestep filter to achieve this. But I noticed that it doesn't matter if I process every 10-th or 1000-th frames, ffmpeg reads to whole file anyway, and different framestep intervals don't really have an effect on the speed of the script. There is no significant performance difference between framestep 10 or 1000.
So I am looking for a way to speed this whole thing up. I would like to make ffmpeg to skip reading all frames from the input, and only read the necessary data from the source.
How is it possible the achieve that?
To work accurately, first convert the video to RAW YUV bitstream (if it is not already) by:
ffmpeg -i input.mp4 -an -vcodec rawvideo -pix_fmt yuv420p rawbitstream.yuv
Next step: The select filter takes an expression, where n is the frame number.
ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv
ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv
To have ffmpeg not duplicate frames, you have to force half of the framerate of your input - so you set "2" as the input and "1" to the output. Don't forget to replace the WxH with the actual dimensions of your clip because the raw bitstream doesn't have a header that carries this information.
Instead of the above, another possibility would be to add the setpts filter to set new timestamps for the output. But be careful since it drops frames not accurately. Here, 25 is the actual output frame rate you want:
ffmpeg -i input.mp4 -filter:v select="mod(n-1\,2)",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an odd.yuv
ffmpeg -i input.mp4 -filter:v select="not(mod(n-1\,2))",setpts="N/(25*TB)" \
-c:v rawvideo -r 12.5 -format rawvideo -pix_fmt yuv420p -an even.yuv
You can of course choose another pixel format (any of ffmpeg -pix_fmts). Make sure that when reading the file you know the pixel size and pixel format:
ffmpeg -f rawvideo -s:v 1280x720 -pix_fmt yuv420p input.yuv …
If your ffmpeg was built with the AviSynth flag, then I believe you can pass an .avs file.
You can check by running ffmpeg and looking for --enable-avisynth in the configuration data.

If it's there you can use it like so: ffmpeg -i blahEven.avs blahEven.yuv.
Where blahEven.avs is simply:
ffvideosource("blah.yuv").SelectEven()
For odd frames, use SelectOdd().
For more advanded usage, see the SelectEvery documentation.
When I convert png images to avi video ffmpeg is dropping frames. At the end I have over 130 dropped frames and with the 24fps video that's 5 second difference at the end. How can I prevent ffmpeg from dropping frames I tried every -vsync option and -frame_drop_threshold 0 but nothing worked. I run
ffmpeg -i ./pictures/asp_%04d.png -vsync 0/1/2/drop -r 24 video.avi ffmpeg -i ./pictures/asp_%04d.png -frame_drop_threshold 0 -r 24 video.avi
but neither worked, for -vsync 0/drop I got errors
Hi all,
Long time lurker, first time poster.
I need some help from some ffmpeg legends on this problem im having.
So I am trying to split a video at a certain second value. The thing is, the split videos when put back together is frame skipping! Expected i guess, but just want to see if anyone here has a solution to this.
Cheers!!
Using ffmpeg within nodejs script.
execSync(`ffmpeg -y -i ${inputVideo} -t 2.001 -c:v copy -an -r 30 output1.mp4`, { stdio: 'inherit' });
execSync(`ffmpeg -y -i ${inputVideo} -ss 2.001 -t 1 -c:v copy -an -r 30 output2.mp4`, { stdio: 'inherit' });
execSync(`ffmpeg -y -i ${inputVideo} -ss 3.001 -t 1 -c:v copy -an -r 30 output3.mp4`, { stdio: 'inherit' });
I realize this is an old question, but in case someone else (like me) stumbles upon it, the answer is that the time code skips you see are not an error, but work as intended.
Since you have specified 29.97 fps drop frame (by using a semicolon in the timecode) the two-frame skip is according to the specification (read more here: https://en.wikipedia.org/wiki/SMPTE_timecode#Drop_frame_timecode).
In short: Since 29.97 is a fractional speed, and a video file cannot contain fractional frames, frames have to be dropped to maintain a correlation between the time code and wall clock time. Note that no actual video frames are dropped, only time codes are skipped. The specification says that on the first second of every minute, the first two frames (zero and one) are skipped, except for when the minute value is divisible by ten.
So seeing the time code go from 00:00:59:29 to 00:01:00:02 is expected behaviour. In order not to get this you have to switch to another frame rate, and write the time code using only colons: 00:00:00:00.
I found a StackOverflow post on the same topic; I think that solution is a little more elegant, so check this out.
What method are you using to examine the video? Have you confirmed somehow that it is the video itself at fault, as opposed to the video decoder skipping the frames?