Skip to content

sfhub split transcript-clean gap-tightening clips held pauses and corrupts the following word onset

Context

sfhub split's default --gap-max 0.55 tightens any silence gap longer than 550ms down to --gap-keep 0.22. This is correct for disfluency gaps but destructive for deliberately held pauses in a performed read.

The failure

A CTA ending "follow ... for more" had a 1.2s intentional dramatic pause between "follow" and "for". Default gap-tightening compressed it to 0.22s, clipping the onset of "for" and merging the tail of "follow" with it. Deepgram Nova-3 re-transcription of the rendered select read "All for more" instead of "Follow for more" — the corruption was invisible in the cut list and only surfaced in ASR verification of the rendered output.

The fix

Pass --gap-max above the pause length on a per-cut basis:

sfhub split --src <stem> --start S --end E --gap-max 1.25 --speed 1.15

The gap-max value must exceed the longest intentional pause in that segment. 1.25 preserved the 1.2s pause; the re-rendered select re-transcribed as "Follow for more" correctly.

Detection rule

Always re-transcribe the rendered select (not the source) and diff against the source transcript. A one-word discrepancy at a gap boundary is the tell. volumedetect at the gap confirms speech vs silence:

ffmpeg -hide_banner -ss <gap_start> -t 0.10 -i <select>.mp4 -vn -af volumedetect -f null -

Room tone reads ~-50 dB; speech reads ~-25 dB. If the gap measures as silence and the word changed, the tightening ate the onset.

No signals yet