Cut a clip into 30-second chunks for 30-second post-processing caps

Runway's SDR-to-HDR model and the Magnific upscaler take 30 seconds at most. Cut any clip into 30-second pieces with Sume video trim at $0.02 per cut.

4 min readSume
All posts

Runway's API models guide lists a 30-second input limit for its ruby SDR-to-HDR model and for the Magnific video upscaler, so a 95-second clip has to be cut into four pieces first. Sume's video trim returns a new MP4 for a start and duration you name at $0.02 per job, which makes a four-piece plan cost $0.08.

Input limits that force chunking (read 2026-10-03)
StepMaximum inputSource
Runway ruby, SDR to HDR30 s, under 4096 px per sideRunway API models guide
Magnific video upscaler30 sRunway API models guide
Runway enhance_frame_rate300 sRunway API models guide

What Sume trim accepts

POST /v1/video-trim takes one video_url on media.sume.com, a start and exactly one of end or duration. The source can be up to 1,800 seconds, and each cut can be 0.2 to 900 seconds. Idempotency-Key is required. The default precision is exact, a frame-accurate re-encode, and keyframe is a stream copy that may start a little early, reported in actual_start_seconds. Files from elsewhere must be imported first through POST /v1/media-imports.

Plan the chunks

The plan is plain arithmetic: divide the length by 30, round up, and let the last piece be shorter. The function also drops a trailing sliver under 0.2 seconds, which trim would refuse, and the submit helper uses the chunk start in the idempotency key so a retry replays the same cut.

import math
import os
import requests

AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

def chunk_plan(total, size=30):
    count = math.ceil(total / size)
    plan = [(i * size, min(size, total - i * size)) for i in range(count)]
    return [(start, length) for start, length in plan if length >= 0.2]

def submit_trim(video_url, start, duration):
    headers = {**AUTH, "Idempotency-Key": f"chunk-{start}-{duration}"}
    body = {"video_url": video_url, "start": start, "duration": duration}
    r = requests.post("https://api.sume.com/v1/video-trim", json=body, headers=headers)
    r.raise_for_status()
    return r.json()["request_id"]

plan = chunk_plan(95)
print(plan, "trim cost: $", round(len(plan) * 0.02, 2))

Run it and watch the seams

For a 95-second clip the plan is (0, 30), (30, 30), (60, 30) and (90, 5). Submit each with submit_trim, wait on GET /v1/jobs/{id}/status until each reaches completed, and read the new video_url from GET /v1/jobs/{id}/result. Keep the default exact precision: with keyframe, a piece can begin before the point you asked for, and neighboring pieces would then overlap.

A model that processes each piece on its own can leave a visible change in tone or grain at the join. Pull the last frame of one piece and the first of the next with video frames and compare them before you rejoin.

Rejoining

Sume's Timeline 1.0 assembles ordered video[] slots against one audio spine into a single MP4, at $0.10 per output minute. It needs an audio object, and audio.mode: "silence" declares the length with no spine file when you plan to restore sound another way. The enhance_frame_rate model in Runway's table takes 300 seconds, so for frame-rate work a 95-second clip needs no chunking at all.

Sources

Related posts

More in Media tools

All Media tools posts

Written by Sume