Skip to content

Repository files navigation

Artune Logo

감정에 따른 음원 추천 서비스

당신의 하루, 당신의 감정을 텍스트로 들려주세요.
AI(OPENAI)가 분석한 감정에 맞춰 음악(iTunes Search API)디저트 아트워크(DALL-E)를 선물합니다.


React NestJS TypeScript Vite Turborepo OpenAI

📖 프로젝트 소개

Artune은 사용자가 입력한 일기나 짧은 텍스트를 분석하여, 현재 감정 상태에 가장 적합한 음악 플레이리스트와 시각적 즐거움을 주는 픽셀 아트 디저트를 제공하는 웹 서비스입니다.

단순 음악 추천이 아닌 감정을 더 깊이 느끼고 싶을 때(Immerse)전환하고 싶을 때(Soothe) 두 가지 선택지를 제공합니다.

🌟 핵심 기능

  • AI 감정 분석 & 큐레이션: OpenAI GPT 4.1 mini 모델이 텍스트의 미묘한 감정선을 분석하고, 감정·모드별로 어울리는 아티스트 풀(25명/모드)을 직접 큐레이션합니다.
  • Dual Mode Playlist:
    • 🎶 감정 심취 (Immerse): 슬플 땐 더 슬픈 음악으로, 기쁠 땐 더 신나는 음악으로 감정을 극대화합니다.
    • 🌿 감정 완화 (Soothe): 격한 감정을 차분하게, 혹은 우울한 기분을 산뜻하게 전환합니다.
  • 인터랙티브 음악 청취:
    • iTunes Search API 기반으로 아티스트별 인기 트랙과 30초 미리듣기를 제공합니다.
    • CD 바이닐 인터랙션: 음악 재생 시 CD가 플레이어에 들어가고, 정지 시 **DJ 스크래치 효과(Fade-out & Pitch down)**와 함께 멈추는 디테일한 UX를 구현했습니다.
  • 감정 맞춤 Pixel Art: 감정 키워드와 장르를 조합하여 DALL-E 프롬프트를 생성, 매번 다른 '오늘의 디저트' 픽셀 아트를 제공합니다. (해당 기능은 잠시 정지시켰습니다.)
  • 실시간 분석 경험: Server-Sent Events (SSE)를 도입하여 감정 분석 → 음악 탐색 → 이미지 생성의 진행 상황을 실시간 프로그레스 바로 시각화했습니다.

🏗️ 시스템 아키텍처

사용자의 텍스트가 어떻게 음악과 이미지로 변환되는지 보여주는 데이터 흐름도입니다.
Server-Sent Events (SSE) 를 도입하여, 각 단계가 완료될 때마다 클라이언트에게 실시간으로 피드백을 제공합니다.

System Architecture Diagram

🛠 기술 스택

Architecture

  • Monorepo: Turborepo (Frontend/Backend 패키지 통합 관리)
  • Package Manager: npm Workspaces

Frontend (apps/frontend)

  • Core: React 19, Vite 7
  • State Management: Zustand 5 (전역 상태 및 비동기 액션 관리)
  • Styling: Emotion (CSS-in-JS), Framer Motion (고성능 애니메이션)
  • Testing: Vitest, React Testing Library

Backend (apps/backend)

  • Core: NestJS 11 (Module 기반 아키텍처)
  • Language: TypeScript (strictNullChecks 활성화)
  • External APIs:
    • OpenAI Chat Completions API: 감정 분석 및 아티스트 큐레이션
    • iTunes Search API: 아티스트 기반 트랙 검색 및 미리듣기 음원 확보
    • DALL-E API: 이미지 생성 (현재 정적 매핑으로 대체)
  • Caching: NestJS CacheModule (아티스트 단위 6시간 버킷 캐시)
  • Testing: Jest (서비스 레이어 단위 테스트)
  • Protocol: HTTP, SSE (Server-Sent Events)

📱 UI/UX 미리보기

