Check an Omni edit's length with video-inspect before a timeline join

An edit should follow the source length. Confirm it with a probe-only video-inspect call before the clip goes into a Timeline render, with a Python read.

4 min readSume
All posts

To check the length of a Gemini Omni Flash edit before a timeline join, call POST /v1/video-inspect on the edited clip with frames: false, then read probe.duration_seconds. The docs say the edit output follows the source clip, but the duration field is only a reserve hint, so a probe is the cheap way to put a real number on the slot.

Why the probe matters

A Timeline render declares each slot's duration, and the whole output must match the audio spine's duration_seconds. Coverage can stop at most 0.5 seconds before the end of the spine. The docs say soft warnings cover padded or looped short sources, so a clip shorter than its slot gets padded or looped, and a looped tail on a talking shot is visible.

The probe call

Video inspect reads one media.sume.com clip. With frames: false it returns only the probe, with no stills. The default mode is sync with a wait of up to 30 seconds, otherwise you get a 202 and poll. An Idempotency-Key is required.

curl -X POST https://api.sume.com/v1/video-inspect \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: probe-edit-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/edit.mp4",
    "frames": false
  }'

Read it back

If the submit returned 202, read the job later by its request id. The script below prints the probed duration and whether the clip has audio. It reads the key and the id from the environment.

import asyncio, json, os, urllib.request

def get(path):
    req = urllib.request.Request(
        "https://api.sume.com" + path,
        headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"]},
    )
    with urllib.request.urlopen(req) as resp:
        return json.load(resp)

async def main():
    inspect_id = os.environ["INSPECT_ID"]
    out = await asyncio.to_thread(get, "/v1/video-inspect/" + inspect_id)
    probe = out["video_inspect"]["probe"]
    print(probe["duration_seconds"], probe["has_audio"])

asyncio.run(main())

Which clips need the check

Not every edit needs it. A clip that goes straight to a social post with no sound design can be judged by eye. A clip that is one of six slots on a timeline, with a voice-over fitted to exact times, does need the number, since a slot that comes up short by a second shifts everything the spine has laid out after it. Check the live catalog for what a probe-only inspect costs.

Keep the numbers in a small manifest next to the clips: slot, source id, probed seconds, planned seconds. It makes the timeline body a few lines of script rather than a manual edit.

What to do with the number

Compare the probed length with the slot you planned and decide.

Probe result and what to do
Probe saysAction
Longer than the slotSet the slot duration to the slot length; the clip is cut at the end
Within 0.5 s shorterLeave it; the coverage rule allows it
Much shorterSet duration to the probed length and adjust the spine, or trim the others
has_audio falseThe slot is video only; the spine carries the sound

Plan before you render

POST /v1/timeline-1.0/plan is unbilled. It checks the schema and the Sume-host URLs and compiles the document, returning duration_seconds, billable_minutes and an estimated cost. It cannot predict short-source pad and loop warnings, which is why the probe comes first. Rendering costs $0.10 per started minute. See the reserve and 30-second cap for how the edit's own reservation behaves.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume