timeline_must_start_at_zero and transition_on_first_segment fixes

Timeline 1.0 needs video[0].start to be 0 and no transition on slot 0. How to open on a fade or a later in-point, with a Python builder that runs.

4 min readSume
All posts

Timeline 1.0 refuses a document whose first video slot does not start at 0 (timeline_must_start_at_zero) or whose first slot carries a transition (transition_on_first_segment). Set video[0].start to 0 and remove its transition. To begin partway into a file use source_in, and to open from black use output.fade_in_seconds.

Why can't the first slot have a transition?

A transition describes the boundary into a slot from the one before it. Slot 0 has no predecessor, so there is nothing to blend with. The Timeline 1.0 page lists the type as legal only on slots after the first, and says video[0].start must be 0 with later starts increasing.

The start field is a position on the audio spine, not a position in the source file. If your first clip should begin at 12 s of the file, that is source_in: 12, while start stays 0.

Opening a Timeline 1.0 render, read 2026-10-03 from the Timeline 1.0 page
I wantUseNot
First clip begins 12 s into its filevideo[0].source_in = 12video[0].start = 12
Open from blackoutput.fade_in_seconds (0 to 5)video[0].transition
Cross-fade clip 1 into clip 2video[1].transitionvideo[0].transition
Only a section of a long fileVideo trim first, or source_in plus durationA negative start

How is this different from an FFmpeg concat list?

FFmpeg's concat approaches take an ordered list and never ask where the first clip sits on a clock. Sume's Timeline is built around an audio spine, so every slot is placed on that clock and the first one anchors it. The in-point inside the file is a separate field, which is the same split FFmpeg makes between -ss on an input and the position in the output.

Output edge fades are separate again: output.fade_in_seconds and output.fade_out_seconds accept 0 to 5 s and their sum cannot exceed the output length, otherwise the render refuses with edge_fades_exceed_output.

How do I build a valid video[] array?

Accumulate durations for the starts, and add a fade only from the second slot onward. The Python below does that and prints the starts together with the audio length you need. It uses placeholder artifact URLs in the shape of the documentation examples.

Every source_url must be a media.sume.com artifact or asset in your workspace, so import external files first. Then check the document with the unbilled POST /v1/timeline-1.0/plan call before the render.

def build(durations, fade=0.0):
    video, t = [], 0.0
    for i, d in enumerate(durations):
        slot = {"source_url": f"https://media.sume.com/artifacts/artf_demo/c{i}.mp4",
                "start": round(t, 3), "duration": d}
        if i and fade:
            slot["transition"] = {"type": "fade", "duration": fade}
        video.append(slot)
        t += d
    return video

video = build([8, 6, 10], fade=0.25)
assert video[0]["start"] == 0 and "transition" not in video[0]
total = video[-1]["start"] + video[-1]["duration"]
print([s["start"] for s in video], "audio.duration_seconds >=", total - 0.5)

What else trips the first slot?

A still as slot 0 is fine: stills are held for the slot duration, and any motion on a still is ignored with a motion_ignored warning. A slot shorter than 0.2 s is refused. And the spine must exist: audio.duration_seconds is required, from 1 to 1800 seconds, even in silence mode.

What does a correct first slot look like?

A slot is a source_url, a start on the spine, a duration, and optional fields such as source_in, fit and motion. For the first one, the minimal valid form is start: 0, a positive duration of at least 0.2 s, and no transition. If a script generator emits a transition for every slot by habit, strip it from index 0 in the same function that sets the start.

If the opening needs a branded sting rather than a fade, make it its own first slot, a short clip or still, and start the main footage in slot 1 with a transition from there. That keeps both rules satisfied and gives the cross-fade something to blend with.

How do I test a generated timeline?

Add two assertions to the unit test that covers your builder: the first slot's start equals 0 and the first slot has no transition key. They are cheap, they run offline, and they catch the two refusals before a request is made.

Then keep the unbilled plan call in an integration test with a small fixture document. It returns duration_seconds, segment_count and an estimate, so you can also assert that the length you expect is the length the API computed.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume