FileLister

Reading media metadata without the command line

The standard answer to what is this file is a command, and it is a good answer for one file. The question people actually have is almost never about one file.

The standard answer to “what is this file?” is a command. ffprobe if you have FFmpeg, mediainfo if you prefer that one. Both are excellent, both are free, and both answer the question for one file at a time.

That is usually where the problem starts, because the question people actually have is rarely about one file.

What a header can tell you cheaply

A media container keeps an index describing its own contents, and reading it is fast — single-digit milliseconds, because it means reading a few kilobytes rather than the file. Everything below comes from there:

  • Codec and its variant, resolution, frame rate, bit rate, bit depth
  • Colour primaries, transfer characteristics, matrix coefficients
  • Duration, and the track structure — how many video, audio and timecode tracks
  • Per-track audio: channels, sample rate, codec, language
  • Start timecode, from the timecode track
  • Camera and lens data for stills, from EXIF

These are the fields most delivery specs are made of, and the fact that they are cheap to read is what makes checking a whole folder practical rather than an overnight job.

What a header cannot tell you at all

Two things that specs routinely require are not written in any container, because they are properties of the content rather than declarations about it.

Loudness. There is no field for it. Integrated loudness has to be computed by K-weighting every audio sample, gating the result and averaging what survives. True peak needs the signal reconstructed at 4× oversampling to find the peaks that fall between samples. Both mean decoding the audio in full.

Key-frame interval. The codec name hints at it — ProRes is intra-only by construction — but for anything that can be either, the answer is in the sample table, and finding the longest run between key frames means walking that index frame by frame.

A third, less often specified but worth knowing: nothing in a header tells you whether the picture is correct. Flags describe intent, and a file can be flagged PQ and contain SDR material.

This is the honest division. A header read is a claim the file makes about itself. A measurement is what the file actually is. Most checks want the first; the two or three that matter most want the second.

Why the command line stops scaling

Nothing wrong with ffprobe. The friction is in what surrounds it.

Run it on one file and you get a wall of output containing the four fields you wanted. Run it on thirty and you are writing a loop, choosing -print_format json, deciding which entries to select, piping through jq, and assembling something a colleague can read. That is an hour of scripting for a job you have once.

Then the requirements change, because they always do — add loudness, add the audio track breakdown, add a column somebody wants in the middle rather than at the end — and the script grows into something with its own maintenance cost. There is a real crossover point where a shell pipeline is the wrong shape for the problem, and most people meet it around the second or third time they need the same answer.

The other half of it is that the output is not the deliverable. What gets sent to a supplier is a list of files with reasons, or a spreadsheet somebody can filter. Getting from JSON to that is the part the loop does not do.

Doing it as a table instead

The alternative shape is to read the metadata once for every file in a folder, put it in columns, and treat it as data rather than as output.

That changes what is easy. Sorting a delivery folder by codec surfaces the odd one out immediately. Sorting by loudness finds the mix that came from a different session. Filtering to everything under thirty seconds answers a question that would otherwise be a script. None of these are clever operations; they are just what a table is for, and they are unavailable when the data is a stream of text.

FileLister reads the header fields during a scan and keeps them as sortable columns — codec, frame rate, dimensions, bit rate, colour flags, track layout, timecode, EXIF for stills. The two expensive measurements are separate commands run over a selection, because both read the whole file and neither belongs in an ordinary scan.

Export goes to CSV, TSV, Excel, JSON, XML, HTML, PDF, Markdown, property list or plain text, in the column order you arranged, which covers both the spreadsheet a colleague wants and the JSON a script wants.

Where each approach belongs

This is not an argument that one replaces the other.

Reach for the command line when you are inspecting one file in depth, need a field nothing else exposes, are working over SSH, or are building something that runs unattended on a server. ffprobe exposes essentially everything, which is exactly what you want when the question is unusual.

Reach for a table when the question spans a folder, when the output is going to a person, when you need to compare files against each other, or when the same check recurs. Comparison is the strongest case: finding the outlier in thirty files is a sorting problem, and sorting is what a spreadsheet does and a terminal does not.

For anything recurring there is a third option worth naming: FileLister exposes its scans and exports to Shortcuts, so a nightly check on an incoming folder can be automated without a shell script and without leaving the Mac.

The check nobody regrets

Whichever tool, the pattern that saves the most time is the same: read the fields for everything in the folder before anyone looks at individual files, and let the odd values point you at which files to open.

Most delivery problems are not subtle once the numbers are side by side. They are one file at the wrong frame rate, one missing its timecode track, one nine decibels off target. All three are invisible while you are opening files one at a time, and obvious the moment thirty rows are in front of you.

Keep reading