감정 입력 및 로딩 (SSE) 결과 페이지 (PC View) 모바일/태블릿 반응형
Loading Process PC Result Page Mobile Result Page
실시간 분석 진행률 표시 아트워크와 플레이리스트 분할 뷰 토글형 뷰 전환 & 터치 인터랙션

⚙️ 설치 및 실행

이 프로젝트는 Turborepo를 사용하고 있습니다. 루트 디렉토리에서 한 번의 명령어로 전체 프로젝트를 실행할 수 있습니다.

1. 환경 변수 설정 (.env)

Backend (apps/backend/.env)

PORT=3000
OPENAI_API_KEY=your_openai_key
FRONTEND_URL=http://localhost:5173

Frontend (apps/frontend/.env)

VITE_API_BASE_URL=http://localhost:3000/api

2. 패키지 설치

npm install

3. 개발 서버 실행 (Frontend + Backend)

npm run dev

# Frontend: http://localhost:5173
# Backend:  http://localhost:3000

📂 프로젝트 구조

artune/
├── apps/
│   ├── backend/              # NestJS Server
│   │   └── src/
│   │       ├── emotion/      # 감정 분석 및 오케스트레이션 (Core)
│   │       ├── music/        # 음악 추천 로직 (Diversity 알고리즘 등)
│   │       ├── itunes/       # iTunes Search API (캐시·rate limit 처리)
│   │       ├── openai/       # GPT 프롬프트 제어
│   │       └── dalle/        # 이미지 생성
│   └── frontend/             # React Client
│       └── src/
│           ├── components/   # LP Card, Toggle, Visualizer 등
│           ├── hooks/        # useAudioScratch, useMediaQuery
│           ├── stores/       # Zustand Store
│           └── pages/
├── package.json
└── turbo.json

💡 주요 기술적 고민

1. Spotify 정책 변경 대응 — iTunes Search API 완전 이전

Spotify API 정책 변경(Developer Mode 유저 제한, Premium 강제)에 대응해 음악 추천 파이프라인을 iTunes Search API로 완전 이전했습니다.

  • LLM 큐레이션 전환: 오디오 피쳐(valence/energy/tempo) 기반 필터링 대신, GPT가 감정·모드별 아티스트 풀을 직접 큐레이션하는 구조로 재설계. 추천 요청당 Spotify API 호출 65회 전부 제거.
  • Rate Limit 방어: 429/403을 상태별로 판별해 국가 폴백의 호출 증폭(최대 3배)을 차단하고, 일시적 차단이 6시간 캐시에 오염되는 문제를 수정. throttle 상황에서도 트랙 수율 20/20 유지.

2. 측정 기반 응답시간 최적화 (17.9초 → 11.6초, -35%)

단계별 타이밍 계측을 심어 병목을 실측으로 식별한 뒤 최적화했습니다. (원본 로그)

단계 응답시간 조치
Baseline 17.9s LLM 52% + iTunes 순차 호출 48%로 병목 분해
SSE 병렬화 ~13.8s iTunes 구간 8.6s → 4.5s. 완료 카운트 기반 마일스톤으로 진행률 단조 증가 보장
LLM 출력 축소 11.6s 아티스트 40→25명/모드로 출력 토큰 절감 (수율 20/20 유지 검증)

3. 오디오 UX 디테일 (Web Audio API & Interaction)

  • 단순한 play/pause가 아닌, 실제 LP판을 멈추는 듯한 경험을 주기 위해 커스텀 훅(useAudioScratch)을 구현했습니다.
  • 재생 속도(playbackRate)와 볼륨을 프레임 단위로 조절하여 Pitch Down & Fade Out 효과를 구현했습니다.
  • 탭 전환 시 자동 정지, 메모리 누수 방지를 위한 Cleanup 로직을 철저히 적용했습니다.

4. 반응형 디자인과 Glassmorphism

  • Emotion을 활용해 세련된 Dark Glassmorphism 테마를 구축했습니다.
  • PC에서는 한 화면에 아트워크와 리스트를, 모바일에서는 토글 방식을 적용하여 디바이스별 최적화된 레이아웃을 제공합니다.

기여자

About

텍스트 기반 감정 분석 음원 추천 서비스

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages