94

I am trying to get resolution of the video with the following command:

ffmpeg -i filename.mp4

I get a long output, but I need just the width and height for my bash script. How should I filter out those parameters? Maybe there's a better way to do this.

llogan
  • 63,280

7 Answers7

138

Use ffprobe

For example:

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4

Output in the format:

1280x720

Examples of other output formatting choices

See -of option documentation for more choices and options. Also see FFprobe Tips for other examples including duration and frame rate.

Default With No [STREAM] Wrapper

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=nw=1 input.mp4

Output in the format:

width=1280
height=720

Default With No Key

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of default=nw=1:nk=1 input.mp4

Output in the format:

1280
720

CSV

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 input.mp4

Output in the format:

1280,720

JSON

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of json input.mp4

Output in the format:

{
    "programs": [
],
"streams": [
    {
        "width": 1280,
        "height": 720
    }
]

}

XML

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of xml input.mp4

Output in the format:

<?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
    <programs>
    </programs>
&lt;streams&gt;
    &lt;stream width=&quot;1280&quot; height=&quot;720&quot;/&gt;
&lt;/streams&gt;

</ffprobe>

llogan
  • 63,280
11

The following commands rely purely on ffmpeg (and grep and cut) to get you the height or width as required:

Width:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f1

1280

Height:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}' | cut -d'x' -f2

720

The difference between the two is just the -f parameter to cut.

If you prefer the full resolution string, you don't need cut:

$ ffmpeg -i video.mp4 2>&1 | grep Video: | grep -Po '\d{3,5}x\d{3,5}'

1280x720

Here's what we're doing with these commands:

  1. Running ffmpeg -i to get the file info.
  2. Extracting the line which just contains Video: information.
  3. Extracting just a string that looks like digitsxdigits which are between 3 and 5 characters.
  4. For the first two, cutting out the text before or after the x.
aalaap
  • 730
4

The output of ffprobe looks like this:

streams_stream_0_width=1280
streams_stream_0_height=720

Technically, you can use eval to assign these to bash variables, but this is not necessary and can be unsafe; see here for more:

https://stackoverflow.com/questions/17529220/why-should-eval-be-avoided-in-bash-and-what-should-i-use-instead

Instead, since you are using bash, take advantage of its built-in arrays and string manipulation:

filepath="filename.mp4"
width_prefix='streams_stream_0_width='
height_prefix='streams_stream_0_height='
declare -a dimensions
while read -r line
do
    dimensions+=( "${line}" )
done < <( ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=width,height "${filepath}" )
width_with_prefix=${dimensions[0]}
height_with_prefix=${dimensions[1]}
width=${width_with_prefix#${width_prefix}}
height=${height_with_prefix#${height_prefix}}
printf "%s\t%sx%s\n" "${filepath}" "${width}" "${height}"
2

Use grep to select only those lines you are looking for. Redirect the output from STDERR to STDOUT, since ffmpeg will output all info there.

ffmpeg -i filename.mp4 2>&1 | grep <keyword>

Edit: A full working example using perl:

$ ffmpeg -i MVI_7372.AVI 2>&1 | grep Video | perl -wle 'while(<>){ $_ =~ /.*?(\d+x\d+).*/; print $1 }'
640x480
slhck
  • 235,242
Andreas F
  • 343
1

I know the question is about bash but, just in case someone ends here looking for a solution for a Windows batch, as myself before I found it out.

for /f "delims=" %%a in ('ffprobe -hide_banner -show_streams filename.mp4 2^>nul ^| findstr "^width= ^height="') do set "myvideo_%%a"

No console messages, and you end with the nice environment variables myvideo_width and myvideo_height. You can check it with:

C:\>set myvideo_
myvideo_height=720
myvideo_width=1280

If the resolution of your video is 1280x720, of course.

cdlvcdlv
  • 1,739
1

edit: FFPROBE solution for windows batch. Use this instead of the FFMPEG-only method, because that's parsing input meant for humans and it broke on me.

 ::Gets resolution
 for /f "tokens=*" %%g in ('"ffprobe.exe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "input.mp4""') do (set videoRes=%%g)

echo videoRes=%videoRes%

::OPTIONAL: Gets individual x and y resolutions if you want that for /f "tokens=1 delims=x" %%x in ("%videoRes%") do set "xRes=%%x" for /f "tokens=2 delims=x" %%y in ("%videoRes%") do set "yRes=%%y"

echo xRes=%xRes% echo yRes=%yRes%


FFMPEG-only solution for windows batch. Don't use because it's brittle. It probably only works if you only have 1 video stream in the file, you'll have to alter it if there are more.

@echo off >nul 2>&1
setlocal enableDelayedExpansion >nul 2>&1

for /f "tokens=*" %%g in ('"ffmpeg -i input.mp4 2>&1 | findstr Video:"') do (set videoInfo=%%g) for /f "tokens=4 delims=," %%g in ("!videoInfo!") do set "videoInfo=%%g" for /f "tokens=1 delims=x " %%x in ("!videoInfo!") do set "xRes=%%x" for /f "tokens=2 delims=x " %%y in ("!videoInfo!") do set "yRes=%%y"

echo xRes=!xRes! echo yRes=!yRes!

Hyper
  • 11
1

I finally found the answer:

I used this package called Media info

And then I commanded:

mediainfo mediainfo --Inform="Video;%Width%" midhand.mp4

To view the list of params:

mediainfo --Info-Parameters

Best tool to extract video metadata!