Timeline 1.0
이 문서는 영문 원고를 AI로 번역한 내용이라 표현이 어색할 수 있습니다.
현재 SoT. Timeline 1.0 렌더(
sume/timeline-1.0). dest와 prod. 이것은 조립입니다 — 시퀀스, 트랜지션, 오디오 스파인. 소재 준비는 비디오 트림, 오디오 분리, 비디오 필터, 타임라인 합성에 남습니다.
Timeline 1.0은 선언적 문서(오디오 스파인 하나 + 순서 있는 video[])를
받아 하나의 MP4를 반환합니다. 서버가 워커 미디어 런타임에서
ffmpeg를 컴파일합니다(apps/api/src/routes.ts renderTimelineV1 /
submitSumeTimelineRenderJob). 호출자는 필터그래프, 코덱, 셸 조각을
보내지 않습니다.
GET /v1/timeline-1.0/:id는 없습니다. Job 봉투로 폴링하세요:
호스티드 MCP: timeline_create → jobs_wait → timeline_get
(packages/mcp-server/src/mcp.ts). timeline_get은
GET /v1/jobs/:id/result입니다. 쓰기는 idempotency_key가
필요합니다(OAuth에서는 mcp:write).
Plan (무료)
POST /v1/timeline-1.0/plan(planTimelineV1)은 스키마 + Sume 호스트
URL 검사 + 순수 컴파일러를 돌리고 object: timeline_plan에
duration_seconds, segment_count, billable_minutes,
estimated_cost_usd_micros, filtergraph_summary를 돌려줍니다. Job을
만들지 않고, 크레딧을 예약하지 않으며, 미디어를 다운로드하지 않습니다.
Idempotency-Key는 필요 없습니다. Plan은 짧은 소스 pad/loop 경고를
예측하지 않습니다.
렌더
필수: audio.duration_seconds(1–1800)와 audio.url 또는
audio.parts[](audio.mode가 "silence"가 아니면), 그리고 video[]
(1–200 슬롯). 모든 URL은 이 워크스페이스의 media.sume.com
아티팩트 또는 에셋이어야 합니다. 먼저 가져오세요
(POST /v1/media-imports). Idempotency-Key는 필수입니다.
기본 mode는 **async**입니다. mode: "sync"를 주면 최대 30초
기다리고 끝난 Job을 200으로 주거나, 202로 폴링합니다.
성공한 submit은 Job을 반환합니다(type: timeline_render,
model: sume/timeline-1.0). result_ready이면
GET /v1/jobs/:id/result는 kind: timeline_render이고 video_url,
duration_seconds, segment_count, billable_minutes, 선택적
warnings[]를 줍니다. 짧은 소스 pad/loop, 스냅된 트랜지션, 무시된
스틸 모션 같은 소프트 경고는 실패가 아닙니다.
공개 요금: 출력 분(ceil)당 $0.10(TIMELINE_PUBLIC_PRICING;
GET /v1/catalog에서 확인). 예약은
ceil(audio.duration_seconds / 60)분입니다. 프로바이더 추론 없음 —
워커 ffmpeg만.
기본 출력은 1080×1920 MP4입니다. output.fps를 생략하면 소스가
이미 쓰는 프레임레이트로 렌더합니다(가장 긴 비디오 소스가 결정, 스틸은
레이트가 없음, 아무것도 없을 때만 30). 소스와 다른 레이트는 몇 프레임마다
한 프레임을 반복하거나 버려서 — 움직임에서 떨림(judder) — 소스가 원한
레이트와 함께 output_fps_resamples_sources로 보고됩니다.
프로그램
| 필드 | 효과 |
|---|---|
audio.duration_seconds | 출력 길이. 필수. 1–1800초. |
audio.url | Sume 호스트 스파인 하나. parts와 배타. |
audio.parts[] | ≤20개의 갭리스 조각(url + 선택 source_in / duration). 샘플 도메인 조인, 재 TTS 없음. url과 배타. |
audio.mode | "silence" — 스파인 파일 없이 선언된 길이. 그때는 url / parts / gain_db / source_in 없음. |
audio.source_in | 단일 url 스파인의 인포인트. parts와 함께 쓰면 거부. 출력 길이는 여전히 duration_seconds. |
audio.gain_db | −60…12. silence와 함께 쓰면 거부. |
video[].source_url | Sume 호스트 클립 또는 스틸. 스틸은 정적 홀드(motion은 받고 motion_ignored로 무시). |
video[].start | 스파인 위 시작. video[0].start는 0. 이후 start는 증가해야 함. 선언된 start가 권위 — 컴파일러가 xfade를 보정하고 미리 당기지 않음. |
video[].duration | 화면 길이, ≥ 0.2초. 커버리지는 스파인보다 최대 0.5초 뒤일 수 있음. |
video[].source_in | 파일 인포인트. |
video[].fit | cover(기본) | contain | stretch | blur. |
video[].transition | 첫 슬롯 이후. type ∈ fade | wipeleft | wiperight | slideup | slidedown | dissolve. 길이 ≤ 1초, 더 짧은 이웃의 50% 이하, 출력 프레임 최소 1장. |
output.width / height | 짝수 정수 256–2160. |
output.fps | 24 | 25 | 30 | 60. 생략하면 소스에 맞춤. |
output.fade_in_seconds / fade_out_seconds | 0–5초; 합 ≤ 출력 길이. |
soundtrack | 선택 배드: url, gain_db, loop, fade_out_seconds ≤ 10, duck_db 0–20(진짜 스파인 필요, silence 불가). |
render.strategy | auto(기본; 12슬롯 넘으면 청크) | chunked | single(12슬롯 초과는 render_strategy_unsafe). |
이 렌더 안에서만 필요한 잘린 VO는 audio.parts[]에 둡니다.
재사용 가능한 병합 파일은 타임라인 오디오입니다.
한 프레임에 소스 두 개가 동시에 필요하면
타임라인 합성 후 그 MP4를 video[]에 넣습니다.
거부 (안정 코드)
| 코드 | 언제 |
|---|---|
audio_url_required | url / parts 없고 silence도 아님. |
audio_url_and_parts_exclusive | url과 parts를 같이 보냄. |
silent_audio_takes_no_url / _parts / _gain / _source_in | silence에 스파인 필드. |
audio_source_in_requires_single_spine | parts와 함께 source_in. |
audio_parts_shorter_than_duration | 선언된 part 길이 합이 duration_seconds보다 짧음. |
timeline_must_start_at_zero | video[0].start ≠ 0. |
transition_on_first_segment | video[0].transition. |
invalid_segment_timing / segment_overlap | start가 증가하지 않거나 xfade를 넘어 겹침. |
transition_too_long / transition_not_frame_aligned | 이웃 / fps 대비 길이. |
too_many_chained_transitions | 인접 페이드 8개 초과. 하드 컷을 넣으세요. |
edge_fades_exceed_output / soundtrack_fade_exceeds_output | 페이드가 스파인보다 김. |
duck_requires_audio_spine | silence에 soundtrack.duck_db. |
render_strategy_unsafe | 슬롯 12개 초과에 strategy: "single". |
unsupported_media_source / source_not_found | 호스트 밖 또는 죽은 URL. |
| 프로바이더 / ffmpeg 키 | 400 — model, filtergraph, ffmpeg_args, codec, crf 등 (TIMELINE_REJECTED_PROVIDER_KEYS). |
호스트 밖 URL(https://example.com/…)은 admit에서 거부됩니다. 먼저
가져오세요.
dim / crop / 픽셀 패스는 렌더 옵션이 아닙니다 — 비디오 필터를 쓰세요.
이 표면이 아닌 것
| 필요 | 사용 |
|---|---|
클립 하나의 [start, end) | 비디오 트림 |
| 오디오 트랙을 내구성 wav / mp3로 | 오디오 분리 |
| 오디오 concat / split로 재사용 파일 | 타임라인 오디오 |
| 한 프레임에 스틸 + 비디오 (반배너) | 타임라인 합성 |
| 픽셀 패스 (dim / crop) | 비디오 필터 |
| 프로브 / 스틸 / 선택 STT | 비디오 검사 |

