Home / Alt manpages / ffprobe-all(1)

  • ffprobe-all(1)
  • User command
  • linux

Inspect Media Files with ffprobe, Then Make the Output Scriptable

You will use ffprobe to identify a media container, inspect its streams, and produce a small JSON report that a shell script can consume. The examples match FFmpeg 8.0.1, installed here from the ffmpeg package. Allow about fifteen minutes if you already have a media file to inspect.

This is a read-only workflow. ffprobe opens a local path or URL, probes the content and writes information to standard output unless you choose an output file. It does not transcode, repair or rewrite the input. You need a shell, the installed ffmpeg package, and a readable input such as /path/to/video.mp4. No command below needs sudo.

1. Check the installed tool

Confirm which executable will run and record its version. This is an ordinary, read-only check:

$ command -v ffprobe
/usr/bin/ffprobe
$ ffprobe -version | head -2
ffprobe version 8.0.1 Copyright (c) 2007-2025 the FFmpeg developers
built with gcc 12 (Ubuntu 12.3.0-1ubuntu1~22.04.2)

Your build configuration and library versions may differ. Keep the version with any diagnostic report because supported formats and compiled-in protocols depend on the build.

2. Get a readable human overview

Start with the input alone. Replace the placeholder with a path you can read:

$ ffprobe /path/to/video.mp4

The default writer prints sections such as Input, Metadata, Stream and Format. Informational messages normally go to standard error, while the probe report goes to standard output. That split is useful when you redirect the report, but it can make a terminal result look busier than expected.

For a quieter report that hides the copyright and build banner, use -hide_banner:

$ ffprobe -hide_banner /path/to/video.mp4

Checkpoint: a recognised input should produce at least one stream and a format section. If the command says it cannot open or recognise the input, stop here and check the path before adding more options.

3. Separate container and stream information

Use -show_format for the container and -show_streams for each media stream. This makes it easier to answer two different questions: what file wrapper is this, and what audio, video, subtitle or data streams does it contain?

$ ffprobe -hide_banner -show_format -show_streams /path/to/video.mp4

A FORMAT section describes the container, including fields such as format name and duration when the input supplies them. Each STREAM section describes one stream. Video entries commonly include dimensions and a codec name; audio entries commonly include sample rate, channel count and codec information. The exact fields depend on the input and the demuxer.

To inspect only audio streams, add the stream specifier a:

$ ffprobe -hide_banner -show_streams -select_streams a /path/to/video.mp4

Use v for video. A specifier such as v:1 selects the second video stream. Stream numbering is based on the order detected by libavformat, so do not assume that the first stream is always video.

4. Produce JSON for scripts

Human output is useful at a terminal, but scripts should consume a structured writer. The manual calls the option -output_format, with -of and -print_format as aliases. Select the JSON writer:

$ ffprobe -v error -of json -show_format -show_streams /path/to/video.mp4 > report.json
$ test -s report.json && echo "report written"
report written

-v error limits library logging to errors, so routine warnings do not get mixed into the JSON stream. The redirection creates or truncates report.json, so do not point it at a valuable existing report unless replacement is intended. To replace a report more safely, write a temporary name and move it only after ffprobe succeeds:

$ ffprobe -v error -of json -show_format -show_streams /path/to/video.mp4 > report.json.tmp && mv report.json.tmp report.json

If the probe fails, the && prevents the move. Remove an incomplete temporary file with rm report.json.tmp only after checking that it is the temporary file you meant to discard. The original report is otherwise left in place.

5. Limit the JSON fields you need

-show_entries reduces output by naming sections and their fields. The separator between sections is a colon; fields within a section are comma-separated. For example, this keeps the container format name and duration, plus the index, type and codec name of each stream:

$ ffprobe -v error -of json \
    -show_entries 'format=format_name,duration:stream=index,codec_type,codec_name' \
    /path/to/video.mp4

The output order is controlled by the writer rather than by the order in which local fields appear in the option. A missing value is not necessarily an error: a live source or an unusual container may not provide a duration or a codec field.

For a quick video-only report, combine the same filter with -select_streams v:

$ ffprobe -v error -of json -select_streams v \
    -show_entries 'stream=index,width,height,avg_frame_rate,codec_name' \
    /path/to/video.mp4

Keep the quotes around the -show_entries value. The punctuation is part of ffprobe's expression and should not be altered by shell expansion.

6. Check duration and timing without changing the file

By default, time values are printed in seconds when the selected writer exposes them. Add -sexagesimal when a clock-shaped value is easier to read:

$ ffprobe -v error -sexagesimal -show_entries format=duration \
    -of default=noprint_wrappers=1:nokey=1 /path/to/video.mp4
00:12:34.560000

The default writer options remove section wrappers and field names, leaving the value on its own line. Do not parse that form as JSON. Use -of json when another program needs named fields, and use the default writer form when a one-line shell value is the useful result.

For a large or remote input, -read_intervals can limit the portion read. For example, %+20 asks ffprobe to read the first twenty seconds. Seeking is not exact, so treat interval output as a bounded probe rather than a frame-accurate extraction:

$ ffprobe -v error -read_intervals '%+20' -show_streams /path/to/video.mp4

7. Diagnose failures and avoid noisy traps

Check the exit status immediately after a probe:

$ ffprobe -v error -of json -show_format /path/to/video.mp4 > report.json
$ printf 'ffprobe exit status: %s\n' "$?"
ffprobe exit status: 0

A positive exit status means ffprobe could not open or recognise the input, or encountered another failure. Test the path without changing anything:

$ ls -l /path/to/video.mp4
$ test -r /path/to/video.mp4 && echo readable

Do not use -f just to silence an error. It forces an input format and can make a valid file fail when the forced demuxer is wrong. Likewise, do not add -show_packets or -show_frames to a routine metadata check: those options can generate very large output. Use them only when packet or frame-level evidence is the actual question.

If a URL is the input, ffprobe will try to open and probe it using the protocols available in this build. Network access is then part of the operation, and an untrusted URL can cause traffic to a system or service you did not intend to contact. Prefer a local copy for repeatable diagnostics, and verify a remote URL before probing it.

Done means

  • You confirmed the installed ffprobe version and used the ffmpeg package's command.
  • You distinguished container data from per-stream data with -show_format and -show_streams.
  • You selected streams deliberately rather than assuming stream index 0 was the desired one.
  • You used JSON and -show_entries for machine-readable reports.
  • You checked the exit status, kept temporary output separate, and left the input file unchanged.