비디오 필터
이 문서는 영문 원고를 AI로 번역한 내용이라 표현이 어색할 수 있습니다.
현재 SoT. Media L2 픽셀 패스(
sume/video-filter-1.0, #5820 / #5839). dest와 prod. 구간 컷이 아닙니다 — 그건 비디오 트림입니다. 조립이 아닙니다 — 시퀀스, 전환, 오디오 스파인은 Timeline 1.0에 남습니다.
Video filter 1.0은 하나의 워크스페이스 media.sume.com 클립과
검증된 프로그램(ops[] dim/crop 및/또는 필터만 있는 filtergraph)을
받아 새 MP4를 반환합니다. 소스는 그대로입니다. 서버가 워커 미디어
런타임에서 ffmpeg를 컴파일합니다(apps/api/src/routes.ts
createVideoFilterV1 / submitSumeVideoFilterJob;
packages/timeline-compiler/src/filter.ts compileVideoFilterProgram).
GET /v1/video-filter/:id는 없습니다. Job 봉투로 폴링하세요:
호스트 MCP: video_filter(packages/mcp-server/src/mcp.ts). 쓰기는
idempotency_key(OAuth에서는 mcp:write)가 필요합니다. 흐름:
check_only: true인 video_filter(무료) → video_filter →
jobs_wait → jobs_result.
프로그램 검사(무료)
POST /v1/video-filter/check는 인코드와 같은 스키마, op 화이트리스트,
filtergraph 허용 목록, Sume 호스트 / HEAD 소스 프리플라이트를 돌리고
400 대신 diagnostics를 반환합니다. Job을 만들지 않고, 크레딧을
예약하지 않고, 박스를 켜지 않고, 인코더를 건드리지 않습니다. 여기를
통과한 프로그램도 박스에서 실패할 수 있습니다(나쁜 식, 메모리, 시간)
— 그건 구조화된 job 오류입니다.
체크에는 Idempotency-Key가 필요 없습니다. 유효한 응답은
object: video_filter_check이며 valid, encode: "not_run",
diagnostics[], 컴파일된 program.filters(이름만, argv 없음), 유효할
때의 estimate, next_action
submit_video_filter | fix_program_and_recheck를 담습니다.
인코드
필수: video_url(이 워크스페이스의 media.sume.com 아티팩트 또는
에셋) 그리고 프로그램 — ops[] 또는 비어 있지 않은 filtergraph
중 최소 하나. 오픈 인터넷 fetch는 없습니다. 먼저 가져오세요
(POST /v1/media-imports). Idempotency-Key가 필요합니다.
선택: ops, filtergraph, metadata, 그리고 일반적인 mode /
webhook_url / wait_timeout_seconds 통신 필드.
기본 mode는 **async**입니다. mode: "sync"를 보내면 최대 30초
기다린 뒤 끝난 job은 200, 아니면 202로 폴링합니다.
성공한 제출은 job을 반환합니다(request_id가 job id). result_ready일
때 GET /v1/jobs/:id/result는 kind: video_filter이며 video_url(새
artf_, 소스가 아님), duration_seconds, ops_applied,
filtergraph, 컴파일된 filters[], 선택적 warnings[]를 담습니다. 그
MP4를 timeline_create video[]에 넣으세요.
공개 요금: 인코드 job당 $0.02(VIDEO_FILTER_PUBLIC_PRICING; 라이브는
GET /v1/catalog). 체크는 무료입니다. 프로바이더 추론 없음 — 워커
ffmpeg만.
프로그램
| 필드 | 효과 |
|---|---|
ops[] | 순서 있는 프로그램. filtergraph 앞에 적용. 최대 8. op 하나 또는 filtergraph가 필요합니다. |
ops[].op: "dim" | 클립 전체 루마 곱. amount는 (0, 1] — 0.45는 더 어둡고, 1은 그대로. 0과 >1은 거절. 검은색은 검은색, 채도는 안 바뀝니다. |
ops[].op: "crop" | 소스 프레임의 비율: x, y는 [0, 1]; width, height는 [0.05, 1]; x+width ≤ 1, y+height ≤ 1. 컴파일러가 yuv420p용으로 짝수 반올림합니다. |
filtergraph | ops[] 뒤에 적용되는 필터만 있는 ffmpeg 그래프. 최대 2048자, 이름 있는 필터 32. 입력/출력/경로 없음 — 서버가 [0:v]…[vout]로 감쌉니다. 내부 라벨(split[a][b])은 되고 스트림 지정자([0:v])는 안 됩니다. |
상한(packages/api-contract/src/index.ts): 소스 ≤ 300초(compose
밴드 클립 천장). 프로그램이 바꾸지 않으면 출력은 소스의 기하, 프레임
레이트, 오디오를 상속합니다.
허용 필터 이름은
packages/timeline-compiler/src/filter.ts
VIDEO_FILTER_GRAPH_ALLOWED_FILTERS(톤, 블러, 기하, fade, 내부
합성)입니다. 목록에 없는 것: trim / setpts(비디오
트림을 쓰세요), drawtext / subtitles /
movie / lut3d, 파일이나 소켓을 읽는 모든 필터.
거절(안정 코드)
| 코드 | 언제 |
|---|---|
video_filter_ops_empty | ops[]도 비어 있지 않은 filtergraph도 없음. |
video_filter_too_many_ops | op가 8개 초과. |
unsupported_filter_op | ops[].op가 dim / crop이 아님. 다른 픽셀 작업은 filtergraph. |
unsupported_filter_op_field | op에 여분 키(dim은 {op, amount}만, crop은 {op, x, y, width, height}). |
video_filter_amount_out_of_range | dim amount가 (0, 1]이 아님. |
video_filter_crop_out_of_bounds | crop 비율이 소스 프레임을 벗어나거나 한 변이 0.05 미만. |
invalid_filtergraph | 비어 있음, 너무 김, 알 수 없는 필터, 잘못된 알파벳, 또는 스트림 지정자. unknown_filter는 토큰과 허용 목록을 이름합니다. |
ffmpeg_fields_rejected | 클라이언트가 vf / filter / ffmpeg / cmd / codec / crf / -i 등을 보냄. 서버가 ffmpeg를 컴파일합니다. |
unsupported_media_source | video_url이 Sume 미디어 호스트가 아님. |
source_not_found | 죽은 또는 다른 워크스페이스의 media.sume.com URL. |
unsupported_media_type | HEAD가 비디오가 아님. |
source_too_large | 소스가 타임라인 다운로드 예산을 초과. |
output_duration_exceeded | 소스가 300초보다 김(워커). |
호스트 밖 URL(https://example.com/…)은 접수에서 거절됩니다. 먼저
가져오세요.
이 표면이 아닌 것
| 필요한 일 | 쓸 것 |
|---|---|
| 프로브 / 스틸 / 선택적 STT | 비디오 검사 |
| 새 MP4 컷 | 비디오 트림 |
| 오디오 트랙을 내구성 wav / mp3로 | 오디오 분리 |
| 여러 클립 시퀀스 | Timeline 1.0 |
| 캡션 플레이트 | HyperFrames compose / 캡션 어셈블러 |
t의 소스 크기 프레임 | 비디오 프레임 |

