How to extract the 1st frame and restore as an image with ffmpeg?
Asked Answered
G

4

92

Anyone knows the trick?

And how to install ffmpeg ? yum install mpeg only returns this:

======================================================================================== Matched: mpeg ========================================================================================
libiec61883.i386 : Streaming library for IEEE1394
libiec61883.x86_64 : Streaming library for IEEE1394
qffmpeg-devel.i386 : Development package for qffmpeg
qffmpeg-devel.x86_64 : Development package for qffmpeg
qffmpeg-libs.i386 : Libraries for qffmpeg
qffmpeg-libs.x86_64 : Libraries for qffmpeg
Grotesquery answered 13/12, 2010 at 2:38 Comment(0)
A
81

It's on the manpage:

* You can extract images from a video, or create a video from many
       images:

       For extracting images from a video:

               ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg

       This will extract one video frame per second from the video and will
       output them in files named foo-001.jpeg, foo-002.jpeg, etc. Images
       will be rescaled to fit the new WxH values.

       If you want to extract just a limited number of frames, you can use
       the above command in combination with the -vframes or -t option, or in
       combination with -ss to start extracting from a certain point in time.

But of course you have to install it first. I'm on Debian and don't use yum.

[update for the other question]


i=1
for avi in *.avi; do
 ffmpeg -i $avi -vframes 1 -f image2 /tmp/$i.jpg; i=$((i+1))
done

Tested and works.

[update for yet another question...]


for flv in *.flv; do
 ffmpeg -i $flv -vframes 1 -f image2 ${flv%%.flv}.jpg
done
Alarice answered 13/12, 2010 at 2:53 Comment(4)
How to extract only the 1st frame of a list of .flv files?Grotesquery
Sorry,but my list of .flv files is specified by something like a.flv,b.flv...,and I want to save the image with the same name as the flv files..Grotesquery
Furthering on from this. Is it possible to convert a video to images at 1fps starting from the very first frame? Setting fps = 1 starts from 1sProsody
probably, but you'll have to ask it as a question, not as a comment.Alarice
C
122

I've cobbled up this command line from various answers that works great for me to get the absolutely first frame out from a video. I use this to save a thumbnail screenshot for the video.

ffmpeg -i inputfile.mkv -vf "select=eq(n\,0)" -q:v 3 output_image.jpg

Explanation:

The select filter -vf "select=eq(n\,0)" is to select only frame #0.

-q:v allows you to set the quality of the output jpeg between 1 and 31. Lower the number, higher the quality. 2 - 5 works good, I use 3.

Note: This will get you an image with the same size as the video. To get a thumbnail, you can use the scale filter to get a thumbnail to fit whatever width you need, like so:

ffmpeg -i inputfile.mkv -vf "select=eq(n\,0)" -vf scale=320:-2 -q:v 3 output_image.jpg

The above command will give you a thumbnail jpeg that will be scaled to match width of 320, and height will be calculated to match the aspect ratio.

Calcite answered 19/5, 2017 at 15:23 Comment(10)
Interestingly enough, though, it always returns an error saying it could not get the image out and the exit code reflects that. However, the image is right there... Have you had that problem too?Parrie
Well no, actually. In reality I'm using this command running out through Node and / or PHP and in both cases the command is completing successfully, as far as I can gather, because (at least in Node) the exit code is used to signal successful run or not.Calcite
For me it's not keeping the aspect ratio of the video and outputs a square imageTokenism
@Tokenism did you try the first command (without the scale filter). That shouldn't change the output image size at all, it should be same as source video.Calcite
I figured that the width and height where the same, but the aspect ratio was part of the metadata and not handled properly by the above command.Tokenism
@DhirajGupta I got en error with the scale command "Could not get frame filename number 2 from pattern 'output_image2.jpg' (either set updatefirst or use a pattern like %03d within the filename pattern) av_interleaved_write_frame(): Invalid argument"Mert
@Mert Check your quote marks around the parameters, and ordering - from the error you're seeing, it looks like as if ffmpeg is treating output_image2.jpg as the input file?Calcite
@DhirajGupta In the output filename, use something like output_image%03d.jpg. The %03d pattern specifies to use a decimal number composed of three digits padded with zeroes to express the sequence number.Kielce
This approach is unoptimal since it decodes the full video even after dumping the first frame. The answer by @Alarice is the optimal one.Cardwell
It works and the image is good, but the command produces whole screen of errors: Cannot write more than one file with the same name. Are you missing the -update option or a sequence pattern?Wattage
A
81

It's on the manpage:

* You can extract images from a video, or create a video from many
       images:

       For extracting images from a video:

               ffmpeg -i foo.avi -r 1 -s WxH -f image2 foo-%03d.jpeg

       This will extract one video frame per second from the video and will
       output them in files named foo-001.jpeg, foo-002.jpeg, etc. Images
       will be rescaled to fit the new WxH values.

       If you want to extract just a limited number of frames, you can use
       the above command in combination with the -vframes or -t option, or in
       combination with -ss to start extracting from a certain point in time.

But of course you have to install it first. I'm on Debian and don't use yum.

[update for the other question]


i=1
for avi in *.avi; do
 ffmpeg -i $avi -vframes 1 -f image2 /tmp/$i.jpg; i=$((i+1))
done

Tested and works.

[update for yet another question...]


for flv in *.flv; do
 ffmpeg -i $flv -vframes 1 -f image2 ${flv%%.flv}.jpg
done
Alarice answered 13/12, 2010 at 2:53 Comment(4)
How to extract only the 1st frame of a list of .flv files?Grotesquery
Sorry,but my list of .flv files is specified by something like a.flv,b.flv...,and I want to save the image with the same name as the flv files..Grotesquery
Furthering on from this. Is it possible to convert a video to images at 1fps starting from the very first frame? Setting fps = 1 starts from 1sProsody
probably, but you'll have to ask it as a question, not as a comment.Alarice
S
56

An easy to grok solution that works for me is

ffmpeg -i <input> -vframes 1 <output>.jpeg

Note that I do get an error "[swscaler @ 0x111652000] deprecated pixel format used, make sure you did set range correctly" but according to a little reading (see for example https://mcmap.net/q/242195/-im-getting-error-quot-deprecated-pixel-format-used-make-sure-you-did-set-range-correctly-using-ffmpeg-quot-can-someone-check-my-code-below) that can safely be ignored.

Soporific answered 25/10, 2019 at 20:37 Comment(2)
The accepted answer did not work for me, got Error initializing filter 'select' with args 'eq(n', but maybe a formatting problem on my end. Your answer worked great!Tomasz
Worked a lot faster than other solution proposed hereCallimachus
B
8

It's works for me

ffmpeg -i sample-mp4-file.mp4 -ss 1 -vframes 1 output.jpg
Burst answered 11/5, 2021 at 7:7 Comment(1)
the -ss 1 is wrong here , because it will seek to 1st second not 1st frame.Spinescent

© 2022 - 2024 — McMap. All rights reserved.