Audio detach
Current SoT. Media L2 demux (
sume/audio-detach-1.0, #5953). Dest and prod. This is not clip inspection — that is video inspect. For many ranges, detach once then split with timeline audio.
Audio detach 1.0 takes one workspace media.sume.com video and
returns a new audio artifact. Default is sample-exact wav
(pcm_s16le) — what timeline_create audio.url,
POST /v1/timeline-1.0/audio, and speech-to-text want. The video is
untouched. The server compiles ffmpeg on the worker media runtime
(apps/api/src/routes.ts createAudioDetachV1 /
submitSumeAudioDetachJob).
There is no GET /v1/audio-detach/:id. Poll the job envelope:
Hosted MCP: audio_detach (packages/mcp-server/src/mcp.ts). Writes
need idempotency_key (and mcp:write under OAuth). Flow:
audio_detach → jobs_wait → jobs_result.
Create a detach
Required: video_url (this workspace’s media.sume.com artifact or
asset). There is no open-internet fetch — import first
(POST /v1/media-imports). Idempotency-Key is required.
Optional: format, range, channels, sample_rate, plus the usual
mode / webhook_url / wait_timeout_seconds communication fields.
Default mode is async. 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: audio_detach with
audio_url (new artf_), duration_seconds, format, channels,
sample_rate (null when omitted — inherited from the source),
source_duration_seconds, and optional range / warnings[].
Public rate: $0.01 per job (AUDIO_DETACH_PUBLIC_PRICING; confirm
live in GET /v1/catalog). No provider inference — worker ffmpeg only.
Program
| Field | Effect |
|---|---|
format | wav (default, pcm_s16le sample-exact) or mp3 (128 kbps). |
range | Optional { start, end? } seconds. Omit for the whole track. end open-ended when omitted. |
channels | source (default) or mono. |
sample_rate | 16000 | 44100 | 48000. Omit to inherit the source. 16000 + channels: "mono" is the STT shape. |
Caps (from packages/api-contract/src/index.ts): source ≤ 1800 s;
output ≤ 900 s. A whole track past 900 s needs a range.
A source with no audio track fails detach_source_has_no_audio. Check
probe.has_audio first with video inspect
(frames: false is enough).
Refusals (stable codes)
| Code | When |
|---|---|
audio_detach_range_empty | range.end ≤ range.start, or the range is longer than 900 s. |
detach_source_has_no_audio | Source has no audio track (worker). |
detach_start_past_source | range.start is past the probed duration (worker). |
ffmpeg_fields_rejected | Client sent af / filter / ffmpeg / cmd / codec / 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 |
Exact frame at t, source size | Video frames |
| A new MP4 cut | Video trim |
| Pixel pass (dim / crop) | Video filter |
| Many audio ranges from one track | Detach once, then timeline audio operation: "split" |
| Sequence several clips | Timeline 1.0 |