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…

1 year ago

Merrimu Reservoir drone images

Merrimu Reservoir from drone. Click images to view larger.

1 year ago

FTP getting array of file details such as size using PHP

Using FTP and PHP to get an array of file details such as size and…

2 years ago

Creating Laravel form requests

Creating and using Laravel form requests to create cleaner code, separation and reusability for your…

2 years ago

Improving the default Laravel login and register views

Improving the default Laravel login and register views in such a simple manner but making…

2 years ago

Laravel validation for checking if value exists in the database

Laravel validation for checking if a field value exists in the database. The validation rule…

2 years ago