Video trim
Current SoT. Media L2 range cut (
sume/video-trim-1.0, #5953). Dest and prod. This is not clip inspection — that is video inspect. It is not assembly — sequencing, transitions, and the audio spine stay on Timeline 1.0.
Video trim 1.0 takes one workspace media.sume.com clip plus a range
and returns a new MP4 artifact holding only [start, end). The source
is untouched. The server compiles ffmpeg on the worker media runtime
(apps/api/src/routes.ts createVideoTrimV1 /
submitSumeVideoTrimJob).
There is no GET /v1/video-trim/:id. Poll the job envelope:
Hosted MCP: video_trim (packages/mcp-server/src/mcp.ts). Writes need
idempotency_key (and mcp:write under OAuth). Flow: video_trim →
jobs_wait → jobs_result.
Create a trim
Required: video_url (this workspace’s media.sume.com artifact or
asset), start (seconds, ≥ 0), and exactly one of end or
duration. There is no open-internet fetch — import first
(POST /v1/media-imports). Idempotency-Key is required.
Optional: precision, audio, output (exact only), plus the usual
mode / webhook_url / wait_timeout_seconds communication fields.
Default mode is async (readCommunicationOptions). Pass
mode: "sync" to wait up to 30 seconds for a 200 finished job, or
get 202 and poll.
A successful submit returns a job (request_id is the job id). When
result_ready, GET /v1/jobs/:id/result is kind: video_trim with
video_url (new artf_, never the source), duration_seconds,
actual_start_seconds, precision, audio, output, and optional
warnings[]. Drop that MP4 into timeline_create video[] with
source_in 0.
Public rate: $0.02 per job (VIDEO_TRIM_PUBLIC_PRICING; confirm live
in GET /v1/catalog). No provider inference — worker ffmpeg only.
Program
| Field | Effect |
|---|---|
start | In-point, seconds from the source start. Required. |
end | Out-point, seconds. Exactly one of end / duration. Past the source it clamps and the result warns trim_clamped_to_source. |
duration | Length of the cut, seconds. 0.2–900. Exactly one of end / duration. |
precision | exact (default): frame-accurate re-encode (libx264, yuv420p). keyframe: stream copy; the cut may start a GOP early — re-base against actual_start_seconds. |
audio | keep (default) or drop. Exact remuxes kept audio as AAC. |
output | Optional { width, height, fps } conform on the way out. exact only. Width/height 256–2160; fps 24 | 25 | 30 | 60. Omit to inherit the source. |
Caps (from packages/api-contract/src/index.ts): source ≤ 1800 s;
output ≤ 900 s; output ≥ 0.2 s.
Refusals (stable codes)
| Code | When |
|---|---|
video_trim_range_required | Neither end nor duration. |
video_trim_range_conflict | Both end and duration. |
video_trim_range_empty | end ≤ start, or the range is longer than 900 s. |
video_trim_output_requires_exact | output with precision: "keyframe". |
ffmpeg_fields_rejected | Client sent vf / filter / ffmpeg / cmd / codec / crf / friends. The server compiles ffmpeg. |
unsupported_media_source | video_url is not on the Sume media host. |
source_not_found | Dead or foreign media.sume.com URL. |
unsupported_media_type | HEAD is not a video. |
source_duration_exceeded | Source longer than 1800 s (worker). |
Off-host URLs (https://example.com/…) are rejected at admit. Import first.
Not this surface
| Need | Use |
|---|---|
| Probe / stills / optional STT | Video inspect |
| Audio track as a durable wav / mp3 | Audio detach |
| Sequence several clips | Timeline 1.0 |
| Pixel pass (dim / crop) | Video filter |
Exact frame at t, source size | Video frames |