Update: Still using this 8 years later, but in the form of a quick script, which is useful if you are doing it more than once.
Update 2: DHM points out the way this was written no longer works in modern versions of ffmpeg. Instead of -t 1
, use -vframes 1
Update 3: Yet another update to frame selection, thanks Thelo!
Dead handy, this:
ffmpeg -ss 0.5 -i inputfile.mp4 -frames:v 1 -s 480x300 -f image2 imagefile.jpg
The various options:
-frames:v 1
: limit to 1 frame extracted-ss 0.5
: point of movie to extract from (ie seek to 0.5 seconds; you can also use HH:MM:SS.ZZZZ sexagesimal format)-s 480x300
: frame size of image to output (image resized to fit dimensions)-f image2
: forces format
I use this to generate preview stills for jwplayer to use. Dead handy!
Edit: Thanks to DieBagger who pointed out it is much faster to place the seek argument before the input file, and Matthias his point about the seek time.
Nice, exactly what I was looking for =)
Thx man,
one suggestion though: if you put the -ss in front of -i, ffmpeg will seek to the given position much faster…
Hey DieBagger, thanks for the tip, I will test and confirm that! Why does the order of the arguments matter in this case, can you say?
Well, there’s a quite clear difference there! It would be good to know exactly why it works this way though.
Yeah…I frequently use FFMPEG for extract single image from video. Thanks mate 🙂
Putting the -ss before the -i is faster (and less precise) because ffmpeg does not decode the video to find the frame. I think this has something to do with keyframes. Because of this I have found it to be problematic with some videos that will produce a gray frame, whereas putting the -ss after the -i will work fine (though of course much slower).
Thanks Rob! So it’s a case of ‘try -ss -i, but if that doesn’t work, try -i -ss’ then.
I think “-t 1” is not correct. What you need instead is “-vframes 1”. See http://club.myce.com/f62/ffmpeg-command-line-options-166608/
Yes, -vframes 1 did the trick for me.
Pingback: extract image | daw.raks
i extracted the frames but they were not of good quality, pixels are getting scattered.
So if any one have any idea for the good solution plz suggest me and my querry is->
ffmpeg -i input.mp4 -r 25 -s 1280*720 -f image2 frame_%d.jpg
You can use -ss both before and after the -i. The -ss before will skip to the nearest keyframe before the specified time. What you can do (and possibly use a simple wrapper script to generate this) is
T=3456 # total seconds to skip
ffmpeg -ss $((T-20)) -i file.mp4 -ss 20 … out.mp4
Quite possibly adding -ss 0 after the -i file.mp4 also improves things. Certainly if I extract a 10 second segment using
ffmpeg -ss 1234 -i file.mp4 -t 10 … out.mp4
the output file (sometimes) isn’t quite right (for example the length isn’t exactly 10 seconds).
Excellent Post, thanks for sharing.
The -ss parameter needs the time in mm:ss format, like `-ss 5:00` to get 5 minutes. I tried passing `-ss 5` and it returned an image from the very beginning.
Matthias: True- you can specify the time in either hh:mm:ss.micro (sexagesimal format!); or as a simple number, which is interpreted as seconds. I will update the post to point this out. Thanks 🙂
Pingback: Quick Hacks: A Script to Extract a Single Image/Frame From Video – Bertie Baggio's Wonderland
Doesn’t work in 2020. That’s with ffmpeg 4.2.2-1. It produced this error.
[image2 @ 0x559704154fc0] Could not get frame filename number 2 from pattern ‘imagefile.jpg’.
Use ‘-frames:v 1’ for a single image, or ‘-update’ option, or use a pattern such as %03d within the filename.
av_interleaved_write_frame(): Invalid argument
@DHM: Quite correct! Good catch.
I hadn’t noticed this as I was using it in a script] which uses
-vframes 1
.I’ll update this post. Cheers for the heads-up 🙂
…seems I had actually updated the explanation to use
vframes 1
already, just not the example. Sorted now!Thanks, man! It worked for me as required!
Glad it worked for you Serz, thanks for stopping by 🙂
Hi Rob have you used kmsgrab option instead from a video file to export an image /screenshot?
Or anyone familiar with it?
Also of of any interest
-frames:v 1 tells FFmpeg to take only 1 screenshot. Note that, -vframes is deprecated.
Hi Thelo, thanks for the note on vframes, I’ll need to update usage again!
As for
kmsgrab
, I haven’t really use that. For a partial screengrab, I use imagemagick’simport
very frequently! So frequently I have an alias for doing it quickly to file or to clipboard. I’ll write it up as another ‘quick tip’ when I get a moment!Cheers for stopping by and taking the time to comment 🙂
Update: here’s how I do it: https://blog.roberthallam.org/2022/04/quick-tip-region-screenshot-from-cli/
HI @Rob! Thank you for you kind reply! I m trying to figure out kmsgrab to take full screenshot of a graphical app running at CLi. htop etc its easy to get with fbgrab and scrot for x enviroment but if i run a game for example or retroarch at CLi i cant get a screenshot with any tool on a non rpi board ( for rpi boards there are tools taking screenshot of any environment at the moment)
Welcome back @Thelo 🙂
I see now where you’re coming from with kmsgrab- no DE, maybe even no X (?) means that other tools won’t work for you, which I assume you have tried!
Alas I am not in a position to help with that, as I use NVidia cards- attempting to capture the default card results in `Failed to get plane resources: Operation not supported`, and if I use the nvidia device (eg `/dev/nvidia0`), I get `Failed to get version information from /dev/nvidia0: probably not a DRM device?`.
More reading (you’ll see the same koko handle):
– https://forums.developer.nvidia.com/t/ffmpeg-f-kmsgrab-is-failing-failed-to-open-drm-device/110589
– https://github.com/kokoko3k/ssh-rdp/issues/2
– https://gist.github.com/Brainiarc7/7b6049aac3145927ae1cfeafc8f682c1
Would love to hear if you have any success. Good luck! 🙂