# How Output-Timeline Subtitle Offsets Are Calculated in the video-use Master SRT Builder

> Learn how video-use Master SRT Builder calculates output-timeline subtitle offsets. Understand the formula for mapping segment timings to global positions.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: internals
- Published: 2026-07-09

---

**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`](https://github.com/browser-use/video-use/blob/main/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:

```python
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_start`** and **`local_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 at `0.0` and incremented by `seg_duration` after 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

```python
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

```python
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

```python
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`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), specifically within `build_master_srt`, `_words_in_range`, and `_srt_timestamp`.
- **Cumulative tracking**: The `seg_offset` variable 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`](https://github.com/browser-use/video-use/blob/main/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`](https://github.com/browser-use/video-use/blob/main/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).