How to Debug Subtitle Misalignment Issues in Video-Use Rendered Videos

Subtitle misalignment in video-use output stems from three root causes: incorrect timestamp conversion in the master SRT, subtitles applied before overlays in the filter graph, or missing subtitle files.

The browser-use/video-use repository automates video rendering from multiple source transcripts, but timing errors can occur when the pipeline converts word-level timestamps into output-timeline coordinates. This guide provides a systematic debugging workflow based on the actual source code implementation to help you identify and fix subtitle synchronization issues.

Verify Master SRT Timestamp Conversion

The build_master_srt function in helpers/render.py (lines 15-75) converts per-source transcript timestamps into output-timeline timestamps by applying segment offsets. Incorrect calculations here cause persistent drift throughout the video.

Check the Offset Calculations

The conversion logic applies accumulated segment offsets to local timestamps:

out_start = max(0.0, local_start - seg_start) + seg_offset
out_end   = max(0.0, local_end   - seg_start) + seg_offset

Hard Rule 5 in SKILL.md (lines 22-27) mandates that the master SRT must use output-timeline offsets. If your subtitles appear consistently early or late by a fixed duration, the seg_offset accumulation logic at lines 28-73 is likely miscalculating the accumulated segment durations.

Inspect Generated Files

Verify that edit/master.srt contains monotonically increasing timestamps starting near 0 seconds. Compare cue timestamps against the source transcript JSON to ensure the difference equals the expected segment offset.


# Display first 10 cues from the master SRT

head -n 40 edit/master.srt

# Check raw transcript timestamps for a specific source

jq '.words[] | {text, start, end}' edit/transcripts/C0103.json | head

Validate Subtitle Filter Order in FFmpeg Pipeline

Hard Rule 1 requires subtitles to be the last filter in the filter graph. If subtitles are applied before overlays, they will be hidden or appear misaligned.

Confirm Filter Graph Structure

The build_final_composite function (lines 95-170 in helpers/render.py) assembles the filter graph in three stages. The subtitles filter must appear at lines 38-44:

filter_parts.append(
    f"{current}subtitles='{subs_abs}':force_style='{SUB_FORCE_STYLE}'[outv]"
)

Examine the generated FFmpeg command output to verify that -filter_complex ends with the subtitles= filter. If the subtitles parameter appears before overlay filters, the pipeline violates Hard Rule 1.

Test with the --no-subtitles Flag

Run the render script with --no-subtitles to isolate the issue:

python helpers/render.py edit/edl.json -o final.mp4 --no-subtitles

If the video renders correctly without subtitles, the misalignment originates from the subtitle filter placement or the SRT file itself, not the underlying video composition.

Check Subtitle File Path Resolution

The script silently skips the subtitle filter if the resolved path does not exist. The existence check occurs at lines 8-10 of build_final_composite:

has_subs = subtitles_path is not None and subtitles_path.exists()

Verify file presence by checking the resolved path printed by the script (look for "subtitles: yes/no" in the output). If you specified --build-subtitles, confirm that the function successfully wrote the file via out_path.write_text at the end of build_master_srt.

Inspect Final Video with ffprobe

Use ffprobe to extract embedded subtitle timestamps and compare them against your master SRT:


# Check subtitle stream metadata

ffprobe -loglevel error -show_entries stream=index,codec_type:stream_tags=language \
        -select_streams s -i final.mp4

# Dump first 10 seconds of subtitle timestamps

ffprobe -loglevel error -show_entries frame=pkt_pts_time:stream_index=2 \
        -select_streams s -read_intervals 0%+10 -i final.mp4

The pkt_pts_time values should match the timestamps in edit/master.srt. Any deviation indicates a mismatch between the generated SRT and the filter graph application.

Enable Verbose FFmpeg Logging

Modify the command construction in build_final_composite to expose the exact filter chain:

cmd = [
    "ffmpeg", "-y", "-loglevel", "info",  # Add this flag

    *inputs,
    "-filter_complex", filter_complex,
    # ... remaining arguments

]

Re-run the render and examine the output for the filter_complex string. Confirm that the subtitle filter appears as the final element producing the [outv] output label.

Summary

  • Master SRT timestamp conversion happens in build_master_srt (lines 15-75) and must account for segment offsets according to Hard Rule 5.
  • Subtitle filter order must place the subtitles filter last in the filter graph (Hard Rule 1), implemented at lines 38-44 of build_final_composite.
  • File existence validation occurs at lines 8-10 and silently disables subtitles if the path is invalid.
  • ffprobe verification confirms that embedded subtitle timestamps match the source SRT file.
  • Verbose logging reveals the exact FFmpeg filter chain for manual inspection.

Frequently Asked Questions

Why do my subtitles appear at the wrong time even though the SRT file looks correct?

If the SRT timestamps appear correct but the video shows misalignment, the seg_offset calculation in build_master_srt (lines 28-73) likely contains an arithmetic error. Verify that the accumulated offsets correctly map local transcript times to the output timeline by comparing the difference between a transcript JSON timestamp and the corresponding SRT cue time.

How can I tell if subtitles are being hidden by video overlays?

Run the render with --no-subtitles first. If the underlying video composition looks correct without subtitles but the overlay appears to cover the text when subtitles are enabled, the subtitle filter is positioned before the overlay filters in the filter graph. According to Hard Rule 1 in SKILL.md, the subtitles filter must be the last element in the chain, as implemented at lines 38-44 of build_final_composite.

What causes subtitles to disappear completely from the rendered output?

The script checks subtitles_path.exists() at lines 8-10 of build_final_composite and sets has_subs = False if the file is missing. Check that the resolved path points to an existing file and that --build-subtitles actually wrote the file to disk (the function ends with out_path.write_text). The script indicates file presence with a "subtitles: yes/no" message in the output.

How do I manually rebuild the master SRT for testing?

Import the build_master_srt function from helpers/render.py and call it with the EDL JSON and output directory:

from helpers.render import build_master_srt
import json
from pathlib import Path

edl = json.loads(Path('edit/edl.json').read_text())
build_master_srt(edl, Path('edit'), Path('edit/master_test.srt'))

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →