본문으로 건너뛰기

업로드 흐름

체육관 로컬 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 매핑 테이블