How Output-Timeline Subtitle Offsets Are Calculated in the video-use Master SRT Builder
In the browser-use/video-use repository, subtitle offsets are calculated by mapping segment-relative word timings to global output positions using the formula max(0.0, local_start - seg_start) + seg_offset, where seg_offset accumulates the total duration of all previously processed segments.
The master SRT builder transforms per-source transcript timings into a seamless timeline that matches the final edited video. Understanding how output-timeline subtitle offsets are calculated is critical for debugging synchronization issues or extending the caption generation pipeline.
The Core Offset Formula
The build_master_srt function in helpers/render.py implements a precise mathematical transformation that translates local word timestamps into global cue positions.
Segment-Relative to Global Timeline
For each caption chunk, the code computes output timestamps as follows:
out_start = max(0.0, local_start - seg_start) + seg_offset
out_end = max(0.0, local_end - seg_start) + seg_offset
Variable definitions:
local_startandlocal_end: The absolute start and end times of the word chunk within the original source file, clamped to the segment's bounds (lines 60-64).seg_start: The start time of the current segment in the source timeline as specified by the EDL (Edit Decision List) entry.seg_offset: A running total representing the cumulative duration of all previously processed segments, initialized at0.0and incremented byseg_durationafter each segment (lines 26-27, 73).
The subtraction local_start - seg_start calculates the relative position of the word within its segment. Adding seg_offset shifts this value into the global output timeline, ensuring that earlier segments contribute their full duration to subsequent cue positions.
The Processing Pipeline
The offset calculation occurs within a six-stage pipeline that transforms source transcripts into the final SRT file.
1. Source Transcript Loading
For every cut segment defined in the EDL, the system loads the corresponding transcript JSON from transcripts_dir / f"{src_name}.json".
2. Word Range Selection
The _words_in_range helper function (lines 300-311) filters the transcript to include only words that fall within the segment's time boundaries.
3. Word Chunking
Selected words are grouped into 2-word chunks (or smaller units if punctuation appears), creating the caption text blocks that will appear in the output (lines 444-457).
4. Cue Duration Enforcement
The code ensures a minimal cue length of 0.4 seconds. If out_end <= out_start, the end timestamp is automatically extended forward to maintain readability (lines 65-66).
5. Timestamp Formatting
The _srt_timestamp function (lines 92-98) converts floating-point second counts into standard SRT format (HH:MM:SS,mmm).
6. Final Assembly
The resulting list of (out_start, out_end, text) tuples is sorted by start time (line 76) and written to disk in standard SRT format (lines 78-84).
Practical Implementation Examples
Generating a Master SRT for an Edited Timeline
from pathlib import Path
import json
from helpers.render import build_master_srt
# Assume `edl` is the Edit Decision List produced by the LLM
# and `edit_dir` points at the directory where segment files live.
edl_path = Path("edit/edl.json")
edit_dir = Path("edit")
out_srt = Path("edit/master.srt")
with edl_path.open() as f:
edl = json.load(f)
build_master_srt(edl, edit_dir, out_srt)
print(f"✅ Master subtitles written to {out_srt}")
Manual Offset Calculation
def cue_offset(seg_start, seg_offset, chunk_start, chunk_end):
# chunk_* are absolute timestamps from the source transcript
out_start = max(0.0, chunk_start - seg_start) + seg_offset
out_end = max(0.0, chunk_end - seg_start) + seg_offset
return out_start, out_end
# Segment starts at 30.0 s in the source, has already contributed 45.2 s to the output.
seg_start = 30.0
seg_offset = 45.2
chunk_start = 31.4 # word begins at 31.4 s in the source
chunk_end = 31.9 # word ends at 31.9 s in the source
print(cue_offset(seg_start, seg_offset, chunk_start, chunk_end))
# → (46.6, 47.1) seconds in the final video timeline
Converting Seconds to SRT Format
from helpers.render import _srt_timestamp
# Example: first cue after processing
start_sec = 12.345 # seconds in the final video
end_sec = 12.845
print(_srt_timestamp(start_sec), "-->", _srt_timestamp(end_sec))
# → 00:00:12,345 --> 00:00:12,845
Summary
- Offset calculation: Output timestamps derive from
max(0.0, local_time - seg_start) + seg_offset, combining segment-relative positioning with cumulative duration tracking. - Core implementation: The logic resides in
helpers/render.py, specifically withinbuild_master_srt,_words_in_range, and_srt_timestamp. - Cumulative tracking: The
seg_offsetvariable accumulates the total duration of processed segments, ensuring seamless timeline continuity across cuts. - Chunk processing: Words are grouped into 2-word captions before offset calculation, with automatic extension for cues shorter than 0.4 seconds.
- Code references: Critical calculations occur at lines 26-27, 60-66, 73, 76, 78-84, 92-98, 300-311, and 444-457 in
helpers/render.py.
Frequently Asked Questions
What prevents negative timestamps when a word appears slightly before the segment start?
The max(0.0, local_start - seg_start) expression ensures that even if boundary clamping places a word near the segment edge, the calculation never produces negative values. This safeguard maintains valid SRT formatting while preserving the intended synchronization (lines 60-64).
How does the system handle time gaps between non-consecutive segments?
The seg_offset variable maintains a running total of all previous segment durations. When processing transitions to a new segment, this offset increments by the previous segment's duration (lines 26-27, 73), effectively compressing the source timeline and eliminating gaps so the output matches the edited video flow.
Can the default 2-word chunking strategy be modified?
The current implementation in helpers/render.py (lines 444-457) groups words into 2-word chunks with punctuation-based early breaks. While the code does not expose a configuration parameter for chunk size, developers can modify the grouping logic within build_master_srt to adjust caption density or maximum character limits.
Why is a minimum cue length of 0.4 seconds enforced?
The 0.4-second minimum ensures that subtitle cues remain readable and valid according to standard SRT specifications. When word boundaries produce out_end <= out_start, the code automatically extends the end timestamp by 0.4 seconds to prevent zero-duration or invalid cues (lines 65-66).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →