Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit 3da6cc254d868f17c66df2363a6f540290a6070b
parent ee8e96e668c1fb2818988dc71516d39dd816aa99
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Sat, 19 Sep 2026 01:38:37 -0400

clip bench: play the cached file that holds THIS clip's window, not the widest for the video

out/clips-raw is keyed by VIDEO, and a report cites the same stream more than
once -- ElfpireEva cites 07ZaDnyzO1g four times -- so the directory holds one
file per clip and "the widest file for this video" is another clip's file as
often as not. The bench plays windows[0] and seeks `start - from` into it: for
a01's 44-second file and f01's window that is 1146 s past the end, so the
player showed nothing, or the wrong seconds, on every clip after the first.

windowsFor() now filters to files that actually overlap the clip's own
[start,end] and sorts containing first, then by overlap, then by width, with
build-video's own 0.02 s tolerance. A clip whose material is not cached gets an
empty list -- "nothing fetched for this clip yet", which is true -- instead of
somebody else's window. A caller with no window (the raw route's ledger-claim
path, which asks for a VIDEO's files) still gets every file, widest first.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Diffstat:
Mumtool/lib/report/serve.mjs | 25+++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/umtool/lib/report/serve.mjs b/umtool/lib/report/serve.mjs @@ -23,18 +23,39 @@ export async function resolveClip(projectId, clipId) { return { project, manifest, clip }; } +/** build-video's own tolerance for "this file holds that window". */ +const WIN_EPS = 0.02; + /** - * The cached source windows for a clip, widest first. + * The cached source windows for a clip: the ones that hold ITS window, widest + * first, then any that merely overlap it. * * The bench wants the WIDEST containing file, because that is how much room * there is to drag before anything has to be fetched. The BUILD wants the * tightest, because it decodes the whole file to find a silence. They are * different questions and both are asked here. + * + * "Containing" is not optional. clips-raw is keyed by VIDEO, and a report + * cites the same stream more than once -- ElfpireEva cites one video four + * times -- so the directory holds a file per clip and "widest for this video" + * is another clip's file as often as not. The bench then seeks `start - from` + * into a 44-second file, i.e. 1146 s past its end, and plays nothing or the + * wrong seconds. A caller with no window (a ledger claim asking for the raw + * files of its video) still gets every file, widest first. */ export async function windowsFor(project, clip) { const rawDir = path.join(project.dir, "out", "clips-raw"); const all = await cachedWindowsFor(rawDir, clip.video); - return all.sort((a, b) => b.to - b.from - (a.to - a.from)); + const width = (w) => w.to - w.from; + const { start, end } = clip; + if (!Number.isFinite(start) || !Number.isFinite(end)) { + return all.sort((a, b) => width(b) - width(a)); + } + const overlap = (w) => Math.max(0, Math.min(w.to, end) - Math.max(w.from, start)); + const contains = (w) => (w.from <= start + WIN_EPS && w.to >= end - WIN_EPS ? 1 : 0); + return all + .filter((w) => overlap(w) > 0) + .sort((a, b) => contains(b) - contains(a) || overlap(b) - overlap(a) || width(b) - width(a)); } export function pickWindow(windows, wantedName) {