ui.py — graphical front-end
Queue several videos and run them one after another. Each job shells out to
lektor_ai_comfy.py with ordinary command-line arguments, so the terminal
script stays the single source of truth and remains usable on its own.
Videos chosen together in one multi-select form a linked set whose settings
move together; blocks added with + stay independent. Subtitles are found
beside the video automatically, picked manually, or chosen from the video's
embedded tracks. REGENERATE / RESUME / RE-BUILD map to --regen,
--resume-from and --rebuild; RESUME pre-fills the last clip on disk, since an
interrupted run can leave that one half-written. A Settings dialog edits
settings.ini in place, rewriting only the value lines so the file's comments
survive — configparser would have dropped all 29 of them. Closing asks first,
and names the queued jobs that would be discarded.
tkinter, so no new dependencies. It needs a Tk with real fonts: the system
one after `apt install python3-tk`. Under miniforge's Python it still runs but
falls back to X11 bitmap fonts, which the UI detects and reports.
Reading the child's pipe deliberately avoids text=True. Text mode enables
universal newlines, which rewrites a lone carriage return as a newline — so
ffmpeg's progress bars redrew as a new line per update instead of animating.
Wheel events are bound per widget rather than with bind_all, so scrolling
stops at a widget's limit instead of spilling into whatever is behind it, and
can no longer change a dropdown's value in passing.
start_lektor_ui.sh
Picks a Python that has tkinter, preferring the system one for its fonts.
Runaway clip padding
When the model fails to emit a stop token it generates until --max-tokens is
exhausted: a two-second line becomes a 136s clip. Placement uses a
push-forward cursor, so that padding delayed every clip after it — measured
on one film, 1807 of 2075 clips were pushed late, the worst by 981 seconds,
which is why the voiceover fell silent over later dialogue.
Clips are now trimmed before they are saved. Two padding modes occur and both
are handled: digital silence, found with silencedetect; and a steady tone that
sits above any sane silence threshold, found by its flatness instead — tone
tails spread 3-5 dB across their windows where speech spreads 43-61 dB.
--trim-silence repairs jobs generated before this, in place and without
regenerating anything. Applied to the six existing jobs it removed 77 clips'
worth of padding, about 1h55m, leaving every job within a few seconds of its
subtitle timing.
--embedded-sub-index
Selects an embedded subtitle track by ffmpeg stream index instead of
prompting, for the UI and for scripted runs. Interactive behaviour is
unchanged when it is omitted.
settings.ini — voice gudowski_short_3, temperature 0.6.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>