ecole42

hypertube

hypertube

hypertube는 ecole42의 웹 프로젝트로, 토렌트 프로토콜을 사용하여 비디오를 다운로드하면서 동시에 스트리밍할 수 있는 웹 애플리케이션을 만들어야한다. 해당 프로젝트는 NestJS와 Nuxt 3를 사용한 풀스택 애플리케이션으로, OAuth2 인증(42, Google, GitHub), 토렌트 기반 스트리밍, TMDB/YTS API 통합, 자막 지원, 댓글 시스템 등을 구현하였다. Docker를 통한 컨테이너화와 Cron job 을 통한 자동화 기능을 포함한다

NestJS
Nuxt.js
TypeORM
MySQL
Docker
Socket.IO

개요

Hypertube는 토렌트 프로토콜을 사용하여 비디오를 다운로드하면서 동시에 스트리밍할 수 있는 웹 애플리케이션이다. ecole42의 웹 프로젝트다.

스크린샷

homelogin
registerprofile
movievideo

기술 스택

Backend

  • Framework: NestJS
  • Database: MySQL
  • ORM: TypeORM
  • Authentication: Passport.js (JWT, OAuth2)
  • Streaming: torrent-stream, fluent-ffmpeg
  • API Documentation: Swagger
  • Task Scheduling: @nestjs/schedule (Cron)

Frontend

  • Framework: Nuxt 3
  • UI Library: PrimeVue
  • Styling: TailwindCSS, SCSS
  • State Management: Pinia
  • Internationalization: @nuxtjs/i18n (FR/EN)
  • HTTP Client: Axios

Infrastructure

  • Containerization: Docker & Docker Compose
  • Package Manager: pnpm

주요 기능

인증 및 사용자 관리

  • OAuth2 로그인: 42, Google, GitHub 지원
  • 로컬 인증: 이메일/비밀번호 기반 회원가입 및 로그인
  • 비밀번호 재설정: 이메일을 통한 비밀번호 재설정 기능
  • 프로필 관리: 사용자 정보 수정 및 프로필 이미지 업로드

영화 스트리밍

  • 토렌트 기반 스트리밍: 다운로드와 동시에 비디오 스트리밍
  • 다양한 해상도 지원: 여러 비디오 품질 옵션 제공
  • 자막 지원: Open Subtitles API를 통한 FR/EN 자막 제공
  • 자막 동기화: 자막 동기화 버튼 기능

영화 검색 및 탐색

  • TMDB API 통합: 영화 메타데이터 및 포스터 제공
  • YTS API 통합: 토렌트 파일 정보 제공
  • 무한 스크롤: 영화 목록을 효율적으로 로드
  • 장르 필터링: 다양한 영화 장르별 필터링

사용자 경험

  • 다국어 지원: 프랑스어(FR) 및 영어(EN) 지원
  • 시청 기록: 사용자가 본 영화 목록 관리
  • 댓글 시스템: 영화별 댓글 작성 및 조회
  • 반응형 디자인: 모바일 및 데스크톱 지원

자동화

  • Cron 작업: 매월 1일 자정에 1개월 이상 시청되지 않은 영화 자동 삭제
  • 데이터베이스 시딩: 개발 환경을 위한 샘플 데이터 생성

사전 요구사항

  • Docker 및 Docker Compose
  • pnpm (또는 npm/yarn)
  • MySQL (Docker로 실행 가능)
  • 다음 API 키:
    • TMDB API Key
    • Open Subtitles API Key
    • OAuth2 클라이언트 ID 및 Secret (42, Google, GitHub)

설치 및 실행

1. 환경 변수 설정

프로젝트 루트에 .env 파일을 생성하고 다음 변수들을 설정한다:

# Database
MYSQL_USER=your_mysql_user
MYSQL_PASSWORD=your_mysql_password
MYSQL_DATABASE=hypertube
DB_PORT=3306

# Backend
BACK_PORT=3005
BACK_HOST=http://localhost:3005

# Frontend
FRONT_PORT=3000
FRONT_HOST=http://localhost:3000

# JWT
JWT_SECRET=your_jwt_secret
JWT_ACCESS_DURATION=1h

