One 6-minute b-roll, twelve Shorts episodes: source_in offsets

Slice one imported b-roll into twelve non-repeating 30-second episode backgrounds with Timeline 1.0 source_in, and plan the whole season unbilled in Python.

6 min readSume
All posts

Give every episode its own slice of the same footage

A season of Shorts needs a background for each episode, and twelve separate stock clips is twelve things to import and keep track of. The alternative is one long b-roll file and a different source_in for each episode. In Timeline 1.0, video[].source_in is the in-point into the file, so episode 1 can start at second 0 of the b-roll, episode 2 at second 30, and so on, with no frame shown twice across the season.

This matters now because YouTube's Shorts series feature, with seasons, episodes, custom thumbnails and sequential playback, began rolling out on 23 September per the October platform roundup. A season is a set of near-identical episodes, and a pattern that generates twelve bodies from one file is easier to maintain than twelve hand-built ones.

The math, so the last episode does not run out

With a 360-second b-roll and 30-second episodes, episode n uses seconds (n-1)*30 to n*30, and episode 12 ends exactly at 360. If the b-roll is any shorter, the last slices run past the end of the file. Sume does not fail that: it pads or loops a short source and reports it as a soft warning, and the plan cannot predict it because the plan never downloads media. That is why the script below asserts the arithmetic in your own code instead of finding out from a warning on episode 12.

Read the real length of the b-roll first. Video inspect returns a probe for any clip in your workspace, and frames: false returns only the probe with no stills, the lightest form of the call (Sume bills probe and stills by their Modal compute, so it is cheap rather than free). Use that number for BROLL_SECONDS so the assertion compares against the file, not against your memory of it.

Slicing numbers for a season

Every figure here is derived from the slice size; the render bills by output minute, not by source length.

b-roll needed per season at 30 s per episode, and the render bill at the documented rate (read 2026-10-06)
Episodesb-roll neededSource minutes readRender minutes at $0.10
6180 s36 minutes = $0.60
12360 s612 minutes = $1.20
24720 s1224 minutes = $2.40

Python: plan twelve episodes from one file

The helper at the top posts JSON to the API with your key. The loop builds one body per episode, each with its own spine file and its own source_in, and posts it to the unbilled plan endpoint. Replace the example URLs with your imported artifacts. Once the numbers look right, post each body to /v1/timeline-1.0/render with Idempotency-Key: season1-ep<N>-v1.

import json, os, time, urllib.request

def sume(method, path, body=None, key=None):
    h = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
         "Content-Type": "application/json", "User-Agent": "sume-example/1.0"}
    if key:
        h["Idempotency-Key"] = key
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request("https://api.sume.com" + path, data, h, method=method)
    with urllib.request.urlopen(req) as r:
        return json.load(r)

BROLL = "https://media.sume.com/artifacts/artf_demo/broll-360s.mp4"
BROLL_SECONDS, EP_SECONDS = 360, 30
for ep in range(12):
    start = ep * EP_SECONDS
    assert start + EP_SECONDS <= BROLL_SECONDS, "b-roll is too short"
    body = {"audio": {"url": f"https://media.sume.com/artifacts/artf_demo/ep{ep + 1}.wav",
                      "duration_seconds": EP_SECONDS},
            "video": [{"source_url": BROLL, "start": 0, "duration": EP_SECONDS,
                       "source_in": start}]}
    plan = sume("POST", "/v1/timeline-1.0/plan", body)
    print(ep + 1, plan["billable_minutes"], plan["estimated_cost_usd_micros"])

Things that are not covered by this pattern

A source slice has no audio of its own in this design: the spine is the episode's voice file. If you want the b-roll's sound instead, detach it first. Looping is also not a style choice here; if you want a short clip repeated on purpose, say so with several slots rather than relying on the pad or loop warning. And the b-roll must be on media.sume.com, so import it once with POST /v1/media-imports before you plan anything.

One more reason to prefer this over twelve stock clips is consistency: the same lighting, the same color and the same grain in every episode means your captions and your voice carry the identity of the series, not the background. If you do want variety, change the fit value or crop with the video filter on a copy of the b-roll rather than hunting for new footage.

If your season is not a clean multiple, the same arithmetic still works. For ten episodes of 45 seconds you need 450 seconds of b-roll, with source_in values of 0, 45, 90 and so on. For variable lengths, keep a running offset in the loop instead of multiplying: add each episode's length to the offset after you build its body. That also makes it obvious when the total exceeds the file, which is the case the assertion above is there to catch before any request is sent.

A last practical point is cost visibility. The plan returns billable_minutes and estimated_cost_usd_micros for each body, so the loop above prints a line per episode that you can sum into a season budget before spending anything. The render itself bills per whole output minute at the documented $0.10 rate, so twelve 30-second episodes are twelve minutes, not six, because each episode is its own job and rounds up on its own. Confirm the live rate in GET /v1/catalog before you quote a number to anyone.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume