How do I use ffmpeg to get the video resolution?

82,337

Solution 1

Use ffprobe

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4
  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
  width=1280
  height=720

With no key:

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

CSV

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

JSON

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of json input.mp4
{
    "programs": [

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

XML

$ ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of xml input.mp4
<?xml version="1.0" encoding="UTF-8"?>
<ffprobe>
    <programs>
    </programs>

    <streams>
        <stream width="1280" height="720"/>
    </streams>
</ffprobe>

Solution 2

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

Height:

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

1280

Width:

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

Solution 3

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}"

Solution 4

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

Solution 5

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.

Share:
82,337

Related videos on Youtube

Vladimir Stazhilov
Author by

Vladimir Stazhilov

Updated on September 18, 2022

Comments

  • Vladimir Stazhilov
    Vladimir Stazhilov over 1 year

    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.

  • slhck
    slhck over 9 years
    You also need to use STDERR. I fixed that part.
  • Nathaniel M. Beaver
    Nathaniel M. Beaver over 7 years
    Using eval is risky and not really necessary for this. stackoverflow.com/questions/17529220/…
  • Elisa Cha Cha
    Elisa Cha Cha about 6 years
    The output from ffmpeg is only meant for human eyes, and not meant to be parsed by scripts or other tools. The output is not standardized and so it is not guaranteed to be the same format for all files, so it is a fragile use case. Use ffprobe instead. Lots of examples here in this thread.
  • Elisa Cha Cha
    Elisa Cha Cha about 6 years
    @bariumbitmap Thanks. eval in the answer has been eliminated for a super simple solution that I somehow missed despite staring at the documentation for years.
  • Salem F
    Salem F almost 6 years
    I got two result with that command { "programs": [ { "streams": [ { "width": 640, "height": 360 } ] } ], "streams": [ { "width": 640, "height": 360 } ] }
  • Cyker
    Cyker almost 6 years
    @SalemF Append | sort -nur | head -n 1. This returns the resolution with the largest width. That being said, in all cases I've ever seen, there is only one resolution, but that may be duplicated.
  • aalaap
    aalaap over 5 years
    @LordNeckbeard I agree, but this is an option for those who do not wish to ffprobe for whatever reason.
  • Natim
    Natim almost 5 years
    Also your code play the whole file if I am not mistaken
  • Ωmega Δ
    Ωmega Δ over 4 years
    Could you please advise how to get simple output of the video length? Thanks
  • Elisa Cha Cha
    Elisa Cha Cha over 4 years
  • Ωmega Δ
    Ωmega Δ over 4 years
    @llogan - I would like to print them together (resolution and sexagesimal length) with running ffprobe just once. Possible?
  • Elisa Cha Cha
    Elisa Cha Cha over 4 years
    @ΩmegaΔ ffprobe -v error -sexagesimal -show_entries stream=width,height:format=duration -of default=nw=1 input.mp4
  • Ωmega Δ
    Ωmega Δ over 4 years
    @llogan - I used ffprobe -v error -select_streams v:0 -show_entries stream=width,height,duration -of csv=s=x:p=0 -sexagesimal input.mp4, but I would like to change separator s=x to a standard space character. I cannot find documentation how to use space character in csv parameter. Please advise. Thanks
  • Elisa Cha Cha
    Elisa Cha Cha over 4 years
    @ΩmegaΔ -of "csv=s=\ :p=0"
  • Ωmega Δ
    Ωmega Δ over 4 years
    @llogan - Genius! Thank you!!!