Getting video dimension / resolution / width x height from ffmpeg
Solution 1
Have a look at mediainfo Handles most of the formats out there.
If you looking for a way to parse the output from ffmpeg, use the regexp \d+x\d+
Example using perl:
$ ./ffmpeg -i test020.3gp 2>&1 | perl -lane 'print $1 if /(\d+x\d+)/'
176x120
Example using python (not perfect):
$ ./ffmpeg -i /nfshome/enilfre/pub/test020.3gp 2>&1 | python -c "import sys,re;[sys.stdout.write(str(re.findall(r'(\d+x\d+)', line))) for line in sys.stdin]"
[][][][][][][][][][][][][][][][][][][]['176x120'][][][]
Python one-liners aren't as catchy as perl ones :-)
Solution 2
Use ffprobe
Example 1: With keys / variable names
ffprobe -v error -show_entries stream=width,height -of default=noprint_wrappers=1 input.mp4
width=1280
height=720
Example 2: Just width x height
ffprobe -v error -select_streams v -show_entries stream=width,height -of csv=p=0:s=x input.m4v
1280x720
Example 3: JSON
ffprobe -v error -select_streams v -show_entries stream=width,height -of json input.mkv
{
"programs": [
],
"streams": [
{
"width": 1280,
"height": 720
}
]
}
Example 4: JSON Compact
ffprobe -v error -select_streams v -show_entries stream=width,height -of json=compact=1 input.mkv
{
"programs": [
],
"streams": [
{ "width": 1280, "height": 720 }
]
}
Example 5: XML
ffprobe -v error -select_streams v -show_entries stream=width,height -of xml input.mkv
<?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
<programs>
</programs>
<streams>
<stream width="1280" height="720"/>
</streams>
</ffprobe>
What the options do:
-
-v error
Make a quiet output, but allow errors to be displayed. Excludes the usual generic FFmpeg output info including version, config, and input details. -
-show_entries stream=width,height
Just show thewidth
andheight
stream information. -
-of
option chooses the output format (default, compact, csv, flat, ini, json, xml). See FFprobe Documentation: Writers for a description of each format and to view additional formatting options. -
-select_streams v:0
This can be added in case your input contains multiple video streams.v:0
will select only the first video stream. Otherwise you'll get as manywidth
andheight
outputs as there are video streams.-select_streams v
can be used to show info from all video streams and avoid empty audiostream
info in JSON and XML output. -
See the FFprobe Documentation and FFmpeg Wiki: FFprobe Tips for more info.
Solution 3
As mentioned here, ffprobe
provides a way of retrieving data about a video file. I found the following command useful ffprobe -v quiet -print_format json -show_streams input-video.xxx
to see what sort of data you can checkout.
I then wrote a function that runs the above command and returns the height and width of the video file:
import subprocess
import shlex
import json
# function to find the resolution of the input video file
def findVideoResolution(pathToInputVideo):
cmd = "ffprobe -v quiet -print_format json -show_streams"
args = shlex.split(cmd)
args.append(pathToInputVideo)
# run the ffprobe process, decode stdout into utf-8 & convert to JSON
ffprobeOutput = subprocess.check_output(args).decode('utf-8')
ffprobeOutput = json.loads(ffprobeOutput)
# find height and width
height = ffprobeOutput['streams'][0]['height']
width = ffprobeOutput['streams'][0]['width']
return height, width
Solution 4
From Fredrik's tip above, here is how I did it using MediaInfo ( http://mediainfo.sourceforge.net/en ):
>>> p1 = subprocess.Popen(['mediainfo', '--Inform=Video;%Width%x%Height%',
'/Users/david/Desktop/10stest720p.mov'],stdout=PIPE)
>>> dimensions=p1.communicate()[0].strip('\n')
>>> dimensions
'1280x688'
Solution 5
In this blog post theres a rough solution in python:
import subprocess, re
pattern = re.compile(r'Stream.*Video.*([0-9]{3,})x([0-9]{3,})')
def get_size(pathtovideo):
p = subprocess.Popen(['ffmpeg', '-i', pathtovideo],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
match = pattern.search(stderr)
if match:
x, y = map(int, match.groups()[0:2])
else:
x = y = 0
return x, y
This however assumes it's 3 digits x 3 digits (i.e. 854x480), you'll need to loop through the possible dimension lengths, such as (1280x720):
possible_patterns = [re.compile(r'Stream.*Video.*([0-9]{4,})x([0-9]{4,})'), \
re.compile(r'Stream.*Video.*([0-9]{4,})x([0-9]{3,})'), \
re.compile(r'Stream.*Video.*([0-9]{3,})x([0-9]{3,})')]
and check if match returns None on each step:
for pattern in possible_patterns:
match = pattern.search(stderr)
if match!=None:
x, y = map(int, match.groups()[0:2])
break
if match == None:
print "COULD NOT GET VIDEO DIMENSIONS"
x = y = 0
return '%sx%s' % (x, y)
Could be prettier, but works.
Related videos on Youtube
David542
Updated on May 29, 2021Comments
-
David542 about 3 years
How would I get the height and width of a video from
ffmpeg
's information output. For example, with the following output:$ ffmpeg -i video.mp4 ... Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'video.mp4': Metadata: major_brand : isom minor_version : 1 compatible_brands: isomavc1 creation_time : 2010-01-24 00:55:16 Duration: 00:00:35.08, start: 0.000000, bitrate: 354 kb/s Stream #0.0(und): Video: h264 (High), yuv420p, 640x360 [PAR 1:1 DAR 16:9], 597 kb/s, 25 fps, 25 tbr, 25k tbn, 50 tbc Metadata: creation_time : 2010-01-24 00:55:16 Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 109 kb/s Metadata: creation_time : 2010-01-24 00:55:17 At least one output file must be specified
How would I get
height = 640, width= 360
? -
Geoff about 9 yearsThis is helpful, but I think OP wanted to capture the values in python.
-
llogan about 9 years@Geoff This will provide the needed values, and will be more reliable than the other method shown here. How it's used with Python is up to the user.
-
P.R. about 9 yearsThis one fails in when I tested, because the stream info is
Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj420p(pc, bt470bg/unknown/unknown), 733x446 [SAR 1:1 DAR 733:446], 7516 kb/s, 60 fps, 60 tbr, 60 tbn, 60 tbc
, so the result is[][][][][][][][][][][][][]['0x47504', '733x446'][]
-
Geoff about 9 yearsIndeed. It helped me a lot. Thanks. Very easy to parse with
re.search
using thesubprocess
package to capture the output. Sorry for sounding negative. -
Simon Steinberger almost 9 years
-of json
returns the data in JSON format, which is easier accessible in Python (avoiding regex). -
llogan almost 9 years@SimonSteinberger Edited to mention json, along with all the other available formats.
-
Agile Bean almost 6 yearsThe advantage of this solution is that it returns the correct dimensions not only for mp4 but also m4v. The method by @oldo.nicho proposed wouldn't work as m4v stores the dimensions not in the first but second json array
-
Agile Bean almost 6 yearsThis is great but it doesn't work for m4v which stores the dimensions in the second array. so only then, the dimensions must be retrieved by
height = ffprobeOutput['streams'][1]['height']
andwidth = ffprobeOutput['streams'][0]['width']
-
nicbou over 3 yearsThis is an excellent answer. If you pass the JSON output to Python, you can parse it with
json.loads(cmd_output)
. You saved me quite a bit of trouble! -
zui-coding over 3 yearsSometime ,the width and height value are wrong, It may be related to display_aspect_ratio, I encountered this situation. please help me
-
llogan over 3 years@zui-coding You should ask a new question. Show your command and the full log, and describe how you determine the values are wrong.
-
Choy almost 3 yearspossible to get video resolution? 4k? 2k?
-
llogan almost 3 years@Choy ffprobe can't tell you if something is 4k or 2k or whatever. It will tell you the width and height of the video which you can use to determine if something is 4k. For example, if ffprobe gives you 4096x3072 then that is 4k.
-
Hashim Aziz over 2 yearsIn the second example, what does the
v
afterselect_streams
do? -
llogan over 2 years@HashimAziz It is mentioned in the answer: "
-select_streams v:0
This can be added in case your input contains multiple video streams.v:0
will select only the first video stream. Otherwise you'll get as many width and height outputs as there are video streams.-select_streams v
can be used to show info from all video streams and avoid empty audio stream info in JSON and XML output." So it has been added to avoid the extra, empty lines for that blank audio info that appear for some output formats. -
Hashim Aziz over 2 years@llogan Apologies, it was late and I was skimming
-
llogan over 2 years@HashimAziz I didn't even remember it was there until I was about to reply. I'm guessing 98% of readers skip the notes anyway.
-
Mark Rogers over 2 yearsI think the answer is cool, but its usually easier to get access to ffmpeg than ffprobe because many libraries carry a copy of one but not the other.