본문으로 건너뛰기

예약 & 영상 시스템

문서 정보

  • 작성일: 2026-02-27
  • 최종 업데이트: 2026-02-27
  • 버전: v1.0.0

TL;DR

사용자가 체육관 코트에서 **녹화를 예약(Recording)**하면, 카메라가 촬영한 영상이 **10분 단위 세그먼트(Video)**로 클라우드에 저장됩니다. 저장된 영상은 일정 기간 후 만료되며, 원본 4K 영상을 영구 소장하려면 카메라당 2,000캐쉬로 구매할 수 있습니다.


목차

  1. 전체 구조 한눈에 보기
  2. 녹화 예약 (Recording)
  3. 영상 (Video)
  4. 10분 세그먼트 구조
  5. 멀티카메라와 메타데이터
  6. 영상 저장소 구조
  7. 영상 만료 정책
  8. 자동 예약 vs 개별 예약
  9. 초상권 동의
  10. 영상 구매
  11. FAQ

전체 구조 한눈에 보기

스포클립의 예약 & 영상 시스템은 크게 예약 흐름영상 흐름 두 축으로 구성됩니다.

핵심 엔티티 관계

엔티티역할관계
Recording녹화 시간대 컨테이너체육관 + 코트 + 시작/종료 시간
Schedule사용자별 예약 기록Recording 1 : N Schedule
UserSchedule접근 권한 및 만료 관리Schedule 1 : N UserSchedule
Video10분 단위 영상Recording 1 : N Video

녹화 예약 (Recording)

Recording이란?

Recording은 특정 체육관의 특정 코트에서 특정 시간대에 이루어지는 녹화의 컨테이너입니다.

하나의 Recording에 여러 사용자의 예약(Schedule)이 연결될 수 있습니다. 같은 시간, 같은 코트에서 운동하는 사람들은 모두 같은 Recording을 공유합니다.

Recording의 주요 필드

필드설명예시
date녹화 날짜2026-02-27
startTime녹화 시작 시간14:00:00 (KST)
endTime녹화 종료 시간15:00:00 (KST)
gymId체육관이동국 FC
courtId코트실내 A 구장
expiresAt만료 시점녹화 종료 후 일정 시간

Recording이 생성되는 3가지 시점

동일 코트-시간대 중복 방지

같은 코트에서 같은 시작/종료 시간의 Recording은 하나만 존재합니다. 이미 있으면 기존 Recording에 연결됩니다.


영상 (Video)

Video란?

Video는 Recording 시간대 안에서 생성되는 10분 단위 영상 파일의 메타데이터입니다.

예를 들어 1시간(60분) 녹화가 진행되면, 6개의 Video 레코드가 생성됩니다.

Video의 주요 필드

필드설명예시
recordingId소속 RecordingRecording #42
gymId체육관이동국 FC
courtId코트실내 A 구장
date녹화 날짜2026-02-27
hour시(0~23)14
timeSlot10분 슬롯(0~5)0 (= xx:00~xx:09)
videoType영상 타입RAW_VIDEO
metadata카메라별 파일 정보 (JSON)videoResources[]
expiresAt영상 만료 시점2026-03-01T15:00:00Z
status상태ACTIVE

10분 세그먼트 구조

영상은 시간(hour) + 타임슬롯(timeSlot) 조합으로 정확한 10분 구간을 식별합니다.

타임슬롯 번호와 시간 매핑

timeSlot시간 범위예시 (14시 기준)
0xx:00 ~ xx:0914:00 ~ 14:09
1xx:10 ~ xx:1914:10 ~ 14:19
2xx:20 ~ xx:2914:20 ~ 14:29
3xx:30 ~ xx:3914:30 ~ 14:39
4xx:40 ~ xx:4914:40 ~ 14:49
5xx:50 ~ xx:5914:50 ~ 14:59

유니크 제약 조건

하나의 영상은 체육관 + 코트 + 날짜 + 시 + 타임슬롯 조합으로 유일하게 식별됩니다.

예: "이동국 FC / A코트 / 2026-02-27 / 14시 / 슬롯 2" = 14:20~14:29의 영상


멀티카메라와 메타데이터

하나의 코트에 여러 대의 카메라가 설치될 수 있습니다. 각 카메라가 촬영한 영상 정보는 Video의 metadata 필드에 JSON 형태로 저장됩니다.

메타데이터 구조

metadata
├── videoResources[] ← 카메라별 영상 파일 목록
│ ├── cameraInfo
│ │ ├── cameraCode ← 카메라 시리얼 번호
│ │ └── isDefault ← 기본 카메라 여부
│ ├── thumbnail ← 썸네일 URL
│ ├── duration ← 영상 길이 (초)
│ ├── stream ← Cloudflare Stream (HLS 스트리밍)
│ │ ├── videoId
│ │ ├── uploadStatus ← UPLOADING | ENCODING | READY | FAILED | DELETED
│ │ └── readyToStream
│ └── r2 ← Cloudflare R2 (원본 4K)
│ ├── bucketName
│ ├── objectKey
│ ├── uploadStatus ← UPLOADING | UPLOADED | FAILED | DELETED
│ └── size
└── totalPlayableCount ← 재생 가능한 영상 수

카메라별 영상의 의미

예를 들어, A코트에 왼쪽 카메라와 오른쪽 카메라가 설치된 경우:

카메라 코드

각 카메라는 고유한 cameraCode로 식별됩니다. 영상 구매 시 이 코드를 지정하여 특정 카메라의 영상을 구매합니다.


영상 저장소 구조

영상 파일은 Cloudflare 인프라에 이중으로 저장됩니다.

저장소용도포맷설명
Cloudflare R2원본 보관 / 다운로드4K MP4원본 해상도 영상 파일 저장
Cloudflare Stream실시간 스트리밍HLS앱에서 시청할 때 사용

영상 처리 파이프라인

레거시 저장소

기존에는 Mux(스트리밍)와 BunnyNet(원본 보관)을 사용했으나, 현재 Cloudflare로 마이그레이션 완료 상태입니다. 기존 메타데이터에 mux, bunnyNet 필드가 남아 있을 수 있습니다.


영상 만료 정책

영상과 관련 접근 권한은 시간이 지나면 만료됩니다.

만료 시간 정리

대상만료 기준기본값
UserSchedule.expiresAt녹화 종료 + maxRetentionHours (환경변수)종료 후 48시간
UserSchedule.accessibleUntil녹화 종료 + Feature Policy SCHEDULE_ACCESS_DURATION.accessHoursFREE: 24시간, PLUS/PRO: 48시간
Video.expiresAt영상 파일 만료 시점시스템 설정에 따름
PLUS 멤버십 혜택

PLUS 패스 사용자는 기본 패스보다 더 오래 영상에 접근할 수 있습니다. 기본 패스는 24시간, PLUS는 48시간입니다.


자동 예약 vs 개별 예약

스케줄(Schedule)에는 두 가지 타입이 있습니다.

구분AUTO_SCHEDULED (자동 예약)INDIVIDUAL (개별 예약)
생성 주체체육관 업주 / 새벽 스케줄러사용자 본인 (QR 스캔 등)
생성 시점새벽에 일괄 생성사용자가 예약 요청 시
초상권 동의항상 true (자동 처리)사용자가 명시적으로 동의 필수
triggeredAtnull (자동이므로 요청 시점 없음)사용자가 버튼을 누른 시점 기록
사용 사례정기 수업, 팀 훈련개인 운동, 자유 이용

하나의 Recording에 두 타입이 공존

같은 시간대에 자동 예약과 개별 예약이 함께 존재할 수 있습니다.


초상권 동의

하나의 Recording에 여러 사용자가 참여할 수 있으므로, 자신의 모습이 다른 예약자에게 보여질 수 있습니다. 이에 따라 **초상권 동의(portraitRightsConsent)**가 필수입니다.

동의 규칙

예약 타입동의 방식동의 시점 기록
INDIVIDUAL사용자가 예약 시 명시적으로 동의createdAt (예약 생성 시점)
AUTO_SCHEDULED자동으로 true 처리createdAt (예약 생성 시점)
동의 없이 예약 불가

개별 예약(INDIVIDUAL)에서 portraitRightsConsent: false로 요청하면 예약이 거부됩니다.


영상 구매

사용자는 앱에서 영상을 스트리밍으로 시청할 수 있지만, 원본 4K 영상을 영구 소장하려면 구매가 필요합니다. 1회 구매당 10회 다운로드 사이클이 제공되며, 구매 즉시 다운로드 URL이 반환됩니다.

구매 개요

항목내용
가격10분 세그먼트당 2,000캐쉬 (고정)
단위비디오 + 카메라 조합 (카메라별 별도 구매)
다운로드 횟수1회 결제당 10회 (무기한)
사이클 소진동일 비용으로 재결제 → 새 10회 사이클
결제 수단캐쉬 (Grain) 차감

구매 API

API설명
POST /videos/:videoUuid/purchase구매 + 다운로드 URL 즉시 반환
GET /videos/:videoUuid/purchase-status구매 상태 + 사이클 정보 조회
GET /.../videos/:videoUuid/download-url다운로드 URL 요청 (횟수 차감)
GET /videos/:videoUuid/download-history다운로드 이력 조회

구매 흐름

구매 상태 확인

구매 여부와 다운로드 사이클 정보를 함께 반환합니다.

GET /videos/:videoUuid/purchase-status?cameraCode=CAM001

Response:
{
purchased: true, // 구매 여부
downloadCount: 3, // 현재 다운로드 횟수
maxDownloads: 10, // 최대 다운로드 횟수
remainingDownloads: 7, // 남은 다운로드 횟수
canDownload: true // 다운로드 가능 여부
}

다운로드 사이클 정책

상황결과
Video A + 왼쪽 카메라 첫 구매2,000캐쉬 차감 + 10회 사이클 시작
Video A + 왼쪽 카메라 재다운로드무료 (횟수만 차감, 남은 횟수 내)
Video A + 왼쪽 카메라 10회 소진 후2,000캐쉬 재결제 → 새 10회 사이클
Video A + 오른쪽 카메라 첫 구매2,000캐쉬 차감 (별도 사이클)
다운로드 이력 조회

GET /videos/:videoUuid/download-history?cameraCode=xxx로 현재 사이클 정보, 다운로드 이력, 이전 사이클 목록을 조회할 수 있습니다.


FAQ

Q: Recording과 Video의 차이가 뭔가요?

Recording은 녹화 시간대 전체(예: 14:0015:00)를 나타내는 컨테이너이고, Video는 그 안의 10분짜리 영상 파일 하나(예: 14:2014:30)입니다. 1시간 Recording에는 6개의 Video가 포함됩니다.

Q: 왜 10분 단위로 나누나요?

긴 영상을 한 파일로 관리하면 업로드 실패 시 전체를 다시 올려야 하고, 사용자가 원하는 구간을 찾기 어렵습니다. 10분 단위로 나누면 업로드 안정성과 탐색 편의성이 모두 향상됩니다.

Q: 카메라가 2대인 경우 구매 비용은?

카메라별로 별도 구매입니다. 2대 모두 구매하면 2,000캐쉬 x 2 = 4,000캐쉬이며, 각각 10회 다운로드 사이클이 생성됩니다.

Q: 한번 구매한 영상을 다시 구매하면?

다운로드 횟수가 남아있으면(10회 미만) 캐쉬 차감 없이 다운로드 URL이 반환됩니다. 10회를 모두 소진한 경우에는 2,000캐쉬를 재결제하여 새 10회 사이클이 시작됩니다.

Q: 영상 만료 후에도 구매할 수 있나요?

영상(Video) 자체가 삭제되지 않았다면 구매는 가능합니다. 단, UserSchedule의 접근 권한이 만료되면 해당 영상을 앱에서 볼 수 없게 됩니다.

Q: 자동 예약과 개별 예약의 영상 품질 차이가 있나요?

없습니다. 같은 Recording을 공유하므로 동일한 카메라, 동일한 영상 파일을 봅니다. 예약 타입은 누가 어떻게 예약했는지만 구분합니다.

Q: 초상권 동의는 언제 필요한가요?

개별 예약(INDIVIDUAL)으로 예약할 때마다 매번 동의가 필요합니다. 같은 시간대에 다른 사용자도 촬영되므로, 자신의 모습이 공유될 수 있음을 인지하고 동의해야 합니다.

Q: 예약 없이 영상만 올라올 수 있나요?

네. 카메라 시스템이 자동으로 업로드하는 경우, 예약 없이 Recording이 생성되고 영상이 저장됩니다. 이런 "고아(orphan)" 영상은 일반 사용자에게 노출되지 않지만, 관리자 도구로 확인할 수 있습니다.


관련 문서


변경 이력

버전날짜변경 내용
v1.0.02026-02-27초기 문서 작성
- Recording/Video 핵심 개념 정의
- 10분 세그먼트 구조 설명
- 멀티카메라 메타데이터 구조
- Cloudflare R2/Stream 저장소 구조
- 영상 만료 정책
- 자동 예약(AUTO_SCHEDULED) vs 개별 예약(INDIVIDUAL)
- 초상권 동의 규칙
- 영상 구매 흐름 (2,000캐쉬, 무료 재다운로드)
- FAQ 작성