Extracting "one of every 10 frames" in a video using VLC or FFmpeg

46,509

Solution 1

Select 1 frame out of every 10 frames

You can use the select video filter in ffmpeg to do this:

ffmpeg -i input.mov -vf "select=not(mod(n\,10))" -vsync vfr -q:v 2 img_%03d.jpg
  • For JPG output you can vary quality with -q:v. Effective range is 2 (best quality) to 31 (worst quality). You don't need this option if you want to output to PNG instead.

  • This will output img_001.jpg, img_002.jpg, img_003.jpg, etc.

Solution 2

The most important aspect in your question is the fact that the video uses 29.97 frames per second, not 30. Pesky NTSC.

Anyway, I think it would be easiest to just extract every frame, and then remove the ones you don't need:

ffmpeg -i 1.mov -y -f image2 -c:v mjpeg %03d.jpg

Then, remove the ones you don't need. Since every tenth frame will end with a 1.jpg, we can just take all the others …

find . -maxdepth 1 -not -iname "*1.jpg"

… and once you're sure these are the ones you want to remove:

find . -maxdepth 1 -not -iname "*1.jpg" -exec rm '{}' \;

If you can use mencoder, you could try the framestep option, as explained in the documentation, like framestep=10 in your case. I personally couldn't install/try it though.

Share:
46,509

Related videos on Youtube

wmac
Author by

wmac

Updated on September 18, 2022

Comments

  • wmac
    wmac almost 2 years

    I am trying to extract "exactly 1 frame of every 10" frames of a video (i.e. extract 1 , leave 9 then repeat) for scientific purposes. The video is 105 frames, 3.5 seconds, 29.97fps (h.264, .mov, produced by Nikon D3100).

    I have uploaded it here.

    VLC

    Below command should produce 10 frames, but it only produces 6 images. I tried different scene ratios and neither of them produce correct number of frames (not even near to correct).

    vlc 1.mov --video-filter=scene --vout=dummy --scene-ratio=10 --scene-prefix=img- --scene-path=. vlc://quit
    

    Would someone please tell me what is the problem?

    FFmpeg

    FFmpeg does not seem to have a command exactly for my purpose. Below command extracts 3 frames out of every second, but since the FPS is not exactly 30 (rather 2.97), that will not produce correct results for me.

    In addition even FFmpeg does not give out correct number of frames with even this command. For 3.5 seconds of video I expect at most 10 frames, but what I get is 12 frames!

    ffmpeg -i 1.mov -y -an -sameq  -r 3 -f image2 -vcodec mjpeg %03d.jpg 
    

    How can I achieve what I want?

    • Admin
      Admin about 10 years
      BTW -sameq doesn't do what you probably think it does, and has been removed from the current version (the real ffmpeg that is, I'm not sure if it's in the Ubuntu fake ffmpeg). Use qscale instead.
  • wmac
    wmac over 12 years
    I also cannot run the command and receive the following error on ffmpeg windows N-35709-g7d531e8: [select @ 017EBB00] [Eval @ 0022DC08] Missing ')' or too many args in 'mod(n\,10))' [select @ 017EBB00] Error while parsing expression 'not(mod(n\,10))' Error initializing filter 'select' with args 'not(mod(n\,10))' Error opening filters!
  • Elisa Cha Cha
    Elisa Cha Cha over 12 years
    @mivk Your FFmpeg version from the Ubuntu repo does not have filtering capabilities. You will have to compile FFmpeg.
  • Elisa Cha Cha
    Elisa Cha Cha over 12 years
    @wmac I guess Windows doesn't like the single quotes. Change them to double quotes: ".
  • wmac
    wmac over 12 years
    @LordNeckbeard, thanks, it runs correct and solved the whole problem. I really really appreciate your help.
  • northern-bradley
    northern-bradley almost 5 years
    i was going from a 10 fps video and i wanted every 10th frame. however select=not(mod(n\,10)) did not have the desired effect. i expected it to produce a file 1/10th the duration but it did not. from superuser.com/a/1156862/316154 you also need to use setpts=N/10/TB (10 is the fps) making the whole thing -vf select=not(mod(n\,10)),setpts=N/10/TB
  • Elisa Cha Cha
    Elisa Cha Cha almost 5 years
    @northern-bradley Looks like you want to output video. Users who want images, such as the question the answer addressed, won't need setpts.