무엇을 만들었나요?
Video Chain Player를 만들었습니다. 비디오의 필요한 구간만 연결해 하나의 경험으로 재생/공유할 수 있는 웹 앱입니다.
🔗 지금 써보기: https://video-chain-player.sloth255.com/
- 시작/종료 시간을 지정해 비디오를 클립 처리
- 여러 클립을 체인(큐) 으로 연결해 연속 재생
- 체인 상태를 URL로 인코딩해 링크 하나로 공유
워크아웃 플로우, 강의 하이라이트, 컴필레이션 릴 같이 "이 부분만 보여주기" 경험을 만들기에 딱입니다.
사용자가 할 수 있는 것
- 클립 만들기: URL/ID와 시작/종료 시간을 입력해 비디오 추가
- 순서 변경: 드래그 앤 드롭으로 순서 조정
- 미리보기: 즉석에서 재생해 타이밍 확인
- 공유: URL 복사해서 전송 (수신자가 같은 체인을 열게 됨)
- 다국어: URL로 언어 전환 (예:
?lang=ja)
기술 스택
| 영역 | 기술 | 비고 |
|---|---|---|
| 프론트엔드 | React 18 + TypeScript | UI 유지보수성 및 타입 안전성 |
| 빌드/개발 서버 | Vite | 빠른 HMR, 좋은 DX |
| 라우팅 | React Router v6 | 경로 + 쿼리로 상태 표현 |
| 상태 관리 | Zustand | 경량, URL 동기화에 적합 |
| 드래그 앤 드롭 UI | @dnd-kit | 순서 변경 구현 |
| 비디오 플레이어 | react-youtube (IFrame Player API) | 빠른 임베드 재생 |
| i18n | i18next + react-i18next | 모든 UI 문자열 번역 |
| 번역 로딩 | i18next-http-backend | /public/locales/...에서 런타임 페치 |
| 언어 감지 | i18next-browser-languagedetector | 우선순위: ?lang= / localStorage / 브라우저 |
| 분석 | GA4 (gtag) | SPA page_view + 커스텀 이벤트 |
| 호스팅 | S3 정적 사이트 + CloudFront | CDN 배포 |
| IaC | AWS SAM Template | S3/CloudFront를 코드로 관리 |
| CI/CD | GitHub Actions + OIDC | 장기 키 없이 배포 |
| 테스트 | Vitest + Testing Library | 컴포넌트/로직 테스트 |
| Lint/Format | ESLint + Prettier | 파괴적 변경 방지 |
아키텍처 및 구현 하이라이트
1) Zustand 상태를 URL에 동기화해 즉시 공유
공유 마찰을 최소화하기 위해 체인의 핵심 정보를 URL로 인코딩하도록 설계했습니다.
- 서버 측 저장소 불필요 (계정 필요 없음)
- 수신자는 링크를 열기만 하면 동일한 상태를 재현 가능
URL이 길어지는 것(공유가 어려워짐)을 막기 위해 URL에 인코딩하는 정보를 최소화했습니다.
- 비디오
id와start/end시간만 인코딩 - 제목과 썸네일은 나중에 보완해서 표시(URL 비대화 방지)
최소 인코딩 예시:
// URL에 필수 정보(id/start/end)만 인코딩
const minimalSegments = segments.map(({ id, start, end }) => ({ id, start, end }));
또한 공유 링크에는 재생 위치(어떤 클립이 재생 중인지)는 포함하지 않아, "링크를 열면 처음부터 시작"되도록 했습니다.
2) HTTP 백엔드를 통한 런타임 i18n 로딩 (빌드 독립적)
처음에는 빌드 시 번역 JSON을 임포트하는 것도 고려했지만, 정적 호스팅과 CI와의 호환성을 높이기 위해 /public/locales/{{lng}}/translation.json에서 HTTP를 통해 페치하는 방식을 선택했습니다.
- 언어 파일만 추가하면 되므로 유지보수가 쉬움
- 빌드 프로세스가 번역 임포트에 의존하지 않음
3) URL 변형을 강건하게 처리 (watch / Shorts / embed)
"표준 URL만 지원"하면 불편하므로 입력 패턴을 확장했습니다:
- 일반 watch URL
- Shorts
- 임베드 URL
결과적으로 "그냥 붙여넣기" 성공률이 높아져 일괄 등록이 훨씬 편해졌습니다.
4) 배포: S3 + CloudFront, CI: GitHub Actions (OIDC)
정적 사이트이므로 배포는 간단합니다:
- S3 (정적 호스팅)
- CloudFront (CDN)
CI/CD는 GitHub Actions로 자동화: 빌드 → S3 동기화 → CloudFront 캐시 무효화.
핵심은 OIDC입니다. 장기 키 저장 없이 배포할 수 있어 Secrets를 최소화하면서 환경 수준의 제어가 가능합니다.
정적 사이트여도 앞에 CloudFront를 두면:
- 캐싱으로 빠른 로딩
- SPA 라우팅 지원(
/로 폴백 등)이 쉬워집니다
정리
Video Chain Player는 "클립 × 연속 재생 × URL 공유"에 집중하며, 다음을 중시했습니다:
- URL에 상태를 인코딩해 공유 마찰 최소화
- i18n + 언어 URL 동기화로 수신자도 같은 언어로 보임
- 배포와 분석을 포함한 "프로덕션 레디"로 만들기
기술적으로는 다음을 조합할 수 있었습니다:
- Vite로 빠른 개발
- Zustand 상태의 URL 동기화로 공유성 향상
- i18next의 HTTP 백엔드로 경량 번역 관리
- OIDC로 안전한 배포
이 "전체 운영 스택"을 한 번에 구축하는 것이 하이라이트였습니다.
