How do I get the number of frames in a video on the linux command line?

Solution 1:

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)

Solution 2:

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:

nb_frames=159697

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

Solution 3:

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).