Skip to main content

Align video captions with a transcript timebase

2026-11-11 16:36:37.712539+00:00
Align video captions with a transcript timebase

A transcript timed against a source video needs a new time origin when a clip starts partway through that video. Subtract the clip start and clamp cues to the clip's visible interval. Otherwise a subtitle can appear late, start before zero or remain after the exported clip ends.

Convert one cue

Use the same time unit for source cues and clip boundaries. This synthetic example uses milliseconds, avoiding binary floating-point rounding during the overlap calculation.

def local_cue(start, end, clip_start, clip_end):
    if end <= start or clip_end <= clip_start:
        raise ValueError("Invalid interval")
    left, right = max(start, clip_start), min(end, clip_end)
    return None if left >= right else (left - clip_start, right - clip_start)

assert local_cue(9500, 11200, 10000, 15000) == (0, 1200)
assert local_cue(15000, 16000, 10000, 15000) is None
assert local_cue(14000, 16000, 10000, 15000) == (4000, 5000)

The half-open overlap rule excludes a cue that starts exactly at the clip end. A cue crossing the clip start remains visible from local time zero. Decide separately whether trimming a cue's timing should also trim its text; timing overlap alone cannot infer which words belong to the visible portion.

Only the overlapping part of a source cue survives, then its timestamps shift to the clip start.

Match the media timestamp origin

A subtitle file and encoded video must agree on their timebase origin. Trimming frames while preserving an old presentation timestamp can move the video relative to rewritten cue times. FFmpeg's timestamp filters and subtitle rendering controls should be checked against the exact filter sequence used by the application.

Use an authored fixture with a visible time marker and a cue whose expected appearance is obvious. Inspect frames just before, inside and after the cue interval. A successful encode and a valid subtitle file do not prove that the words appear at the intended moment.

Preserve text and escaping

Subtitle text and file paths require escaping appropriate to the chosen renderer and filter syntax. Avoid constructing an FFmpeg shell string from arbitrary transcript text. Keep transcript contents in a controlled subtitle file and invoke the process with an argument array where possible.

The interval assertions above are suitable for local execution. They do not validate a speech-recognition model or establish rendered subtitle quality. References: FFmpeg filters and FFprobe. ShortForge provides related local-video context.