Why does my video freeze while the voiceover keeps playing?
Timeline holds the last frame when slots end before audio.duration_seconds, or leave a gap. Plan reports it free as video_coverage_shorter_than_audio.

The picture freezes because the video slots in your Timeline document cover fewer seconds than audio.duration_seconds, and the renderer holds the previous frame to reach the spine length instead of failing. The render still succeeds, and warnings[] says which of three causes it was.
Timeline 1.0 treats the audio spine as the clock. The output is exactly audio.duration_seconds long, and every video slot is placed on that clock by its declared start and duration. Anything the slots do not cover is filled with a hold of the frame before it.
The three causes, by warning code
Each cause has its own code in the render result. The first two come from the numbers in your document alone, so the free POST /v1/timeline-1.0/plan call returns them before you spend anything. The third needs the real clip length, which only the render probes.
We ran the repository's own plan builder on a 12-second spine with two 4-second slots, the second one starting at 6 seconds and carrying a 0.3-second fade, at 25 fps. It reported a 2-second gap before the second slot and a coverage end of 10 seconds against a 12-second spine.
| Warning code | Trigger | What you see | Fix |
|---|---|---|---|
| timeline_gap_filled | A slot's start is later than the previous slot's start plus duration | Previous frame holds through the gap, then the next slot starts on time | Set the next start to the previous end, or lengthen the previous duration |
| video_coverage_shorter_than_audio | Last slot ends before audio.duration_seconds | Last frame holds to the end of the spine | Lengthen the last slot or add another |
| segment_source_short_padded | A clip is shorter than source_in plus duration | That slot's last frame holds, position unchanged | Trim the slot shorter or use a longer clip, see the short-source post |
Why it is a warning and not an error
The audio is authoritative. A voiceover that must not be cut is more valuable than a refusal, so the compiler keeps the spine intact and fills the picture. The warning text in our run read: "Video coverage ends at 10.000s; holding last frame to audio spine 12.000s." The context object carries coverage_seconds, audio_duration_seconds and hold_seconds, so a script can act on it.
The check runs one way only. The request schema refuses a final slot that ends more than 0.5 seconds after the spine, with invalid_segment_timing. A slot that ends early is accepted and held. So a document can fail for being too long but never for being too short, which is why the freeze surprises people.
Catch it before you render
Declared starts are authoritative, so the arithmetic is easy to do client-side. This function lists every gap and the tail hold for a list of slots, using the same rule the compiler applies. For two 4-second slots with starts 0 and 6 on a 12-second spine it prints the 2-second gap and the 2-second tail.
def coverage_gaps(slots, spine):
gaps, end = [], 0.0
for s in slots:
if s["start"] > end + 1e-6:
gaps.append(("gap", end, s["start"]))
end = s["start"] + s["duration"]
if end + 1e-6 < spine:
gaps.append(("tail", end, spine))
return gaps
slots = [{"start": 0, "duration": 4}, {"start": 6, "duration": 4}]
print(coverage_gaps(slots, 12))Run that, or call the plan endpoint, then fix the numbers. If you want a deliberate freeze, such as a held title card under a long sentence, leave the gap in on purpose and ignore the warning. The coverage_seconds field on the plan response gives the end of the last slot directly. A plan response cannot see source lengths, so the third cause still has to be read from the render result.
Sources
Related posts
More in Media tools
- Video reach campaign: which video lengths to cut from one master
A Google Ads video reach campaign wants a 15 s, a 6 s and sometimes a 30 s horizontal cut, plus a vertical one. Google's compositions, and trims on Sume.
- Vimeo "Invalid Caption File": build clean WebVTT from Sume
Vimeo rejects a cue that starts at the previous cue's end. Sume sentence segments touch, so trim 1 ms, write UTF-8 WebVTT and upload. Script included.
- Webinar to Shorts: pick moments by transcript, not fixed cuts
Fixed-interval cuts make interchangeable Shorts. Read the webinar's sentence segments, choose complete thoughts, then trim and caption each with Sume.
- WebVTT cue settings (line, size) vs Sume anchor_ratio and width
WebVTT line:78%,center and size:90% have close matches in Sume's caption design fields. A converter script, and what per-cue settings a burned render loses.
Written by Sume