90

Is there any simple way to find the fps of a video in ubuntu? In windows I use Gspot to find out all the information about a video file. But in ubuntu I find it very difficult to find out this basic information. Any help is appreciated.

Vivek
  • 3,749

15 Answers15

103

This will tell you the framerate if it's not variable framerate:

ffmpeg -i filename

Sample output with filename obscured:

Input #0, matroska,webm, from 'somerandom.mkv':
  Duration: 01:16:10.90, start: 0.000000, bitrate: N/A
    Stream #0.0: Video: h264 (High), yuv420p, 720x344 [PAR 1:1 DAR 90:43], 25 fps, 25 tbr, 1k tbn, 50 tbc (default)
    Stream #0.1: Audio: aac, 48000 Hz, stereo, s16 (default)
ffmpeg -i filename 2>&1 | sed -n "s/.*, \(.*\) fp.*/\1/p"

Someone edited with one that didn't quite work the way I wanted. It's referenced here
Additional edit...If you want the tbr value this sed line works

sed -n "s/.*, \(.*\) tbr.*/\1/p"
RobotHumans
  • 29,530
  • I needed to use tb instead of fp in the one-liner. Seems not all video files report fps but all autput something like tbr tbc which has the same value. – sup Mar 11 '12 at 17:28
  • valid, but the one-liner from the edit output-ed the tbc value not the tbr value in this particular set of output. something to consider on why i changed it...I'ld rather it fail in a really noticeable way than a way that isn't noticed at all. – RobotHumans Mar 11 '12 at 20:10
  • I think sed -n "s/.*, \(.*\) tbr.*/\1/p misses " in the end, no? – sup Mar 12 '12 at 19:24
  • 10
    ffmpeg is not deprecated, avconv came from a branch of ffmpeg and to avoid confusion for those using the ffmpeg alternative the fake branch was marked as deprecated to let those users know that the version they were using was changing. your comment is misleading and could cause users to waste time researching this – Chris Apr 20 '16 at 14:07
  • 1
    What if it is variable frame rate? – 0xcaff Dec 24 '16 at 00:28
  • It specifies VBR in the output. – RobotHumans Dec 24 '16 at 09:07
  • For both constant and variable bit-rate see my solution. – Alberto Salvia Novella Mar 31 '20 at 06:56
  • 1
    ffmpeg output is not meant to be machine parsed. Use ffprobe instead which is meant for this type of usage and you won't need sed. See some of the answers for this questions or FFmpeg Wiki: FFprobe. – llogan Oct 01 '20 at 17:27
58
ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate infile

Result:

2997/100
Zombo
  • 1
  • 4
    This is probably the best answer in that it gives the EXACT frame rate (in the example 24000/1001 = 23.976023976) – ntg Jan 20 '16 at 12:30
  • 1
    sometimes i get 0/0 depending on the format – Daniel_L Feb 13 '17 at 21:53
  • 3
    Depending on what you want, this either works or doesn't. It reports the framerate of the encoding, but not the actual framerate of the video. For example, a 30fps video encoded into 60fps will report 60fps but will still be 30fps in actual output. – Harvey Jul 20 '17 at 17:16
  • 11
    This didn't work if the video stream is not the first stream, you will get 0/0 if it looks at an audio stream. I will edit to put -select_streams V:0, which will select the first moving video stream. – Sam Watkins Sep 21 '17 at 06:44
  • 2
    @SamWatkins's complement is important. Without it, the command given output 0/0. – jdhao Jun 06 '18 at 05:12
  • Not sure about Linux but Windows was expecting -i before the infile parameter. The command would be ffprobe ..... -i infile – Chef Pharaoh Mar 14 '20 at 18:19
  • ¡¡¡¡WRONG!!! This is the encoder frame-rate, not the video frame-rate. They could match, bun not necessarily! See my solution for the correct answer. – Alberto Salvia Novella Mar 31 '20 at 06:54
  • I noticed that r_frame_rate can return misleading numbers! avg_frame_rate was much more correct. – FloPinguin Oct 27 '20 at 15:11
  • From a video/codec point-of-view, how are these 2 numbers determined? Like why is it 2997 by 100 and not 299.7/10, etc. – Raleigh L. May 09 '23 at 21:06
  • This solution also doesn't work in situations where there are 2 (?) video streams. For some videos I get this result:
    30/1
    
    30/1
    
    – Raleigh L. Jun 15 '23 at 18:30
10

Here is a python function based on Steven Penny's answer using ffprobe that gives exact frame rate

ffprobe 'Upstream Color 2013 1080p x264.mkv' -v 0 -select_streams v -print_format flat -show_entries stream=r_frame_rate
import sys
import os
import subprocess
def get_frame_rate(filename):
    if not os.path.exists(filename):
        sys.stderr.write("ERROR: filename %r was not found!" % (filename,))
        return -1         
    out = subprocess.check_output(["ffprobe",filename,"-v","0","-select_streams","v","-print_format","flat","-show_entries","stream=r_frame_rate"])
    rate = out.split('=')[1].strip()[1:-1].split('/')
    if len(rate)==1:
        return float(rate[0])
    if len(rate)==2:
        return float(rate[0])/float(rate[1])
    return -1
muru
  • 197,895
  • 55
  • 485
  • 740
ntg
  • 541
  • rate = out.decode("utf-8").split('"')[1].split('/') would be better: It handles the case of multiple video streams. Also, I needed to turn the subprocess output into a string with decode. – FloPinguin Oct 27 '20 at 15:10
  • I noticed that r_frame_rate can return misleading numbers! avg_frame_rate was much more correct. – FloPinguin Oct 27 '20 at 15:11
3

Retrieve the average frame-rate, given as a fraction:

fraction=$(ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=nw=1:nk=1 "${input}")

Then divide it by rounding to the nearest integer:

python -c "print (round(${fraction}))"

2

The alternative to command line, is looking at the properties of your file via context menu in Nautilus (graphical file manager). For audio/video files you get an additional tab there with extra informations.

2

This is a python script to do this using mplayer, in case anyone is interested. It is used path/to/script path/to/movie_name1 path/to/movie/name2 etc

#!/usr/bin/python
# -*- coding: utf-8 -*-

import subprocess
import re
import sys

pattern = re.compile(r'(\d{2}.\d{3}) fps')
for moviePath in sys.argv[1:]:
    mplayerOutput = subprocess.Popen(("mplayer", "-identify", "-frames", "0", "o-ao", "null", moviePath), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
    fps = pattern.search(mplayerOutput).groups()[0]
    print fps
muru
  • 197,895
  • 55
  • 485
  • 740
sup
  • 4,862
  • This is not really exhaustive. For example, your regex will not match videos with 120 fps, and it will also fail on 25 fps. Also, you need to escape the .. So, use: (\d+(\.\d+)?) fps – slhck Jul 21 '20 at 08:21
  • Well, this is very outdated now anyway. Nowadays just one plays it in MPV and preses i, – sup Jul 22 '20 at 11:50
1

I usually use exiftool to get info of any file type... For example with command exiftool file.swf I can know the framerate of any swf file, something I cannot achieve with ffmpeg

aesede
  • 131
1

Uses the stats script bundled by default with MPV. So just play the file with MPV and press i. A bunch of statistics including framerate will appear.

sup
  • 4,862
0

Just in case someone stumbles upon this... you can of course use input arg as the path ;)

import numpy as np
import os
import subprocess

def getFramerate():
    con = "ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1:nokey=1 D:\\Uni\\Seminar\\leecher\\Ninja\\stream1.mp4"

    proc = subprocess.Popen(con, stdout=subprocess.PIPE, shell=True)
    framerateString = str(proc.stdout.read())[2:-5]
    a = int(framerateString.split('/')[0])
    b = int(framerateString.split('/')[1])
    return int(np.round(np.divide(a,b)))
WhatAMesh
  • 101
0
framerate=$(( $(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "$1" | sed 's#/# / #g') ))

^ this will return the exact frame rate, and do the maths on it, to give you the final exact frame rate (it will convert 25.000/1 to 25, for example)

No need for Python (requires a Bash-like shell)

sc0ttj
  • 1
0
$fps = exec("ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate input.mkv");
$fps = round(strstr($fps, '/' , true) / substr (strstr($fps, '/'), 1 ), 2);

Output Example: 29.97 or 59.94

Gryu
  • 7,559
  • 9
  • 33
  • 52
0

You can get the framerate with mediainfo cli too.

mediainfo "filename.mov" "--inform=Video;%FrameRate%"
Mint
  • 101
  • 2
0

Python Code to Get a Few things including frames per second (fps), number of frames, height, width.

def get_video_info(filename):
#r_frame_rate is "the lowest framerate with which all timestamps can be 
#represented accurately (it is the least common multiple(LCM) of all framerates in the stream)."
result = subprocess.run(
    [
        "ffprobe",
        "-v",
        "error",
        "-select_streams",
        "v:0",
        "-show_entries",
        "stream=avg_frame_rate,r_frame_rate,nb_frames,width,height",
        filename,
    ],
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
)
ffprobe_out = str(result.stdout, 'utf-8')
print(ffprobe_out)
r_frame_rate = int(ffprobe_out.split('r_frame_rate=')[1].split('\n')[0].split('/')[0])
avg_frame_rate = int(ffprobe_out.split('avg_frame_rate=')[1].split('\n')[0].split('/')[0])
nb_frames = int(ffprobe_out.split('nb_frames=')[1].split('\n')[0])
height = int(ffprobe_out.split('height=')[1].split('\n')[0])
width = int(ffprobe_out.split('width=')[1].split('\n')[0])
return (r_frame_rate, avg_frame_rate, nb_frames, height, width)
Ankur Bhatia
  • 101
  • 1
0
ffprobe <media> 2>&1| grep ",* fps" | cut -d "," -f 5 | cut -d " " -f 2
Raja G
  • 102,391
  • 106
  • 255
  • 328
Daya
  • 11
0

You can right click the target file, Properties, Audio/Video but you will not get the exact framerate. To get a precise framerate you can install MediaInfo.

vladmateinfo
  • 1,435
  • 2
  • 14
  • 11