opx-* suite
Free broadcast
engineering tools.
Binary-only releases for Linux. No account required. No licence key. No telemetry, no update check — the tools phone nowhere. (A URL given as the file argument is opened by FFmpeg, as in any FFmpeg tool.) Built on the same codebase as our commercial products. The two released tools list their known issues below, dated, and say why we withdrew their Windows builds on 29 Sep 2026.
opx-probe
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
$ 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
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
- A false “will reject” line. The line
Rytmi v1 will reject this fileis 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--housealso 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 1080i50can 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 ashim.xmlin the same folder, so oneshim.xmlis 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.
--helpnames 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--helptext 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
opx-drift
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
$ 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
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
syncmeasures 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 --houseflags 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
syncthe 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.
syncreports 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:
filereports steps and exits 1, not 2, andsynccan 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
| headon a long report). - Publisher name.
--helpnames 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.