opx-probe

Fast media file inspector — container, codec, frame rate, MXF sidecar, preflight
Available
v0.2.0 · 28 Jul 2026

opx-probe reads media files directly via libavformat — no shell-out to ffprobe, no subprocess overhead. It returns container duration, video codec and frame rate, audio configuration, fields from an XML sidecar beside an MXF, and whether any stream starts at a non-zero time, which it reports as an edit list. MPEG-TS has no edit lists, yet all 9 .ts files we tried on 27 Sep 2026 tripped it, as did the Matroska and FLV files we tried on 29 Sep 2026. Run preflight against a target format (--house) to check a file before ingest. JSON output for scripting and pipeline integration.

  • Container and stream inspection — H.264, MPEG-2, ProRes, DNxHD
  • MXF with an XML sidecar, found by file name — programme title and audio track layout; AFD, subtitles and rights expiry only under field names AS-11 does not use (see known issues)
  • Preflight against a target format — frame rate, audio sample rate, stream start offset (reported as an edit list), VFR; resolution and scan type are not checked
  • JSON output for scripting and pipeline integration
  • Exit codes: 0 = clean, 1 = preflight fail, 2 = probe error
  • No installation — single binary, requires FFmpeg libraries
usage examples
# Inspect a file
$ opx-probe programme.mxf

# Preflight against a target format
$ opx-probe clip.mp4 --house 1080p50

# JSON output for scripting
$ opx-probe clip.mp4 --json | jq .video.frame_rate_label

# Target formats (--house): 1080p50, 1080p25, 1080p2997, 1080p30,
# 1080p24, 1080p2398, 1080i50, 1080i5994,
# 720p50, 720p25
# Resolution and scan type are not compared: 1080p50 and 720p50 give
# the same verdict, as do 1080p25, 1080i50 and 720p25 (opx-probe 0.2.0).

Download opx-probe v0.2.0

Linux: requires FFmpeg 6.x shared libraries (libavformat.so.60). Ubuntu 24.04 LTS only: sudo apt install ffmpeg. 22.04 ships FFmpeg 4.4 and 26.04 ships FFmpeg 8 (libavformat.so.62) — neither is supported; other distributions need FFmpeg 6.x from their own sources.

Windows: the Windows zip bundled FFmpeg 6.1.1 DLLs (gyan.dev full_build-shared), licensed GPL version 3 or later. It did not include that licence’s text or an offer of the FFmpeg source, which the licence requires. The Linux builds do not bundle FFmpeg. Windows downloads withdrawn 29 Sep 2026 for this reason.

Source code is not published. One exception, stated so nobody has to find it: from 16 Apr to 28 Jul 2026 the opx-probe repository carried one source file of the command-line front-end, committed by mistake under .github/workflows/. It was removed from the tree on 28 Jul 2026. It remains in the repository’s history and in the “Source code” archive of the v0.1.0 release. Stated 29 Sep 2026. All releases on GitHub →

Known issues in opx-probe 0.2.0

Added 29 Sep 2026 · they apply to the published 0.2.0 binary
  • A false “will reject” line. The line Rytmi v1 will reject this file is wrong: Rytmi does not reject such a file. The line prints whenever any stream starts at a non-zero time: every MPEG-TS file we tried, and the Matroska and FLV files we tried on 29 Sep 2026, including a fresh MKV encode, which --house also fails.
  • Several files: only the last is probed. Given several files, 0.2.0 probes only the last and ignores the others without a message, so opx-probe *.mxf --house 1080i50 can print PASSED and exit 0 over files it never opened. Pass one file per run: for f in *.mxf; do opx-probe "$f" --house 1080i50 || echo "FAIL $f"; done.
  • VFR. VFR is flagged only when FFmpeg reports no frame rate at all. A variable-rate file that declares a nominal rate, such as a typical phone or screen capture or a stream whose rate changes part-way, passes preflight.
  • Truncated files. Preflight reads the container header, not the media. A truncated file whose header survives passes: on 29 Sep 2026 the first 23 % of a faststart MP4 reported its full 10 s duration and PASSED.
  • Edit lists. The start-offset check does not read MP4/MOV edit lists. A stream-copy trim that carries a real edit list passes, reports has_edit_list: false, and counts the frames its edit list discards.
  • MXF sidecar. The sidecar is found by file name only: <name>.xml, <name>_shim.xml, or a shim.xml in the same folder, so one shim.xml is reported against every MXF beside it. Any well-formed XML counts as a sidecar. AFD, subtitles and rights expiry are read from field names that are not AS-11’s, and a missing subtitles field reads as false. AS-11 metadata embedded in the MXF is not read.
  • Exit code 101. opx-probe ends in a Rust panic with exit code 101, outside the documented 0/1/2, when a file name is not valid UTF-8, and intermittently when stdout is closed early (| head).
  • Publisher name. --help names a limited company that is not the publisher, and the archive’s README.txt runs the trading name together as one word. The publisher is Bear Media Services LTD, trading as Karhu TV. The --help text is fixed in source; the published archive is unchanged.
  • Supported systems. The README.txt inside the Linux archive says “Ubuntu 24.04+”. Of Ubuntu releases, only 24.04 LTS is supported, as this page states.

opx-loudness

EBU R128 loudness analysis — integrated, short-term, momentary, true peak
Designed; not built
Designed to check EBU R128 and Free TV OP-59, with the thresholds read from the issuing bodies’ own documents rather than a summary, and to say INCONCLUSIVE where it can’t honestly say pass. The BS.1770 loudness meter exists in Rytmi’s codebase; this tool does not.

opx-drift

Media timeline drift — PTS deviation and audio/video differential, EBU R37 quoted
Available
v0.2.2 · 12 Aug 2026

Does this file’s presentation timeline hold together? Two questions, two modes. file measures PTS deviation against the stream’s own declared rate. sync measures the audio-versus-video differential and quotes it against EBU R37. The frame period is resolved as an exact rational and never floated, so rounding the period adds no error. Each track in a differential is measured against its own declaration, so the common-mode term subtracts out.

  • PTS drift against an exact rational timeline — steps of ±1 period are dropped or repeated frames
  • Audio/video differential with EBU R37 (+40 / −60 ms) — asymmetric, so the sign selects the bound
  • Two files — their video timelines compared against each other
  • Quantisation floor printed with every report; a slope inside it is labelled quantisation-limited
  • JSON output for scripting and pipeline integration
  • Exit codes: 0 = no discontinuities, 1 = discontinuities detected (in sync, also an R37 breach inside the file), 2 = error, too little data, or a VFR stream
usage examples
# Lip-sync DRIFT (not a constant offset), with EBU R37 bounds
$ opx-drift sync programme.mxf

# PTS drift of a recorded stream
$ opx-drift file capture.ts

# Analyse a 30 fps file as though it were 29.97
$ opx-drift file capture.mp4 --rate 30000/1001

# The differential is the finding, not the slope
# opx-drift 0.2.2 on bars_h264_1080p25_stereo_10s.mp4, captured 2026-09-06
no significant differential · differential +0.000 ppm (+ = audio ahead) · guard 14.836 ppm (3× the 4.945 ppm slope floor)

Download opx-drift v0.2.2

Linux: requires FFmpeg 6.x shared libraries (libavformat.so.60). Ubuntu 24.04 LTS only: sudo apt install ffmpeg. 22.04 ships FFmpeg 4.4 and 26.04 ships FFmpeg 8 (libavformat.so.62) — neither is supported; other distributions need FFmpeg 6.x from their own sources.

Windows: the Windows zips (0.2.1 and 0.2.2) bundled FFmpeg 6.1.1 DLLs (gyan.dev full_build-shared), licensed GPL version 3 or later. They did not include that licence’s text or an offer of the FFmpeg source, which the licence requires. The Linux builds do not bundle FFmpeg. Windows downloads withdrawn 29 Sep 2026 for this reason.

Read the note under a sync report before quoting a number. A common-mode slope is a coherent retime, not a sync fault.

Source code is not published. All releases on GitHub →

Known issues in opx-drift 0.2.2

Added 29 Sep 2026 · they apply to the published 0.2.2 binary
  • sync measures drift, not a constant offset. Drift means a change in A/V alignment across the file. Each track is anchored at its own first packet, so a file whose audio is late by a fixed amount from the first frame reports no differential and exits 0. On 29 Sep 2026 a copy of our bars file with its audio 178 ms late passed. opx-probe --house flags such a file as a non-zero stream start (reported as an edit list).
  • Dropped frames mid-file. When dropped or repeated frames sit near the middle of a file, or are spread through it, the slope estimate absorbs them. The report then shows a slope the file does not have (roughly drops ÷ frames) and, on MPEG-TS and on some MP4s (25 fps in our tests), lists nearly every frame as a sub-period step. The ±1-period steps are still listed and the exit code is still 1. In sync the same slope appears as an A/V differential and can be reported as an EBU R37 crossing. On 29 Sep 2026 one dropped frame at the midpoint of a 500-frame 50p TS read +2066 ppm and 499 steps.
  • AAC in MKV or FLV. sync reports a false audio drift of about 1.6 %, and an EBU R37 breach, on AAC audio in Matroska (MKV) or FLV, because those containers round each AAC packet’s duration to the millisecond. A lossless remux of a clean MP4 failed this way on 29 Sep 2026. In the same tests AAC in MP4, MOV and TS read clean, as did PCM audio in MXF and Opus audio in WebM.
  • VFR. VFR is recognised only when FFmpeg reports no frame rate. A variable-rate file that declares a nominal rate is analysed at that rate: file reports steps and exits 1, not 2, and sync can report a false R37 breach.
  • Truncated files. A truncated file is analysed as far as it goes and can read clean; the report does not say the file ended early.
  • --audio-stream. An index that is out of range or not audio falls back to video only, reports “no audio stream in this file”, and exits 0.
  • Exit code 101. opx-drift ends in a Rust panic with exit code 101, outside the documented 0/1/2, when a file name is not valid UTF-8, and when stdout is closed before the report is written (for example | head on a long report).
  • Publisher name. --help names a limited company that is not the publisher, and the archive’s README.txt runs the trading name together as one word. The publisher is Bear Media Services LTD, trading as Karhu TV. Both are fixed in source; the published archives are unchanged.
  • Supported systems. The README.txt inside the Linux archive says sudo apt install ffmpeg (Ubuntu/Debian). No current Debian release ships FFmpeg 6; of Ubuntu releases, only 24.04 LTS is supported.

opx-verify

As-run log verifier — hash-chain validation across day files and restarts
In progress
Verifies a hash-chained as-run archive across day-file boundaries and restarts. A single file can’t check what it continues. What checking the log proves, and what it does not, is on the as-run page.