Home / Alt manpages / ffprobe(1)

  • ffprobe(1)
  • User command
  • linux

Inspect Media Streams Reliably with ffprobe

You will finish with a repeatable way to inspect a media file, identify its container and streams, and produce small JSON output for scripts. The examples use ffprobe 8.0.1 from the installed FFmpeg package on this machine. Allow about fifteen minutes if the input file is already available.

You need a shell, a readable media file, and the ffprobe command. The commands are read-only unless you deliberately use -o to write a report. No example needs elevated privileges. Do not run ffprobe as root merely because a file is inconvenient to read: fix the file's ownership or permissions through your normal system administration process.

1. Check the installed command

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

$ command -v ffprobe
/home/linuxbrew/.linuxbrew/bin/ffprobe
$ ffprobe -version | head -n 1
ffprobe version 8.0.1 Copyright (c) 2007-2025 the FFmpeg developers

The exact path and build options vary between hosts. Keep the version with any automated report, because available demuxers, protocol support and output details depend on the build.

Checkpoint: if command -v ffprobe prints nothing, stop and install or expose the FFmpeg package using your distribution's normal package process. Do not copy a binary from an unrelated host.

2. Get a human-readable first look

Replace the placeholder with a path to your own file. Quote it so spaces and shell metacharacters in the path remain part of the filename:

$ ffprobe -hide_banner /path/to/input.mkv

ffprobe writes its normal diagnostic messages to standard error and the selected report to standard output. The default report is divided into named sections such as FORMAT and STREAM. A successful probe usually shows the container name, duration, stream indexes, codecs and dimensions or audio properties.

-hide_banner removes the copyright, build and library-version banner. It does not hide probe results or errors. If you need a quiet command for a script, use -v error as well:

$ ffprobe -hide_banner -v error /path/to/input.mkv
$ printf 'exit status: %s\n' "$?"
exit status: 0

A non-zero status means the input could not be opened, recognised or probed successfully. Treat that status as authoritative; do not decide that a file is valid because part of a report appeared on screen.

3. Separate container facts from stream facts

Use the two focused display options when you know what you need. -show_format reports the container, while -show_streams reports each media stream:

$ ffprobe -v error -show_format -show_streams /path/to/input.mkv

Stream indexes are zero-based and follow the order detected by the input libraries. A video stream at index 0 is not necessarily the first stream in every file. Select by type when you need all audio or video streams:

$ ffprobe -v error -select_streams a -show_streams /path/to/input.mkv
$ ffprobe -v error -select_streams v -show_streams /path/to/input.mkv

The selector affects stream-related reports such as streams and packets. It does not turn a format report into a stream report. This is a common distraction when a command appears to ignore -select_streams.

4. Produce focused JSON

JSON is safer for a program than scraping the default section headings. Combine -of json with -show_entries to limit the fields and keep the result reviewable:

$ ffprobe -v error -of json \
    -show_entries 'format=filename,format_name,duration:stream=index,codec_type,codec_name,width,height,sample_rate,channels' \
    /path/to/input.mkv

The colon separates sections. Within a section, commas select fields. The installed command may retain fields that do not apply to a particular stream, so a video stream can omit audio-only values. Do not assume that every key exists or that all values are numeric. Handle absent fields and the fact that many time and rate values are represented as strings.

Checkpoint: validate the output with a JSON parser if it will enter a pipeline:

$ ffprobe -v error -of json -show_format /path/to/input.mkv | jq empty
$ printf 'JSON status: %s\n' "$?"
JSON status: 0

jq is a separate tool and is not required by ffprobe. If it is unavailable, save the output temporarily and use the JSON parser already approved for your application.

5. Measure packets or frames only when needed

Counting requires ffprobe to read the relevant material, so it can take longer than a metadata-only probe. Ask for counts per stream explicitly:

$ ffprobe -v error -count_packets -count_frames -show_streams /path/to/input.mkv

The resulting stream sections can contain nb_read_packets and nb_read_frames. Counts are about what ffprobe read and decoded for this input and build; they are not a promise that a damaged file contains every frame expected by a player.

For a bounded inspection, -read_intervals accepts intervals such as %+20 for the first twenty seconds or 01:23%+#42 for 42 packets after a seek point. Seeking is not exact, especially with compressed formats, so use intervals to reduce work, not to make frame-accurate editing decisions.

6. Handle failures without making the problem worse

Keep the original input untouched. ffprobe only reads it when no output destination is supplied. If you choose -o report.txt, the destination is state-changing and can overwrite an existing file, so use a new path:

$ ffprobe -v error -show_format -show_streams \
    -o /tmp/ffprobe-report.txt /path/to/input.mkv
$ test -s /tmp/ffprobe-report.txt && echo 'report written'

Remove that temporary report when it is no longer needed. Before any batch job, check that the input is readable and that the output directory has enough space. A permission error is not fixed by changing probe options; use the correct account or access path.

If a probe fails, rerun with the normal diagnostics visible, without -v error. Then check the path, file type and permissions. A positive exit status is expected for an unrecognised or inaccessible URL or file. Do not pass untrusted URLs to a script without considering the protocols enabled by your local FFmpeg build and the network access that the script permits.

Done means

  • You confirmed the installed ffprobe executable and version.
  • You can distinguish container output from per-stream output.
  • Your automation uses focused JSON and checks the exit status.
  • You select streams by type rather than assuming fixed indexes.
  • You use packet or frame counts and read intervals with their performance and accuracy limits understood.
  • The input remains unchanged, and any report destination was chosen deliberately.