Trim 12 Shorts from one recording with asyncio and a semaphore

Cut 12 Shorts from one recording with asyncio and httpx: 12 trims at $0.02 is $0.24. A semaphore of 4 caps in-flight requests; the limit is your choice.

4 min readSume
All posts

A 12-clip batch from one recording is 12 independent trim jobs at $0.02 each, $0.24 in total, and they can run together. Use asyncio.run(main()) with an httpx.AsyncClient and a semaphore so only a few requests are in flight; the 4 below is a polite choice and not an API limit.

YouTube defines Shorts as vertical videos up to 3 minutes (read 2026-10-09), so each range is well inside the 900 s trim output cap.

Cost and limits

Twelve Shorts from one recording (rates and limits read 2026-10-09)
ItemValue
Trim jobs12
Rate per job$0.02
Total$0.24
Source recordingup to 1800 s
Each output0.2 s to 900 s

Code

Each range gets its own Idempotency-Key, so rerunning the script re-reads the same jobs instead of billing again.

import asyncio, os, httpx

API = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
SRC = "https://media.sume.com/artifacts/artf_demo/long.mp4"

async def cut(c, sem, i, start, end):
    async with sem:
        r = await c.post(f"{API}/v1/video-trim", headers={
            **H, "Idempotency-Key": f"shorts-{i}-{start}-{end}"},
            json={"video_url": SRC, "start": start, "end": end})
        r.raise_for_status()
        return r.json()["data"]["request_id"]

async def main(ranges):
    sem = asyncio.Semaphore(4)
    async with httpx.AsyncClient(timeout=60) as c:
        return await asyncio.gather(
            *(cut(c, sem, i, s, e) for i, (s, e) in enumerate(ranges)))

jobs = asyncio.run(main([(i * 60, i * 60 + 45) for i in range(12)]))

Then what

  • The submit returns a job; poll GET /v1/jobs/:id/status for sume_status, then read GET /v1/jobs/:id/result for video_url.
  • A 429 or 5xx should retry with the same key, never a new one.
  • A source over 1800 s fails with source_duration_exceeded; split it first.
  • The ranges here are placeholders; take real ones from your transcript.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume