Adding updates to titlesZZ

This commit is contained in:
2026-07-14 14:04:44 +02:00
parent f9ff847f6b
commit 308a9f8bcd
17 changed files with 4608 additions and 186 deletions
+57 -11
View File
@@ -974,6 +974,49 @@ def _resolve_video_path(
return source_path, False
def _interpolate_slide_times(
marker_timings: list[MarkerTiming],
slides: dict,
total_duration: float,
) -> list[float]:
"""
Return sorted slide timestamps with unaligned slides (timestamp < 0)
interpolated evenly between their aligned neighbours. Used by both
_extract_slide_events and _extract_video_events so video end-times
never skip over a slide that Whisper failed to align.
"""
all_markers = [
(t.timestamp, t.marker_id)
for t in marker_timings
if t.marker_id in slides
]
if not all_markers:
return []
n = len(all_markers)
resolved = list(all_markers)
i = 0
while i < n:
if resolved[i][0] < 0:
run_start = i
while i < n and resolved[i][0] < 0:
i += 1
run_end = i
prev_time = resolved[run_start - 1][0] if run_start > 0 else 0.0
next_time = resolved[run_end][0] if run_end < n else total_duration
count = run_end - run_start
for j, idx in enumerate(range(run_start, run_end)):
frac = (j + 1) / (count + 1)
resolved[idx] = (
prev_time + (next_time - prev_time) * frac,
resolved[idx][1],
)
else:
i += 1
return sorted(t for t, _ in resolved)
def _extract_slide_events(
marker_timings: list[MarkerTiming],
slides: dict[str, SlideDefinition],
@@ -991,7 +1034,8 @@ def _extract_slide_events(
"""
range_start, range_end = time_range if time_range else (0.0, float("inf"))
# Get ALL slide markers in manuscript order (aligned and unaligned)
# Get ALL slide markers in manuscript order (aligned and unaligned),
# with unaligned ones interpolated via the shared helper.
all_slide_markers: list[tuple[float, str]] = []
for timing in marker_timings:
if timing.marker_id in slides:
@@ -1000,9 +1044,8 @@ def _extract_slide_events(
if not all_slide_markers:
return []
# Interpolate timestamps for unaligned slides (timestamp < 0).
# For each run of consecutive unaligned slides, spread them evenly between
# the nearest aligned slides before and after in manuscript order.
# Re-derive interpolated times (same logic as _interpolate_slide_times but
# we need the (time, id) pairs here for event building).
n = len(all_slide_markers)
resolved: list[tuple[float, str]] = list(all_slide_markers)
@@ -1075,13 +1118,12 @@ def _extract_video_events(
warnings: list[str] = []
range_start, range_end = time_range if time_range else (0.0, float("inf"))
# Collect slide times for video: end time calculation
slide_times: list[float] = sorted(
[
t.timestamp
for t in marker_timings
if t.marker_id in slides and t.timestamp >= 0
]
# Collect slide times for video end-time calculation.
# Use the interpolated times (same as _extract_slide_events) so that a slide
# Whisper failed to align doesn't get skipped, causing the preceding video to
# bleed through into the following slide.
slide_times: list[float] = _interpolate_slide_times(
marker_timings, slides, total_duration
)
# Pause-variant prefixes — the only thing the render pass still needs from
@@ -1177,6 +1219,10 @@ def _extract_video_events(
if slide_time > start_time:
end_time = slide_time
break
# pause_narration videos must stay visible for the full pause duration —
# the narration is held for that long, so the overlay should match.
if video_source.pause_narration:
end_time = max(end_time, start_time + video_source.pause_narration)
else:
# end_on is None and marker_type == "narration": runs to end
end_time = total_duration