Archilyzer · Source

archilyzer

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

commit b070be886ce6454d48a9255d8becc1f2d4956615
parent 5c36c9d3ebf17181a79a867237ae648f37ca3a16
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Thu,  1 Oct 2026 13:47:42 -0400

umtool: an export with no chapters.ffmeta reads a deck cut's offsets from its schedule.json, holds included

The segment files alone do not know a clip is held, so the fallback that sums
their lengths is wrong for a cut with posts; the deck's schedule is the cut's
own clock.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mumtool/lib/report/export.mjs | 17++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/umtool/lib/report/export.mjs b/umtool/lib/report/export.mjs @@ -64,7 +64,7 @@ const titleOf = (e, i) => e.chapter ?? (e.type === "clip" ? `${i + 1}. ${e.video /** * Deliverable-second offsets for every entry of the chosen variant. - * @returns {Promise<{ starts: number[], source: "ffmeta"|"segments", file: string, note?: string } | { error: string }>} + * @returns {Promise<{ starts: number[], source: "ffmeta"|"schedule"|"segments", file: string, note?: string } | { error: string }>} */ export async function chapterOffsets(dir, manifest, variant) { const entries = manifest.timeline ?? []; @@ -84,6 +84,21 @@ export async function chapterOffsets(dir, manifest, variant) { return { starts: chapters.map((c) => c.start), source: "ffmeta", file }; } + // No ffmeta, but a deck schedule for this cut: its starts are the cut's own, + // holds included -- the segment files alone do not know a clip is held. + const sched = await readFile(path.join(outDir, variant, "schedule.json"), "utf8") + .then((t) => JSON.parse(t), () => null); + if (sched?.kind === "deck" && Array.isArray(sched.segments) && + sched.segments.map((x) => x.id).join("\n") === entries.map((e) => e.id).join("\n")) { + const D = sched.transition ?? 0; + return { + starts: sched.segments.map((x, i) => (i === 0 ? 0 : x.start + D)), + source: "schedule", + file: path.join(outDir, variant, "schedule.json"), + note: "no chapters.ffmeta; offsets from the deck's schedule.json", + }; + } + // No ffmeta: the pipeline's own offset arithmetic over the segments on disk. const segDirs = [path.join(outDir, variant, "segments"), path.join(outDir, "segments")]; for (const segDir of segDirs) {