Categories: Computing

Getting video resolution, bitrate, fps, size and more with ffprobe

FFmpeg can do a massive amount of things, getting video details can be done with FFmpeg however there is a special offspring from FFmpeg called ffprobe that is dedicated to getting you this information.

Its use is super simple and what it can return is super beneficial.

You can view all the possible outputs here, I am going to show you how to output all the available data into a JSON file:

ffprobe -v quiet -print_format json -show_format -show_streams '/path/media/thevideo.mp4' > thevideo.json

or

ffprobe -v quiet -print_format json -show_format -show_streams 'https://website.com/media/avideo.mp4' > avideo.json

quite means it runs without console output, -print_format json is the JSON formatted output, -show_format attaches the format section to the data (see example below) and -show_streams shows the stream information which is the main part.

The output will look like this:

{
  "streams": [
    {
      "index": 0,
      "codec_name": "h264",
      "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",
      "profile": "Main",
      "codec_type": "video",
      "codec_time_base": "6337331/379867500",
      "codec_tag_string": "avc1",
      "codec_tag": "0x31637661",
      "width": 1280,
      "height": 720,
      "coded_width": 1280,
      "coded_height": 720,
      "has_b_frames": 2,
      "sample_aspect_ratio": "1:1",
      "display_aspect_ratio": "16:9",
      "pix_fmt": "yuv420p",
      "level": 31,
      "color_range": "tv",
      "color_space": "bt709",
      "color_transfer": "bt709",
      "color_primaries": "bt709",
      "chroma_location": "left",
      "refs": 1,
      "is_avc": "true",
      "nal_length_size": "4",
      "r_frame_rate": "30000/1001",
      "avg_frame_rate": "189933750/6337331",
      "time_base": "1/90000",
      "start_pts": 0,
      "start_time": "0.000000",
      "duration_ts": 152095950,
      "duration": "1689.955000",
      "bit_rate": "5885980",
      "bits_per_raw_sample": "8",
      "nb_frames": "50649",
      "disposition": {
        "default": 1,
        "dub": 0,
        "original": 0,
        "comment": 0,
        "lyrics": 0,
        "karaoke": 0,
        "forced": 0,
        "hearing_impaired": 0,
        "visual_impaired": 0,
        "clean_effects": 0,
        "attached_pic": 0,
        "timed_thumbnails": 0
      },
      "tags": {
        "creation_time": "2019-12-28T14:44:58.000000Z",
        "language": "und",
        "handler_name": "VideoHandler"
      }
    },
    {
      "index": 1,
      "codec_name": "aac",
      "codec_long_name": "AAC (Advanced Audio Coding)",
      "profile": "LC",
      "codec_type": "audio",
      "codec_time_base": "1/48000",
      "codec_tag_string": "mp4a",
      "codec_tag": "0x6134706d",
      "sample_fmt": "fltp",
      "sample_rate": "48000",
      "channels": 2,
      "channel_layout": "stereo",
      "bits_per_sample": 0,
      "r_frame_rate": "0/0",
      "avg_frame_rate": "0/0",
      "time_base": "1/48000",
      "start_pts": -64,
      "start_time": "-0.001333",
      "duration_ts": 81121248,
      "duration": "1690.026000",
      "bit_rate": "164621",
      "max_bit_rate": "164621",
      "nb_frames": "79222",
      "disposition": {
        "default": 1,
        "dub": 0,
        "original": 0,
        "comment": 0,
        "lyrics": 0,
        "karaoke": 0,
        "forced": 0,
        "hearing_impaired": 0,
        "visual_impaired": 0,
        "clean_effects": 0,
        "attached_pic": 0,
        "timed_thumbnails": 0
      },
      "tags": {
        "creation_time": "2020-01-08T16:42:58.000000Z",
        "language": "eng",
        "handler_name": "SoundHandler"
      }
    }
  ],
  "format": {
    "filename": "/path/to/video.mp4",
    "nb_streams": 2,
    "nb_programs": 0,
    "format_name": "mov,mp4,m4a,3gp,3g2,mj2",
    "format_long_name": "QuickTime / MOV",
    "start_time": "-0.001333",
    "duration": "1690.070000",
    "size": "1279988019",
    "bit_rate": "6058863",
    "probe_score": 100,
    "tags": {
      "major_brand": "mp42",
      "minor_version": "512",
      "compatible_brands": "isomiso2avc1mp41",
      "creation_time": "2019-12-28T14:44:58.000000Z",
      "title": "Video title",
      "artist": "Admin",
      "album_artist": "Admin",
      "encoder": "HandBrake 1.2.0 2018122200",
      "description": "This video is about xyz"
    }
  }
}

You will see the first index in streams is details about the video data and the second is about audio. The size value is in bytes whilst the bitrate is in bits.

You can get the true frame rate by following the equation listed at r_frame_rate which is 30000/1001 = 29.97 fps.

If the video file did not have audio then the index 2 would not exist, keep in mind the if there was subtitle tracks then there would also be data for that.

 

Share

Recent Posts

Kennington reservoir drained drone images

A drained and empty Kennington reservoir images from a drone in early July 2024. The…

2 years ago

Merrimu Reservoir drone images

Merrimu Reservoir from drone. Click images to view larger.

2 years ago

Early September spring shots

Some early September spring shots from a bushwalk, It is still too early for wildflowers.

3 years ago

Cloning an NVMe to SK Hynix Platinum P41 NVMe

I recently needed to clone over a smaller NVMe to a 2TB SK Hynix Platinum…

3 years ago

Using Laravel’s deleteDirectory to delete folders and their contents

If you ever needed a simple solution in Laravel to delete an entire directory and…

3 years ago

How to allow only 1 user to register in a Laravel application

How to enforce only one user to register or be registered in a Laravel web…

3 years ago