# OAuth2 - 42
FT_CLIENT_ID=your_42_client_id
FT_CLIENT_SECRET=your_42_client_secret
FT_CALLBACK_URL=http://localhost:3005/auth/42/callback

# OAuth2 - Google
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
GOOGLE_CALLBACK_URL=http://localhost:3005/auth/google/callback

# OAuth2 - GitHub
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GITHUB_CALLBACK_URL=http://localhost:3005/auth/github/callback

# External APIs
TMDB_ACCESS_TOKEN=your_tmdb_access_token
OPEN_SUBTITLES_API_KEY=your_open_subtitles_api_key
OPEN_SUBTITLES_USER=your_open_subtitles_username
OPEN_SUBTITLES_PASSWORD=your_open_subtitles_password

# Email (for password reset)
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your_email@gmail.com
EMAIL_PASS=your_email_password

2. Docker Alias 설정

개발 편의를 위해 alias를 설정한다:

source alias.sh

3. 개발 환경 실행

첫 실행 (이미지 빌드 포함)

dev-up-build

이후 실행 (이미지가 이미 빌드된 경우)

dev-up

서비스 중지

dev-down

4. 프로덕션 환경 실행

prod-up-build

또는

prod-up

패키지 관리

Docker 컨테이너 내에서 패키지를 설치하려면:

# Frontend 패키지 설치
front-dev pnpm i some-package

# Backend 패키지 설치
back-dev pnpm i some-package

데이터베이스 관리

마이그레이션 실행

back-dev pnpm run db:migrate

마이그레이션 생성

back-dev pnpm run db:generate-migration

시드 데이터 실행

back-dev pnpm run seed:run

API 문서

애플리케이션이 실행되면 Swagger API 문서를 다음 주소에서 확인할 수 있다:

http://localhost:3005/api

프로젝트 구조

hypertube/
├── back/                    # NestJS 백엔드
│   ├── src/
│   │   ├── auth/           # 인증 모듈 (OAuth2, JWT)
│   │   ├── user/           # 사용자 모듈
│   │   ├── movie/          # 영화 모듈 (토렌트, 스트리밍)
│   │   ├── comment/        # 댓글 모듈
│   │   ├── guards/         # 인증 가드
│   │   └── migrations/     # 데이터베이스 마이그레이션
│   ├── movies/             # 다운로드된 영화 파일 저장소
│   └── package.json
├── front/                   # Nuxt 3 프론트엔드
│   ├── components/         # Vue 컴포넌트
│   ├── pages/             # 페이지 라우트
│   ├── composables/       # Vue Composables
│   ├── stores/            # Pinia 스토어
│   └── package.json
├── docker-compose.yml      # 기본 Docker Compose 설정
├── docker-compose.dev.yml  # 개발 환경 오버라이드
├── docker-compose.prod.yml # 프로덕션 환경 오버라이드
└── alias.sh                # 개발 편의를 위한 alias 스크립트

주요 모듈 설명

Backend 모듈

  • AuthModule: 사용자 인증 및 OAuth2 전략 관리
  • UserModule: 사용자 CRUD 및 프로필 관리
  • MovieModule: 영화 검색, 토렌트 다운로드, 스트리밍 처리
  • CommentModule: 영화 댓글 관리
  • CronService: 정기 작업 스케줄링 (오래된 영화 삭제)

Frontend 모듈

  • PageHome: 홈페이지 및 영화 목록
  • PageMovie: 영화 상세 페이지 및 스트리밍 플레이어
  • PageProfile: 사용자 프로필 및 시청 기록
  • Auth Pages: 로그인, 회원가입, 비밀번호 재설정

개발 도구

Linting 및 포맷팅

# Backend
back-dev pnpm run lint

# Frontend
front-dev pnpm run lint
front-dev pnpm run stylelint

테스트

# Backend 테스트
back-dev pnpm run test
back-dev pnpm run test:watch
back-dev pnpm run test:cov

보너스 기능

  • ✅ 모든 서비스 Docker 컨테이너화
  • ✅ 추가 OAuth2 전략 (42, Google, GitHub)
  • ✅ 다양한 비디오 해상도 지원
  • ✅ Swagger를 통한 API 문서화
  • ✅ 자막 동기화 버튼

참고 자료