From 7312fa2366c60fb230cc471e161a4bb824ee4245 Mon Sep 17 00:00:00 2001 From: jenstandstad Date: Sat, 25 Jul 2026 12:21:51 +0200 Subject: [PATCH] Adding fix to the word position that the logo begins --- gnommo/transformer.py | 44 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/gnommo/transformer.py b/gnommo/transformer.py index 4001772..e2788a5 100644 --- a/gnommo/transformer.py +++ b/gnommo/transformer.py @@ -412,6 +412,40 @@ def _find_phrase_timestamp( return -1, -1.0, 0.0, -1 +# Pause-variant video marker prefixes (e.g. [vftp:logo]). These freeze the +# narration when they fire, so their start must land in the gap BETWEEN words, +# never mid-word — otherwise the narration cuts out half-way through a word and +# finishes it when the video ends. +_PAUSE_MARKER_PREFIXES = ( + "vftp:", "vfbp:", "vfmp:", + "vf2tp:", "vf2bp:", "vf2mp:", + "vstp:", "vsbp:", "vsmp:", +) + + +def _snap_to_word_gap(t: float, transcription: list) -> float: + """Snap a time to the midpoint of the gap between transcript words. + + - t inside a word → midpoint of the gap AFTER that word (the word finishes, + then the pause begins), or the word's end if it's the last word. + - t already in a gap → midpoint of that gap. + - t before the first / after the last word → unchanged. + """ + if not transcription: + return t + n = len(transcription) + for i, w in enumerate(transcription): + if w.start <= t <= w.end: + nxt = transcription[i + 1] if i + 1 < n else None + return round((w.end + nxt.start) / 2, 3) if nxt else round(w.end, 3) + if w.start > t: + if i == 0: + return t + prev = transcription[i - 1] + return round((prev.end + w.start) / 2, 3) + return t + + def align_markers_to_transcription( manuscript_text: str, transcription: list[TranscribedWord], @@ -623,6 +657,16 @@ def align_markers_to_transcription( confidence=timing.confidence, ) + # Snap pause-narration video markers off any word they land inside, to the + # midpoint of the gap after it — so the freeze happens between words, not + # mid-word. Flows into both the render plan and events.json. + if transcription: + for timing in deduped: + if timing.timestamp >= 0 and timing.marker_id.startswith( + _PAUSE_MARKER_PREFIXES + ): + timing.timestamp = _snap_to_word_gap(timing.timestamp, transcription) + return deduped