fix(renderer): skip ffprobe Phase 3.5 — use pre-computed freeze duration

Cloud Run-generated freeze segments caused FFprobe to return code 1 with
empty stderr when dispatched to the Celery ffmpeg queue, crashing the
render for every language. The freeze segments are created to an exact
pre-computed duration (ad_duration + silence_before + silence_after),
so probing is unnecessary — assign that value directly instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Vadym Samoilenko 2026-05-01 17:29:33 +01:00
parent 9733700874
commit a3cfe2ff8c

View file

@ -735,29 +735,17 @@ class VideoRendererService:
# ============================================================
# PHASE 3.5: Measure actual freeze segment durations for VTT retiming
# ============================================================
# NOTE: Use _get_video_duration_local directly since freeze segments are
# local files. Using _get_video_duration would incorrectly use the cached
# source video URI in Cloud Run mode instead of measuring the freeze segment.
logger.info("Measuring actual freeze segment durations...")
# Use the pre-computed expected duration for each freeze segment.
# Cloud Run-generated freeze segments are created to this exact duration,
# so probing is unnecessary and avoids dispatching to the Celery ffmpeg
# queue (which caused FFprobe code 1 failures on Cloud Run output files).
logger.info("Setting freeze segment durations from pre-computed values...")
for p in valid_placements:
i = p["index"]
freeze_path = freeze_segment_paths[i]
actual_duration = await self._get_video_duration_local(freeze_path)
p["actual_freeze_duration"] = actual_duration
# Log any discrepancy between expected and actual duration
expected = p["ad_duration"] + p["silence_before"] + p["silence_after"]
discrepancy = actual_duration - expected
if abs(discrepancy) > 0.01: # 10ms threshold
logger.warning(
f"Freeze segment duration mismatch for cue {p['cue_index']}: "
f"expected={expected:.3f}s, actual={actual_duration:.3f}s, "
f"discrepancy={discrepancy:+.3f}s"
)
else:
logger.debug(
f"Freeze segment cue {p['cue_index']}: duration={actual_duration:.3f}s (expected={expected:.3f}s)"
)
p["actual_freeze_duration"] = expected
logger.debug(
f"Freeze segment cue {p['cue_index']}: duration={expected:.3f}s"
)
# ============================================================
# PHASE 4: Assemble segment list in correct order