Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have a video file and I want to get the number of video frames that are in it. I can use ffmpeg to get the length of the video and the FPS. However I can't see anything obvious for the total number of frames.

In theory one should be able to multiply the length (in seconds) by the FPS to get the number of frames, but in this case the length (34.43 seconds) and the framerate (29.97 fps) give a non-integer, which makes me think I'm doing something wrong.

I need to be able to do this on the command line in a totally automated and non-graphical manner. I also need this to be pretty exact, and not an estimate (if that's even possible with video files)

I tried using tcprobe on some files. For some AVI files it works, but for some VOB files, the tcprobe output doesn't have the number of frames. I get this output:

[tcprobe] MPEG program stream (PS)
[tcprobe] summary for myfile.vob, (*) = not default, 0 = not detected
import frame size: -g 720x480 [720x576] (*)
     aspect ratio: 4:3 (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
                   PTS=2199.3972, frame_time=33ms bitrate=7000 kbps
      audio track: -a 0 [0] -e 48000,16,5 [48000,16,2] -n 0x2000 [0x2000] (*)
                   PTS=2199.2763, bitrate=192 kbps
                   -D 3 --av_fine_ms 20 (frames & ms) [0] [0]
share|improve this question
your equation will give you a good ballpark estimate; just round the floating-pt result up. if you need an exact number of frames you'll need to examine the file directly -- your estimate might be off by one or two in either direction due to the particulars of the video codec. – quack quixote Dec 17 '09 at 18:47
are these all-in-one-file VOBs or DVD-style split-into-multiple-file VOBs? – quack quixote Dec 18 '09 at 16:55
up vote 10 down vote accepted

This is horrible, and stupid, and slow, but seems to work:

ffmpeg -i foo.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr ^M '\n' | awk '/^frame=/ {print $2}'|tail -n 1

It will also work right on truncated files and raw streams(that is why you get nothing for .vob files)

share|improve this answer
That's pretty good. In my experience, it doesn't take that long. A 40 minute file takes about <3seconds to run though. Remember that the "^M" is not the 2 characters ^ and M, you have to press Control-V, and then enter. Instead of your command I used: ffmpeg -i somefile.avi -vcodec copy -f rawvideo -y /dev/null 2>&1 | tr "^M" '\n' | grep '^frame=' | perl -pe 's/^frame=\s*([0-9]+)\s.*$/\1/' | tail -n 1 Your command fails if there's no space after the "frames=" – Rory Jan 5 '10 at 12:23
In Ubuntu 12.04, ffmpeg version git-2013-04-15-a4f03f0, you can omit both | tr ^M '\n' and |tail -n 1. Also, no space after frames= doesn't fail. (Maybe something's changed in the past four years.) – Camille Goudeseune Aug 12 '14 at 19:10

ffprobe can be used to get info about a media file:

ffprobe -select_streams v -show_streams input.avi

You will get details about the stream:


Look for nb_frames with grep:

ffprobe -select_streams v -show_streams input.avi 2>/dev/null | grep nb_frames | sed -e 's/nb_frames=//'

That works for avi, mp4 and etc For some containers, it does not show valid value e.g. mpeg.

In that case, this works ffprobe -show_packets a.mpg 2>/dev/null | grep video | wc -l

share|improve this answer
Good idea. I modified the command a little so that it only selects the video stream, and filters the output. That gives you just the number of frames. – slhck Jun 13 '14 at 14:31
Congrats for your 2nd solution which works with MPEG-2 ! – malat Mar 25 '15 at 11:20
It does not work with MKV containers. – Cenk Alti Dec 22 '15 at 9:31

I posted this on another question. Using the tcprobe tool (from the transcode package), the number of frames is included in the info. Use the -i switch to get an info dump from the file:

$ tcprobe -i foo.avi
[tcprobe] RIFF data, AVI video
[avilib] V: 29.970 fps, codec=XVID, frames=38630, width=512, height=384
[avilib] A: 48000 Hz, format=0x55, bits=16, channels=2, bitrate=128 kbps,
[avilib]    53707 chunks, 21768720 bytes, VBR
[tcprobe] summary for foo.avi, (*) = not default, 0 = not detected
import frame size: -g 512x384 [720x576] (*)
       frame rate: -f 29.970 [25.000] frc=4 (*)
      audio track: -a 0 [0] -e 48000,16,2 [48000,16,2] -n 0x55 [0x2000] (*)
                   bitrate=128 kbps
           length: 38630 frames, frame_time=33 msec, duration=0:21:28.954

Note the number of frames is given on two lines here (2nd output line and last output line).

share|improve this answer
That looks like a good answer, and works for some files, but for some VOB files I have, I don't have that data in the output. I've updated the question with the output I get – Rory Dec 18 '09 at 9:58
i expect (but don't know for sure) that tcprobe is examining file headers for this info. if it's not included in the header, tcprobe may not attempt a calculation for it. good question; wish i had a good answer for you. – quack quixote Feb 3 '10 at 7:59

I've found that the number of frames is actually twice the fps*duration (no idea why, I'd be happy know).

In a script of mine, I have:

# Get duration and fps
duration=$($FFMPEG -i $input 2>&1 | sed -n "s/.* Duration: \([^,]*\), start: .*/\1/p")
fps=$($FFMPEG -i $input 2>&1 | sed -n "s/.*, \(.*\) tb.*/\1/p")

hours=$(echo $duration | cut -d":" -f1)
minutes=$(echo $duration | cut -d":" -f2)
seconds=$(echo $duration | cut -d":" -f3)
# For some reason, we have to multiply by two (no idea why...)
# Get the integer part with cut
frames=$(echo "($hours*3600+$minutes*60+$seconds)*$fps*2" | bc | cut -d"." -f1)

And yes, for some reason I have to get the integer part of it. It doesn't make sense, but this script has always managed to convert my videos properly so far.

share|improve this answer
Because FPS stands for Frames Per Second (or first person shooter :D ) and if there's 30 FPS simply multiply it by how many seconds are in the video. – John T Dec 17 '09 at 16:38
Yes John, I could figure that out, but that doesn't explain why I have to multiply it by 2 to get the right amount of frames... In my case, after I calculated the amount of frames, I launched ffmpeg in the background and analyzed the logs to make a progress bar. The logs show how many frames have passed in the conversion. Once the whole video was converted, the frame # was int(seconds*fps*2), hence my code, but I'd like to know why ;-) – ℝaphink Dec 17 '09 at 17:08
that's curious; the tcprobe output in my answer gives the # of frames as exactly seconds*fps (rounded up). i expect you're seeing a quirk of ffmpeg. have you tried analyzing the file with other tools to see if they show the same number of frames? – quack quixote Dec 17 '09 at 17:34
Hmmm... Interesting. I tried on a video and I got seconds*fps=1001.59 and tcprobe=1002. So obviously, tcprobe tells me I don't need to multiply by two. Why then does ffmpeg give me a number that is twice as big in the logs when it's converting? – ℝaphink Dec 17 '09 at 17:55
is it interlaced footage? If so there are two fields per frame, and it could be giving you the number of fields. – stib Jun 14 '14 at 8:28

ffprobe -select_streams v -show_frames -count_frames INPUT_FILE | grep pkt_duration_time=

Add up the duration. Could be fancier with sed/awk and what not.

From our testing I can say that for now it has shown to be the best most reliable. You get a precise framecount and exact duration. Even with variable framerate which all other tools like mediainfo seem to go gaga.

share|improve this answer

I've found that mediainfo --fullscan inputfile | grep "Frame count" works nicely for most files.

Debian based systems can install it with apt-get mediainfo

If you get 2 lines rather than one of output the first line is the video track and the second line is the audio track. It appears that this occurs on files with Variable Bit Rate audio.

Tested on .mkv, .m4v, .mp4 and .avi samples as of date of edit.

Sources: How to retrieve video file information from command line under Linux and testing under Ubuntu flavors.

share|improve this answer

Tested on Ubuntu.

melt icecap.mp4 -consumer xml
  • melt - melt was meant as a test tool for the MLT framework, but it is also a powerful multitrack command line oriented video editor. It could also used as an minimalistic media player for audio and video files.

  • -consumer id[:arg] [name=value]*
    Set the consumer (sink)

  • xml - Set the consumer (sink) to xml formatted output

  • <property name="length">nnnn</property> - shows the number of frames, where nnnn is replaced by an integer number that equals the number of frames

If you don't have melt you can install it on Ubuntu and other Debian based systems with sudo apt-get install melt

share|improve this answer
This is very short, do you want to expand on what it does, why it works, etc? – David Dec 3 '15 at 20:42
This works well on h264 mp4 files which don't provide the framecount via mediainfo -fullscan filename. – Elder Geek Jun 6 at 17:28

You can do this by adding and multiplying the values you get from ffprobe .

Note: ffprobe is part of libav(avconv) - the linux version of ffmpeg.

#your command -
 ffprobe man.avi

When you do this you will get the number of frames per/second and also the duration of the clip.

Convert the duration of the clip to second's and the multiply that value by the number of frames/second.

Remember to round up number to the nearest.

share|improve this answer
On Ubuntu 14.04 LTS ffprobe is unavailable, but there is something called avprobe in libav-tools (which also provides avconv). But at my side it does not print any number of frames, at least not for the formats I tried. It just prints, what avprobe -i prints, too, and this is just some minor bits about the format, sadly. Even with -v debug it only tells me some nice properties of my hardware and software installed, but not a single bit of interesting information about the file/stream to probe. Perhaps it hides in some of the myriads of options which are available. Who knows? – Tino Feb 1 '15 at 2:27
@Tino ffprobe is indeed available as part of the ffmpeg package. avconv is a fork of ffmpeg and caused some confusion. See:… – Elder Geek Jun 9 at 14:11
@ElderGeek For Ubuntu 14.04 LTS there is no ffmpeg in the official repositories. The link you gave correctly states it: FFmpeg returned in Ubuntu 15.04 "Vivid Vervet".. However situation now changed as 16.04 LTS is out. – Tino Jun 9 at 16:02
@Tino That is indeed a fact. However I wouldn't equate unavailable with doesn't exist in the repositories. You'll note it's available for Trusty (14.04) here: – Elder Geek Jun 11 at 19:48

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .