I'd like to record a very long video from webcam which will be mostly the same. I'd like to drop intermediate frames that are very similar to each other to save on filesize and also make it easier to find "interesting" parts of the video later.

The frames will likely not be identical but should be similar (I imagine I'll have to experiment with thresholds)

I am familiar with both mencoder and ffmpeg but have been unable to find any options to do what I need.

I'd prefer to drop the unwanted frames at time of recording but if it must be done as a post-process that is ok however - the video needs to have a timestamp on it, obviously this will interfere with any similarity test so it either needs to be done at time of recording or the similarity test needs to ignore a predefined section of the video without dropping it.

FYI this is the command I am using currently but without the desired framedropping.

ffmpeg -f video4linux2 -s 800x600 -r 15 -i /dev/video1 -maxrate 800k -minrate 1k -bt 800k -bufsize 2M -filter drawtext='text=%{localtime }:fontfile=/usr/share/fonts/truetype/DejaVuSans-Bold.ttf'  -f h264  out.avi -y

What are my options?

  • Incidentally the video will not be streamed live so there is no minimum bandwidth concren
    – DJL
    Commented Jul 22, 2014 at 8:06
  • Keep an eye on this software, developed at CMU. It removes uneventful pieces of video. There's a link to the paper in the press release. cmu.edu/news/stories/archives/2014/june/… Commented Jul 22, 2014 at 10:08
  • Does this actually have a Video Production related use case? I'm having trouble seeing how this really relates to Video Production. It seems to be more specifically a security system kind of requirement that doesn't really apply to any video production situation I can think of.
    – AJ Henderson
    Commented Jul 22, 2014 at 21:47

3 Answers 3


It is actually quite easy using a videofilter with select.

This is quite sensitive to video changes:

-vf "select=gt(scene\,0.0098)"

whereas this is not so sensitive:

-vf "select=gt(scene\,0.3)"

EDIT (added your command)

so your command would look like:

ffmpeg -f video4linux2 -s 800x600 -r 15 -i /dev/video1 -maxrate 800k \ 
-minrate 1k -bt 800k -bufsize 2M -filter \ 
drawtext='text=%{localtime }:fontfile=/usr/share/fonts/truetype/DejaVuSans-Bold.ttf'  \
-vf "select=gt(scene\,0.3)" -shortest -c:v libx264 out.mp4 -y

P.S. You need to explicitly state the codec libx264 and not just tell it -f h264 and why on earth would you be using avi???

  • This seems to work except the output duration is the same as the input. I expected the new frames to all be the same duration (e.g. 1/15th of a second) resulting in a quick jump past the boring bits. I tired adding -r 15 as the last argument before the output filename but it had no effect.
    – DJL
    Commented Aug 8, 2014 at 17:06
  • It seems you will probably want to use the -shortest command, which I forgot to put in.
    – denjello
    Commented Aug 11, 2014 at 15:57

I found this thread. There you can see that Avisynth has a plugin (GetDups) which will allow you to do exactly what you want.


You may reach it by mpdecimate video filter (followed by setpts filter for the correct timing).
Add these filters to your filter chain:


so your command will be

ffmpeg -f video4linux2 -s 800x600 -r 15 -i /dev/video1 -maxrate 800k -minrate 1k \
   -bt 800k -bufsize 2M -filter:v \
    drawtext='text=%{localtime }:fontfile=/usr/share/fonts/truetype/DejaVuSans-Bold.ttf', \
    mpdecimate,setpts=N/FRAME_RATE/TB out.avi -f h264 -y

(In the case of need the filter mpdecimate may be adjusted by its options hi, lo and frac but the default values work fine.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.