Fixed last sentence/subtitle entry timing in generated subtitles

This commit is contained in:
Deniz Şafak
2025-07-16 01:00:27 +03:00
parent 5d9409d391
commit d2f1c12de9
2 changed files with 20 additions and 33 deletions
+16 -33
View File
@@ -793,6 +793,7 @@ class ConversionThread(QThread):
tokens_with_timestamps,
new_entries,
self.max_subtitle_words,
fallback_end_time=chunk_start + chunk_dur
)
if merged_subtitle_file:
subtitle_format = getattr(
@@ -819,6 +820,7 @@ class ConversionThread(QThread):
chapter_tokens_with_timestamps,
new_chapter_entries,
self.max_subtitle_words,
fallback_end_time=chapter_current_time + chunk_dur,
)
if chapter_subtitle_file:
subtitle_format = getattr(
@@ -1146,7 +1148,7 @@ class ConversionThread(QThread):
return f"{h}:{m:02}:{s:02}.{cs:02}"
def _process_subtitle_tokens(
self, tokens_with_timestamps, subtitle_entries, max_subtitle_words
self, tokens_with_timestamps, subtitle_entries, max_subtitle_words, fallback_end_time=None
):
"""Helper function to process subtitle tokens according to the subtitle mode"""
if not tokens_with_timestamps:
@@ -1191,9 +1193,15 @@ class ConversionThread(QThread):
sentence_text = ""
for t in current_sentence:
sentence_text += t["text"] + (t.get("whitespace", "") or "")
subtitle_entries.append((start_time, end_time, sentence_text.strip()))
# Fallback for last entry
if subtitle_entries and fallback_end_time is not None:
last_entry = subtitle_entries[-1]
start, end, text = last_entry
if end is None or end <= start or end <= 0:
subtitle_entries[-1] = (start, fallback_end_time, text)
else:
# Word count-based grouping
try:
@@ -1230,37 +1238,12 @@ class ConversionThread(QThread):
subtitle_entries.append(
(group[0]["start"], group[-1]["end"], text.strip())
)
def _write_ass_subtitle(
self, file_path, subtitle_entries, is_centered=False, is_narrow=False
):
with open(file_path, "w", encoding="utf-8", errors="replace") as f:
# Minimal ASS header
f.write("[Script Info]\n")
f.write("Title: Generated by Abogen\n")
f.write("ScriptType: v4.00+\n\n")
# Only events section, use override tags for positioning
f.write("[Events]\n")
f.write(
"Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n"
)
# Set margin based on is_narrow parameter
margin = "90" if is_narrow else ""
alignment_tag = ""
if is_centered:
alignment = 5
alignment_tag = f"{{\\an{alignment}}}"
# Write each subtitle with override tag for alignment and margins
for i, (start, end, text) in enumerate(subtitle_entries, 1):
start_time = self._ass_time(start)
end_time = self._ass_time(end)
f.write(
f"Dialogue: 0,{start_time},{end_time},Default,,{margin},{margin},0,,{alignment_tag}{text}\n"
)
# Fallback for last entry
if subtitle_entries and fallback_end_time is not None:
last_entry = subtitle_entries[-1]
start, end, text = last_entry
if end is None or end <= start or end <= 0:
subtitle_entries[-1] = (start, fallback_end_time, text)
def cancel(self):
self.cancel_requested = True
self.should_cancel = True