본문으로 건너뛰기

업로드 흐름

체육관 로컬 PC가 카메라 영상을 Cloudflare R2에 업로드하는 과정

문서 정보

  • 작성일: 2026-03-02
  • 최종 업데이트: 2026-03-02
  • 버전: v1.0.0
  • 관련 코드: src/modules/cloudflare/raw-video-webhook/domain/

개요

체육관에 설치된 로컬 PC는 코트 카메라의 영상을 10분 단위 세그먼트로 분할하여 해당 체육관의 Cloudflare R2 버킷에 직접 업로드합니다. Spoclip 서버를 경유하지 않습니다.


R2 객체 구조

버킷

모든 체육관은 동일한 이름의 R2 버킷(raw-videos)을 사용합니다. 체육관마다 별도의 CF 계정을 가지므로 버킷 이름이 같아도 충돌하지 않습니다.

객체 키 형식

{courtCode}/{date}/{hour}/{timeSlot}/{cameraCode}.mp4
세그먼트설명예시
courtCode코트 식별자COURT-A
date촬영 날짜 (YYYY-MM-DD)2026-03-01
hour시간 (0-23)14
timeSlot10분 구간 (0-5)3
cameraCode카메라 식별자CAM-FRONT

예시: COURT-A/2026-03-01/14/3/CAM-FRONT.mp4 = COURT-A의 2026년 3월 1일 14:30~14:40 전면 카메라 영상

TimeSlot 매핑

하나의 시간(hour)은 6개의 10분 구간으로 나뉩니다.

timeSlot시간 범위
0XX:00 ~ XX:10
1XX:10 ~ XX:20
2XX:20 ~ XX:30
3XX:30 ~ XX:40
4XX:40 ~ XX:50
5XX:50 ~ XX+1:00

Passthrough 메타데이터

R2 객체에 포함되는 메타데이터로, 이후 webhook 처리 시 영상의 출처를 식별하는 데 사용됩니다.

{
"source": "R2",
"type": "RAW_VIDEO",
"gymCode": "GYM-001",
"courtCode": "COURT-A",
"cameraCode": "CAM-FRONT",
"date": "2026-03-01",
"hour": 14,
"timeSlot": 3
}

서버에서는 PassthroughVO (Zod 스키마 기반)로 유효성을 검증합니다.

관련 코드: src/modules/cloudflare/raw-video-webhook/domain/value-objects/passthrough.vo.ts


멀티카메라

하나의 코트에 여러 카메라가 설치될 수 있습니다. 동일한 시간대(date + hour + timeSlot)에 카메라별로 별도의 R2 객체가 업로드됩니다.

COURT-A/2026-03-01/14/3/CAM-FRONT.mp4   ← 전면 카메라
COURT-A/2026-03-01/14/3/CAM-SIDE.mp4 ← 측면 카메라

하나의 Video 엔티티가 여러 카메라의 영상을 metadata.videoResources[] 배열로 관리합니다. 각 카메라의 R2/Stream 상태가 독립적으로 추적됩니다.


체육관 CF 계정 크레덴셜

로컬 PC가 R2에 업로드할 때 사용하는 크레덴셜은 체육관별 CF 계정에서 발급됩니다. 서버가 이 크레덴셜을 관리하지 않으며, 로컬 PC에 직접 설정되어 있습니다.

서버가 관리하는 크레덴셜(gym_media_configs)은 webhook 검증과 presigned URL 생성에 사용됩니다. 자세한 내용은 Webhook 처리를 참고하세요.


변경 이력

버전날짜변경 내용
v1.0.02026-03-02초기 문서 작성
- R2 객체 구조 및 키 형식
- Passthrough 메타데이터 명세
- 멀티카메라 구조 설명
- TimeSlot 매핑 테이블