Add real media-file probing (session 9, sixteenth delivery)

Wires real container-header probing into the Rename panel's Match step, the
first item on the porting roadmap: aurora-curator-core::probe reads actual
resolution, frame rate, duration, and video/audio codecs straight from a
file's own header (mp4 crate for MP4/M4V/MOV, matroska crate for MKV/WebM,
no ffmpeg/MediaInfo dependency), batched through a new probe_media_files
Tauri command. Probed values fill {resolution}/{video codec}/{audio codec}
only when a filename release tag hasn't already, and populate five bindings
with no filename-tag equivalent at all: {width}, {height}, {fps},
{duration}, {file size}. 8 new Rust unit tests against real ffmpeg-generated
fixture files (161 -> 169 total), verified end to end with a 15-check
Playwright script against npm run dev, and README updated (status
paragraph, project layout, a new "Real media-file probing" section, and
roadmap item 1 narrowed to what's still missing).
This commit is contained in:
Renamr Scaffold
2026-08-29 18:07:54 +00:00
parent 03768c398d
commit 1291ae086d
12 changed files with 614 additions and 26 deletions
+74 -16
View File
@@ -30,9 +30,13 @@ TV episodes and movies
text straight out of the filename — resolution, source (BluRay/HDTV/WEB-DL/…),
video/audio codec, release group — so naming schemes can reference
`{resolution}`/`{source}`/`{video codec}`/`{audio codec}`/`{release group}` (or
FileBot's own `{vf}`/`{source}`/`{vc}`/`{ac}`/`{group}`) without a media prober; the
rest of FileBot's full media-metadata bindings (real probed video/audio stream info)
are not yet ported. The Align Up/Down buttons reorder the (shared) file list — the two
FileBot's own `{vf}`/`{source}`/`{vc}`/`{ac}`/`{group}`), and now also probes each
file's own container header for its real resolution, frame rate, duration, and
codecs — no ffmpeg/MediaInfo dependency required — filling in `{resolution}`/
`{video codec}`/`{audio codec}` whenever the filename itself didn't already carry
that tag, plus `{width}`/`{height}`/`{fps}`/`{duration}`/`{file size}`, which have no
filename-tag equivalent at all; see "Real media-file probing" below. The Align
Up/Down buttons reorder the (shared) file list — the two
panes always stay positionally paired — and up to 9 naming schemes can be saved as
presets, recalled with a click or a `1`-`9` keypress (persisted locally, same pattern as
Settings/History). The app can also be driven entirely from the command line —
@@ -57,7 +61,10 @@ user-editable naming-scheme-style expression per loaded file (the same `{ }` syn
matching "Match"/Filter use), with a live "N of M lines rendered" count, a Copy List
clipboard export, and an Export to File… button that writes the whole list to a `.txt`
file via a native Save dialog — this closes out the full original panel set (Rename/
Episodes/Subtitles/SFV/Filter/List); see "List" below. See "Porting roadmap" below.
Episodes/Subtitles/SFV/Filter/List); see "List" below. Real media-file probing (real
resolution, frame rate, duration, and codecs read straight from a video file's own
container header, not guessed from its filename) is wired into the Rename panel's
"Match" step — see "Real media-file probing" below. See "Porting roadmap" below.
The naming scheme is fully user-editable from the app (the "Naming Scheme" button next
to the New Names list) — the default is `{show name} - {season number}x{episode
@@ -188,12 +195,20 @@ crates/aurora-curator-core/ Pure Rust core: naming-expression engine (ported),
into (auto-created) subfolders when
the naming scheme includes `/`), a rename history/undo log
(`history/`, a partial `HistoryDialog` port, undo-aware of which
action produced each batch), and pure `-rename` command-line
action produced each batch), pure `-rename` command-line
argument parsing/file expansion (`cli/` — no Tauri or network
dependency at all, see "Command-line usage" below). Not yet
ported: full media metadata bindings, other web datasource
clients (TheTVDB/AniDB/etc). No Tauri dependency, so
it builds and unit-tests standalone.
dependency at all, see "Command-line usage" below), and real
media-file container probing (`probe/` — real resolution, frame
rate, duration, and codecs read straight from a video file's own
header via two pure-Rust container parsers, the `mp4` crate for
ISO-BMFF containers and the `matroska` crate for EBML/Matroska
containers, no ffmpeg/MediaInfo system dependency; see "Real
media-file probing" below). Not yet ported: other web datasource
clients (TheTVDB/AniDB/etc), and everything MediaBindingBean
derives that neither a filename tag nor `probe/`'s two supported
container families can provide (other containers like .avi/.wmv,
audio-only metadata like bitrate/sample rate). No Tauri
dependency, so it builds and unit-tests standalone.
src-tauri/ Tauri app shell: exposes aurora-curator-core as commands to the frontend
(naming-scheme rendering, filename matching for both TV and
movies, metadata fetch — `metadata.rs` for TV episodes (against
@@ -229,7 +244,11 @@ src-tauri/ Tauri app shell: exposes aurora-curator-core as commands
whatever already-rendered, newline-joined text the frontend hands
it to a `.txt` file — the only new Tauri surface List needed, since
matching each file and rendering its line both reuse existing
commands, see below) — `cli.rs` (the
commands, see below), `probe.rs` (a single `probe_media_files`
command backing real media probing in the Rename panel's Match
step: batch-probes every loaded file's real container header off
the main thread, wrapping `aurora-curator-core::probe` — see "Real
media-file probing" below) — `cli.rs` (the
`-rename` command-line mode's orchestration: builds and executes a
rename plan against `aurora-curator-core::cli`'s parsed arguments,
with no Tauri `App`/window ever created for it — `main.rs` branches
@@ -238,7 +257,9 @@ src-tauri/ Tauri app shell: exposes aurora-curator-core as commands
src/ React + TypeScript UI (Vite). Faithful recreation of the original
two-pane rename screen (Aurora theme) wired to real file loading,
drag-and-drop, live naming-scheme preview, local TV/movie
matching, metadata fetch for both (behind a Fetch Data Settings
matching, real media-file probing (`probe_media_files`, batched
alongside the local matching calls in `RenamePanel.tsx`'s
`runMatching`), metadata fetch for both (behind a Fetch Data Settings
modal holding independent TV-source (TMDB/TVmaze/OMDb) and
movie-source (TMDB/OMDb) pickers plus the TMDB token and OMDb key
inputs), a
@@ -519,6 +540,37 @@ and the results header tracks "N of M lines rendered" live as the expression cha
to File…** opens a native Save dialog (defaulted to `list.txt`) and writes the same text
to disk.
## Real media-file probing
Unlike every panel above, this isn't a new sidebar screen — it's a naming-scheme
binding source wired into the Rename panel's existing "Match" step, closing (part of)
the gap the porting roadmap has called out since the beginning: FileBot's
`MediaBindingBean` doesn't just parse tags out of a release name, it also reads a
video file's own container header for its real resolution, frame rate, duration, and
codecs — a naming scheme can reference those even when the filename itself doesn't
carry a tag for them, or came from a mislabeled/renamed-already release. Aurora
Curator ships no ffmpeg/MediaInfo dependency for this — two pure-Rust container
parsers do the actual reading: the `mp4` crate for ISO-BMFF containers (`.mp4`/`.m4v`/
`.mov`) and the `matroska` crate for EBML/Matroska containers (`.mkv`/`.webm`). Any
other extension, or a file that fails to parse as its container, just yields no probed
values — probing is always a best-effort enrichment layered on top of filename
matching, never a hard requirement, so an unsupported or corrupt file can't break
Match.
Clicking **Match** now also probes every loaded file's real container header
(`probe_media_files`, one batched Tauri round trip off the main thread) alongside the
existing filename-based guessing. The result feeds the same bindings the release-tag
parser already populates — `{resolution}`/`{vf}`, `{video codec}`/`{vc}`,
`{audio codec}`/`{ac}` — but only when the filename itself didn't already carry that
tag; an explicit release-group tag always wins over a probed value, since a release
group's own tag is usually deliberate. Five bindings have no filename-tag equivalent
at all, so they're only ever available this way: `{width}`, `{height}`, `{fps}`,
`{duration}` (`h:mm:ss`, or `m:ss` under an hour), and `{file size}` (human-readable,
e.g. `1.4 GB`) — all formatted once on the Rust side so the UI never reimplements that
logic. The Match status line reports how many loaded files were actually probed
(`"N probed from file"`), and the naming-scheme editor's field-reference list has a
new "Real file probing" group listing all five.
## Porting roadmap (not yet done)
Roughly in priority order — each references the original FileBot source file it's
@@ -526,13 +578,19 @@ ported from, for anyone picking this up:
1. **Full naming-scheme bindings** — `net.filebot.format.MediaBindingBean` (1354 lines):
all the `{n}`, `{s00e00}`, `{airdate}`, `{vf}` (video format), etc. binding
properties. A filename-tag-based subset is now ported and wired to "Match"
properties. A filename-tag-based subset is ported and wired to "Match"
(`guess_release_info` in `crates/aurora-curator-core/src/matching`): `{vf}`/`{resolution}`,
`{source}`, `{vc}`/`{video codec}`, `{ac}`/`{audio codec}`, `{group}`/`{release
group}`. What's still missing is everything MediaBindingBean derives from actually
*probing* the media file (real video/audio stream resolution, duration, bitrate,
frame rate, file size/hash, etc.) — Aurora Curator ships no ffprobe/MediaInfo dependency, so
those bindings only work when a release name happens to carry the info as text.
group}`. Real container probing (`crates/aurora-curator-core/src/probe`, see "Real
media-file probing" below) now covers the other half MediaBindingBean derives from
actually reading the file — real resolution/video codec/audio codec fill in
whenever the filename didn't already carry that tag, plus `{width}`/`{height}`/
`{fps}`/`{duration}`/`{file size}`, which have no filename-tag equivalent at all —
for the two container families it supports (MP4/M4V/MOV and MKV/WebM). Still
missing: probing for other containers (.avi, .wmv, ...), audio-only metadata
(bitrate, sample rate, channel layout), file hashing (`{crc32}` reuses the SFV
panel's own hasher today but isn't wired into naming-scheme bindings yet), and
wiring probed bindings into the List/Filter panels (currently Rename-panel-only).
2. **String/expression helper methods** — `net.filebot.format.ExpressionFormatMethods`
(636 lines): FileBot-specific Groovy string extensions like `.pad()`, `.sortName()`.
Only a small subset (`any`, `all_of`, `concat`) is ported so far