Automated release: version and notes generated from pull requests merged since 1.16.1.
1.17.0 — throughput, plus the caption-size half of the eval-17 finding. The release
workflow turns this heading into the version number.
Added
caption.py --fit-size auto|on|off,--min-size N,--fit-size-scope file|cue. The caption
size is fitted to the cue before the cue is split. At a platform caption size (24 ASS units,
about six em per line at 1080x1920) an ordinary sentence needs four lines, so--max-lines 2
cut it into consecutive cues and half of it arrived late — the size, not the breaker, was what
did not fit.--min-sizedefaults toass_units(0.045) = 13, the 4.5 %-of-frame-height
legibility floor, one floor for every destination. New keys inside the existingcaptionblock:
fit_size,size_requested,size_used,size_floor,size_pct_height,shrunk,
fit_scope,fit_exhausted. The caption text is never rewritten, shortened or paraphrased to
make it fit; below the floor the cue is split exactly as before andfit_exhaustedsays so.scenes.py --beats,--beat-step,--beat-range,--min-confidence. The measured beat
grid — onset flux, median+MAD peak picking, an autocorrelation tempo with octave
disambiguation, and a confidence that is half how far the winning lag stands above the others
and half the fraction of onsets that land on the grid. New keysbeatsandbeat_grid. With
--beatsthe file is decoded once and both envelopes come from that pass.cut.py --snap beats,--snap-tolerance,--snap-source,--min-confidence. In/out points
move to the nearest measured beat before the keyframe decision. Below the confidence threshold
the run refuses and names the measured number and--snap none: a cut point may move to a
measured grid point and may not appear from one. New keysnap.render.pyforwards a
project's"snap": {"to": "beats", ...}and reports what came back.silence.py --fillerand its family (--filler-lang,--filler-words,--filler-extra,
--filler-keep,--filler-pad,--words,--transcribe,--filler-list,--max-cuts).
Filler words are removed through the existingkeep_ranges()/aselectgraph — and only where a
speech engine measured a start/end pair for the word. Built-in lists for en, ja, es, de, fr, pt
and it;like,tipoandcioèare deliberately not in them (discourse markers are not
disfluencies) and are reachable with--filler-extra. New keysfillerand
removed_seconds_total(silence plus filler);removed_secondsis unchanged and still holds
the silence-only figure. Whisper stays optional for this tool
exactly as it is forcaption.py.--transcribedrives whichever engine is installed with
its own word-timestamp option (whisper.cpp--output-json-full, faster-whisper
word_timestamps=True, openai-whisper--word_timestamps True); an engine whose build
produces none refuses by name rather than reporting an empty removal as a success.batch.py --jobs N|auto. Parallel items under one shared--timeoutbudget, capped at
min(N, cpu_count, 8)with the applied value reported. The per-item table keeps its shape and
its order, and each item's log is flushed in file order. New keysjobs,jobs_requested,
wall_seconds,item_seconds_total,timed_out.render.py --cache DIRand--from STAGE. An opt-in stage cache keyed on the stage, its
arguments, its inputs' content hashes, the flags render forwards to its children (--fast,
--codec, …), the output's extension and the ffmpeg build banner plus the skill and contract
versions, so a cache is never reused across any of them. New keycache. There is no default cache directory.
Changed
caption.pynow fits the caption size to the cue before splitting it when the size was not
stated (--fit-size auto, the default). A run that passed--sizeexplicitly, or that took a
size from abrand.json, is unchanged;--fit-size offrestores 1.16.1 byte-for-byte (a pinned
ASS fixture asserts it). This changes the rendered ASS for platform caption runs that took the
default size — the defect eval 17 measured.- The optional local speech-to-text bridge and the SRT reader/writer moved from
caption.pyinto
scripts/_common/asr.pyand are re-exported through the_commonfacade, sosilence.py --filler --transcribeshares one engine probe and one "no engine found" message.
caption.parse_srt,caption.transcribeandcaption.whisper_word_timingsare unchanged as
names;caption.py --helpis byte-identical.
Fixed
render.pyleft its auto-named work directory behind after a failed render: a function-local
import shutilshadowed the module-level one and theatexitcleanup raisedNameError.
(Introduced by this release's own--cachework; 1.16.1 never had it.)- feat: 1.17.0 — throughput (caption size that fits the cue, beat-synced cuts, filler-word removal, batch --jobs, render --cache) (#235)
What's Changed
- feat: 1.17.0 — throughput (caption size that fits the cue, beat-synced cuts, filler-word removal, batch --jobs, render --cache) by @claude[bot] in #235
Full Changelog: v1.16.1...v1.17.0