본문으로 건너뛰기

라이브 스트림

라이브 모니터링은 HLS 스트림에서 SSAI 광고 브레이크를 감시합니다. 서비스는 poll_interval_s 간격으로 매니페스트를 폴링하고, 새 광고 경계를 감지할 때마다 버스트(burst) 를 만듭니다. 버스트는 광고 브레이크 직전에 재생된 콘텐츠 세그먼트 segment_n개의 분석 결과입니다. 버스트마다 세그먼트별 장면(캡션, 트랜스크립트, 분위기, 브랜드, GARM 카테고리)과 버스트 단위 집계(요약, 장르, IAB 카테고리, GARM 평가)가 담깁니다.

노트

모든 예시는 https://video.pyler.ai와 $VUF_API_KEY에 담긴 API 키를 사용합니다. 인증을 참고하세요.

스트림 등록​

POST /api/v1/live/streams로 HLS 매니페스트 URL(마스터 또는 미디어 플레이리스트)을 등록합니다. 등록 시 매니페스트를 검증합니다. 접근할 수 없거나 유효하지 않은 플레이리스트는 422를, 이미 등록된 URL은 409를 반환합니다.

urlstringbodyrequired

HLS 매니페스트 URL입니다. 예: https://example.com/live/stream.m3u8

segment_nintegerbodydefault: 8

버스트마다 수집할, 광고 브레이크 직전 콘텐츠 세그먼트 수입니다. 분석 구간을 결정합니다. 1–60.

poll_interval_sintegerbodydefault: 6

매니페스트 폴링 간격(초)입니다. 1–3600.

curl -X POST https://video.pyler.ai/api/v1/live/streams \
-H "Authorization: Bearer $VUF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/live/stream.m3u8", "segment_n": 8, "poll_interval_s": 6}'
Response (201)
{
"id": "b7e2c4d6-1f3a-4b5c-9d8e-0a1b2c3d4e5f",
"url": "https://example.com/live/stream.m3u8",
"segment_n": 8,
"aggregate": true,
"status": "active",
"poll_interval_s": 6,
"namespace": null,
"org_id": "org_...",
"segments_seen": 0,
"error": null,
"created_at": "2026-10-20T09:00:00Z",
"updated_at": "2026-10-20T09:00:00Z"
}

스트림 레코드(LiveStreamOut):

statusstring

현재 상태입니다. active, paused, stopped, error 중 하나입니다.

segments_seeninteger | null

생성 이후 관찰한 미디어 세그먼트의 총수입니다.

errorstring | null

마지막 오류 메시지입니다. status가 error일 때 채워집니다.

namespacestring | null

스트림 목록을 조회할 때 namespace 필터로 사용할 수 있습니다.

레코드에는 url, segment_n, poll_interval_s, aggregate, org_id, created_at, updated_at도 포함됩니다.

목록 조회, 조회, 수정, 삭제​

호출동작레퍼런스
GET /api/v1/live/streams조직에 등록된 스트림을 스트림 레코드 배열로 반환합니다. ?namespace= 필터는 선택입니다.라이브 스트림 목록 조회
GET /api/v1/live/streams/{stream_id}id로 스트림 하나를 조회합니다. 없으면 404입니다.라이브 스트림 조회
PATCH /api/v1/live/streams/{stream_id}설정 일부를 수정하거나 상태를 전환합니다.라이브 스트림 수정
DELETE /api/v1/live/streams/{stream_id}모니터링을 멈추고 스트림을 삭제합니다. 204, 본문 없음.라이브 스트림 삭제

PATCH 본문에는 다음 필드 중 원하는 것만 넣을 수 있습니다.

urlstringbody

새 HLS 매니페스트 URL입니다. 변경하면 새 매니페스트를 동기적으로 검증합니다. 접근할 수 없거나 유효하지 않은 플레이리스트는 422를 반환합니다.

segment_nintegerbody

1–60.

poll_interval_sintegerbody

1–3600.

statusstringbody

active는 폴링을 재개하고, paused는 상태를 유지한 채 폴링을 멈추며, stopped는 스트림을 종료합니다.

# Pause
curl -X PATCH https://video.pyler.ai/api/v1/live/streams/$STREAM_ID \
-H "Authorization: Bearer $VUF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "paused"}'

# Resume with a wider analysis window
curl -X PATCH https://video.pyler.ai/api/v1/live/streams/$STREAM_ID \
-H "Authorization: Bearer $VUF_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "active", "segment_n": 12}'

# Delete
curl -X DELETE https://video.pyler.ai/api/v1/live/streams/$STREAM_ID \
-H "Authorization: Bearer $VUF_API_KEY"
경고

스트림을 삭제하면 해당 스트림의 버스트와 장면도 모두 영구 삭제됩니다(cascade). 필요한 데이터는 먼저 조회해 두세요.

버스트​

버스트(LiveBurstOut)는 광고 브레이크 하나 직전에 수집한 콘텐츠의 분석 결과입니다.

Burst (truncated)
{
"id": "c1d2e3f4-5a6b-4c7d-8e9f-0a1b2c3d4e5f",
"stream_id": "b7e2c4d6-1f3a-4b5c-9d8e-0a1b2c3d4e5f",
"boundary_sequence": 1842,
"break_detected_at": "2026-10-20T09:14:02Z",
"completed_at": "2026-10-20T09:14:21Z",
"status": "done",
"segment_count": 8,
"wall_ms": 18700,
"summary": "A studio panel discusses the evening's match before the break.",
"genre": ["sports"],
"iab_content_leaf": ["Sports"],
"iab_audience_interest_leaf": [],
"iab_audience_purchase_intent_leaf": [],
"iab_ad_product_leaf": [],
"garm_video": [],
"error": null,
"created_at": "2026-10-20T09:14:02Z",
"updated_at": "2026-10-20T09:14:21Z",
"scenes": [
{
"id": "d4e5f6a7-8b9c-4d0e-9f1a-2b3c4d5e6f70",
"segment_index": 0,
"segment_url": "https://example.com/live/seg1835.ts",
"duration_ms": 6000,
"caption": "Three presenters at a desk in front of a stadium backdrop.",
"transcript": "...and that brings us to tonight's line-up.",
"text_on_screen": ["LIVE"],
"valence": 3,
"arousal": 3,
"music_mood": null,
"audio_events": ["speech"],
"garm_categories": [],
"garm_reasoning": [],
"brands": [],
"product_categories_visible": [],
"people": [],
"locations": ["studio"],
"action": ["talking"],
"human_activity": ["presenting"],
"weather": null,
"download_ms": 240,
"caption_ms": 1900,
"status": "done",
"error": null
}
]
}
statusstring

버스트 상태입니다. pending, running, done, failed 중 하나입니다.

break_detected_at / completed_atdate-time

경계를 감지한 시각과 처리를 마친 시각입니다. 처리가 끝나기 전까지 completed_at은 null입니다.

wall_msinteger | null

전체 처리에 걸린 실제 시간(밀리초)입니다.

summarystring | null

AI가 생성한 버스트 콘텐츠의 한 줄 요약입니다.

garm_videoGarmEntry[]

버스트의 GARM 브랜드 세이프티 평가입니다. category, level(high / medium / low), reasoning, time_ranges로 구성됩니다.

scenesLiveSceneOut[]

분석한 세그먼트 하나당 항목 하나입니다. segment_index, segment_url, duration_ms, caption, transcript, text_on_screen, valence, arousal, music_mood, audio_events, garm_categories, garm_reasoning, brands, product_categories_visible, people, locations, action, human_activity, weather, download_ms, caption_ms, status, error를 포함합니다.

버스트에는 id, stream_id, boundary_sequence, segment_count, genre, IAB leaf 목록, error, created_at, updated_at도 포함됩니다.

스트림 단위 버스트 엔드포인트​

호출동작레퍼런스
GET /api/v1/live/streams/{stream_id}/bursts스트림의 모든 버스트를 최신순으로, 장면과 함께 반환합니다. ?since=(ISO 8601 date-time)를 지정하면 그 이후에 생성된 버스트만 반환합니다.버스트 목록 조회
GET /api/v1/live/streams/{stream_id}/bursts/latest가장 최근에 완료된 버스트를 반환합니다. 아직 완료된 버스트가 없으면 404입니다.최신 버스트
GET /api/v1/live/streams/{stream_id}/bursts/{burst_id}스트림 안의 버스트 하나를 반환합니다. 이 스트림에 속하지 않거나 존재하지 않으면 404입니다.버스트 조회

계정 단위 버스트 엔드포인트​

호출동작레퍼런스
GET /api/v1/live/bursts/latest조직의 모든 스트림에서 가장 최근에 생성된 버스트를 배열로 반환합니다. ?since=(ISO 8601 date-time)로 생성 시각을 필터링합니다.최신 버스트 목록
GET /api/v1/live/bursts/{burst_id}어느 스트림에서 생성됐는지와 관계없이 id로 버스트를 조회합니다.id로 버스트 조회
# Latest completed burst for one stream
curl -s https://video.pyler.ai/api/v1/live/streams/$STREAM_ID/bursts/latest \
-H "Authorization: Bearer $VUF_API_KEY"

# Bursts created since a point in time, across all of your streams
curl -s "https://video.pyler.ai/api/v1/live/bursts/latest?since=2026-10-20T09:00:00Z" \
-H "Authorization: Bearer $VUF_API_KEY"

이벤트​

GET /api/v1/live/streams/{stream_id}/events는 오래 유지되는 application/x-ndjson 스트림으로, 한 줄에 JSON 객체 하나씩 스트림 하나의 실시간 이벤트를 전달합니다. 응답 전체를 버퍼링하지 않는 클라이언트로 읽으세요. 각 줄에는 event 필드가 있습니다.

event의미
watching현재 스트림 상태 스냅숏입니다.
break_detected새 광고 경계를 감지했습니다.
scene세그먼트 분석이 끝났습니다.
aggregate버스트 집계가 갱신됐습니다.
burst_done버스트 처리가 끝났습니다.
keepalive유휴 상태 하트비트입니다. 무시하세요.

스트림이 stopped로 전환되거나 삭제되면 연결이 닫힙니다.

curl -N https://video.pyler.ai/api/v1/live/streams/$STREAM_ID/events \
-H "Authorization: Bearer $VUF_API_KEY"
팁

이벤트는 무언가가 언제 일어났는지 알려 주고, 데이터는 버스트에 있습니다. burst_done을 받으면 GET /api/v1/live/streams/{stream_id}/bursts/latest 또는 GET /api/v1/live/bursts/{burst_id}로 버스트를 조회하세요.

오류​

상태 코드발생 조건
404알 수 없는 stream_id 또는 burst_id, 버스트가 속하지 않은 스트림 경로로 요청한 경우, 완료된 버스트가 없는데 bursts/latest를 호출한 경우입니다.
409이미 등록된 URL로 POST /api/v1/live/streams를 호출한 경우입니다.
422본문 검증에 실패했거나, 매니페스트 URL(생성 시 또는 새 url로 PATCH 시)에 접근할 수 없거나 유효한 플레이리스트가 아닌 경우입니다.

모든 오류 본문은 오류에서 설명하는 공통 형식을 따릅니다.

다음 단계​