4

I am looking for a Windows based open source method to extract specific frames from video files (*.avi). Ideally the method will be suited to R.

I need to do this as I have annotated (many) video files using Solomon Coder. This is an open source program which, quickly and easily, allows for user specified frame by frame annotation.

I have then summarized the data using R. In my summary I have a behaviour event and the start and end frame numbers. I also have the start and end time in seconds, epoch time and as a POSIXct object.

I'd like to extract the specific frames in some instances.

I am aware of the following options:

  1. ffmpeg in Matlab. However, I do not have access to Matlab nor I am that competent using it.

  2. Using the command prompt and VLC. However, many images seem to get skipped and one ends up with lots of corrupt files. (e.g: https://www.raymond.cc/blog/extract-video-frames-to-images-using-vlc-media-player/)

  3. Potentially calling Octave through R and using similar approach of ffmpeg. Again, this is a bit beyond my ability for the moment.

If anyone has some quick guidance that would be greatly appreciated.

2
  • How about ffmpeg from the command line? I can supply a command if you're interested.
    – Gyan
    Commented Nov 18, 2016 at 3:56
  • Hi Mulvya, that would be great. Thank you! I have been going through the ffmpeg documentation. It is quite new to me so if you could guide me through the code that would be greatly appreciated!
    – Jono
    Commented Nov 18, 2016 at 13:56

2 Answers 2

6

To extract frame # x through y, use

ffmpeg -i in.mp4 -vf select='between(n\,x\,y)' -vsync 0 frames%d.png
5
  • Hi Mulvya, this is working great so far. Thank you again. I was wondering though, can you modify this code so that the frame numbers are printed in the name of the output file? As oppose to the current naming convention which always begins with "frame1" even if specifying, for example, to start on the 200th frame.
    – Jono
    Commented Dec 8, 2016 at 12:18
  • You can do it manually: ffmpeg -i in.mp4 -vf select='between(n,x,y)' -vsync 0 -start_number x frames%d.png
    – Gyan
    Commented Dec 9, 2016 at 8:38
  • @Gyan Its giving an error, I had to escape the commas in between(n,x,y) with backslash Commented Feb 6, 2019 at 14:51
  • 1
    @burglarhobbit yes, depending on your shell, it's needed.
    – Gyan
    Commented Feb 6, 2019 at 15:02
  • @Gyan I came to know of this from an another similar answer of yours. Please do edit it for other users convenience. I have the latest ffmpeg version. Commented Feb 6, 2019 at 15:08
3

You can also use:

ffmpeg -ss XXX -i input.mp4 -vframes 1 output.png

where XXX is the time in seconds. If you know which exactly frame you want to extract you can calculate the XXX by multiplying the number of the wanted frame * frame duration which is 1/fps.

Please also note that since H.264 is using I, P and B frames it would be best if you first decode your video to some intra-frame codec or raw. You can easily do that by:

ffmpeg -i input.mp4 -vsync 0 output.y4m

And then you can extract the desired frame. But y4m is a format with no compression which means that the output file will be huge. You can also use ffv1 to do that since it is lossless codec, but make sure you use -g 1 option, since you need only I-frames at the output.

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.