Snacks v2.15.1
Automated Media Library Transcoder
A point release built around the verify-failure fix that shipped in v2.15.0. That release stopped healthy open-GOP HEVC files from being falsely reported as VERIFY FAILED — a benign muxer-timestamp complaint during decode sampling was being counted as a defect — but any library scanned before the fix still carries those stale flags in its database, with no way to clear them short of deleting the files. This release adds that missing cleanup: a bulk Reset Verify Failures action and a per-row reset on the Library Health page, both of which clear a file's stored verify state without touching disk and move it to the front of the rolling-verification rotation, so the corrected verifier re-adjudicates it soon and any genuinely-broken file re-surfaces on its own. It also fixes a related bug where the manual Verify button ran the decode-sample check and showed a fresh result but never wrote it back — so a file that now decodes cleanly stayed stuck on the failed list. Rounding it out is a new end-to-end ffmpeg integration test that encodes a real open-GOP HEVC clip and proves the whole verify path passes healthy files while still flagging genuinely-damaged ones.
Clearing stale verify-failure flags
Manual "Verify" now persists its result
The per-row Verify button ran the decode-sample check and displayed the outcome, but never wrote it back — so a file that v2.15.0's fix now decodes cleanly showed a green result yet stayed stuck on the failed-verification list until the rolling verifier happened to re-check it later.
LibraryController.VerifyManual— after runningFileHealthService.VerifyAsync, now persists the fresh outcome viaMediaFileRepository.SetVerifyResultAsync(the same format the rolling verifier stores): a pass clears the file from the failed queue, a fail refreshes its summary. The stored summary is"ok"on success or the first five issues joined, capped at 2000 characters.
Bulk "Reset Verify Failures"
A one-click way to re-adjudicate a whole library's worth of stale flags without deleting anything — the safe counterpart to the existing Delete All.
POST /api/library/health/reset-verify→LibraryController.ResetVerifyFlagged→MediaFileRepository.ResetVerifyForHealthAsync(all new) — clears the stored deep-verification state (result and timestamp) on every file matching the active health category + search. A file with no stored result drops off the failed-verification list immediately, and its nulled verify timestamp sorts it to the front of the rolling-verification rotation (GetVerificationCandidatesAsyncorders nulls first), so the corrected verifier re-checks it soon rather than months later. Only rows that actually carry a stored result are touched; nothing is deleted from disk.- UI — a Reset Verify Failures button in the Library Health card header. It always acts on the whole verify-failed set (a search term still narrows it) regardless of the active tab, and is shown only on the All tab (so it's discoverable) and the Verify-failed tab (its natural home) when there are failures to clear — hidden on unrelated tabs (no-audio, etc.) where it would only confuse. Its confirmation modal spells out that nothing is deleted, that files are marked unverified and moved to the front of the queue, and that rolling verification must be enabled in Settings for them to be re-checked.
Per-file reset
POST /api/library/health/reset-verify-file→LibraryController.ResetVerifyFile→MediaFileRepository.ResetVerifyForPathAsync(all new) — clears the failed-verification flag on a single file by path. It's DB-only (it just nulls the stored verify state), so unlike delete it needs no on-disk path check, and it returnsfalsewhen no row matched the path.- UI — a per-row rotate-left button on the health table, shown only when that row actually carries a non-
okverify result.
Health card header layout
Views/LibraryHealth/Index.cshtml— the card header was reworked so the title, coverage line, and search box are left-anchored (stable) and the action buttons are pushed to the far right withms-auto, so toggling the buttons — or their count labels changing — no longer shifts the search box.
Tests
Snacks.Tests/Pipeline/FileHealthVerifyIntegrationTests.cs(new) — end-to-end coverage ofFileHealthService.VerifyAsyncon real files, complementingFileHealthVerifyTests(which covers the noise-filter string logic). It encodes a ~40s open-GOP HEVC clip with an AAC track (past the verifier's 32s multi-sample threshold), then asserts the decode-sample verifier passes the healthy clip and flags two genuinely-damaged variants: mid-file bit-rot — deterministic garbage over ~48–78% of the file, wide enough to overlap both the middle and near-end sample windows and clear of the trailingmoovatom so the container still probes — surfaces real decoder errors (never the filtered muxer-DTS noise), and a container truncated to 35% is unreadable.FfmpegFactAttribute(new) — skips the integration test at discovery time unless ffmpeg and ffprobe with the libx265 encoder are launchable on PATH (honouringFFMPEG_PATH/FFPROBE_PATH), so minimal CI images without ffmpeg stay green.
Files Changed
Manual verify-failure reset
Snacks/Controllers/LibraryController.cs—VerifyManualpersists the fresh result;ResetVerifyFlagged(health/reset-verify) andResetVerifyFile(health/reset-verify-file) endpoints (new)Snacks/Data/MediaFileRepository.cs—ResetVerifyForHealthAsync/ResetVerifyForPathAsync(new)Snacks/Views/LibraryHealth/Index.cshtml— Reset Verify Failures button; right-anchored header layout so actions don't shift the search boxSnacks/wwwroot/js/api.js—resetVerifyFlagged/resetVerifyFileclient methodsSnacks/wwwroot/js/health/library-health.js— whole-library verify-failed count, bulk + per-row reset handlers and confirmation modals, per-row reset button, click routing
Tests
Snacks.Tests/Pipeline/FileHealthVerifyIntegrationTests.cs— new ffmpeg-backed end-to-end verify test +FfmpegFactAttributeskip gate
Version bumps
Snacks/Controllers/HomeController.cs— health endpoint versionSnacks/Services/ClusterDiscoveryService.cs—ClusterVersionprotocol bump to 2.15.1Snacks/Views/Shared/_Layout.cshtml— footer versionREADME.md— version badge and footerbuild-and-export.bat— Docker tag versionelectron-app/package.json/package-lock.json— version
Full documentation: README.md