Recho
음악으로 나를 알리는 플랫폼
개요
기간
2025.06 ~ 2025.07
개요
팀 프로젝트
역할
백엔드, 프론트엔드, ERD 설계, ffmpeg 활용, AWS 서버 구축, WebView 앱 대응(뒤로가기·화면 확대·구글 로그인)
주요 기능
커뮤니티, 합주 모집, 악기 중고 거래, 숏폼 기능
사용 기술
아키텍처
구현 기능 및 개발 과정
ffmpeg를 활용한 동영상 병합 로직 구현
연주 영상을 둘로 합치는 ‘합주’하기 기능을 구현하기 위해서 입력된 동영상의 싱크를 맞추고 이퀄라이저를 조절하여 영상을 병합하는 과정이 필요함.
검은 화면을 먼저 배치하고, 클립마다 구간을 잘라 크기를 맞춘 뒤 그 위에 차례로 겹치도록 필터를 구성함. 오디오는 클립별 음량과 이퀄라이저를 적용한 뒤 하나로 섞음. S3 업로드와 비디오 컴포넌트 충돌을 막기 위한 다운 스케일링*에도 ffmpeg를 사용함.
*ffmpeg: 동영상, 음악, 사진 포맷들의 디코딩, 인코딩을 위한 프로젝트 *다운 스케일링: 원본 데이터·영상·이미지·해상도 등의 크기를 줄이는 과정
컴포넌트 리팩토링
팀원들이 각자 구현한 기능(영상 업로드, 영상 동시 재생/녹화, ffmpeg 라이브러리 네이티브 이식, 영상 병합 및 편집)을 하나로 연결된 기능으로 리팩토링해야 함.
각 페이지별 공통 컴포넌트를 분리하고 특정 함수들은 리팩토링하고 새로운 페이지를 만들어 관련 컴포넌트 및 기능으로 재구성함.
팀원 4명이 각각 구현한 기능을 공통 컴포넌트로 통합해 하나의 흐름으로 연결함. 이후 새 페이지는 기존 컴포넌트를 조합해 구성함.
합주 세션 모집 게시판 구현
합주를 위해 사람을 모집하는 게시판을 구현해야 함. 글 작성자는 악기와 인원 수를 정해 올리고, 지원자가 하나의 세션에 신청하는 구조임. 악기 파트를 배열 칼럼으로 저장하면 지원자의 신청 파트가 배열 인덱스로 기록됨. 글 작성자가 중간 파트를 삭제하면 이후 파트의 인덱스가 한 칸씩 이동함. 이에 따라 기존 지원자가 다른 악기에 연결됨.
따라서 악기 파트를 별도 엔티티로 분리해 모집글 - 파트 - 지원자 3단 구조로 관리함. 파트 엔티티에 악기명과 모집 인원, 현재 인원을 두어 파트별로 인원을 셈. 모집글 수정은 Nest.js 서비스에서 기존 파트와 요청 파트를 ID로 비교해 추가·수정·삭제로 나눈 뒤 한 트랜잭션으로 반영함.
게시물을 수정해도 지원자와 파트의 연결이 유지됨.
좋아요, 댓글 모듈 리팩토링
좋아요와 댓글이 각 게시판 모듈별로 관리되고 있었음. 추후 알람 기능을 비롯한 좋아요와 댓글 기능을 구현할 때 각 모듈마다 기능을 추가해야 해 확장성이 떨어짐.
댓글과 좋아요를 게시판마다 두지 않고 각각 하나의 모듈로 합침. contentType 컬럼으로 어느 게시판의 글인지 구분함. 게시물 ID가 숫자인 게시판과 문자열인 게시판이 있어 엔티티는 두 종류로 둠.
알람 기능 추가 시 게시판별로 댓글과 좋아요를 다시 구현할 필요가 없어짐. 게시물의 좋아요 수와 댓글 수는 값을 읽어 다시 쓰지 않고 DB의 증감 연산으로 갱신해, 요청이 동시에 들어와도 수가 어긋나지 않게 함.
서버 구축
배포 서버의 보안을 위해 VPC를 포함한 서버 구조 설계 방법을 고민함. React Vite의 빌드 방식을 학습한 결과 CSR 기반 SPA로 빌드됨을 확인함. 또한 영상과 이미지는 백엔드 서버를 거치지 않고, S3에서 전송되므로 CDN을 활용할 경우 비용과 속도 측면에서 효율적임을 확인함.
따라서 프론트엔드는 정적 호스팅 서버인 Cloud Front 및 S3를 기반으로 배포를 함. 백엔드 및 DB 서버는 보안 및 확장성을 고려하여 VPC 환경에서 ALB, EC2, RDBMS 기반으로 구성함.
이슈 클로즈
개발이 막바지에 이르러 해결되지 않은 이슈가 쌓였음.
할당된 기능 구현을 마친 뒤, 출시를 막는 이슈를 우선 선별해 해결함.
담당 외 영역의 이슈도 직접 해결함.
트러블 슈팅
영상 재생 및 동시 녹화 기능 구현
합주 기능을 구현하기 위해 카메라 녹화와 영상 재생을 동시에 해야함.
1. mixWithOthers: 'mix' 설정 → 실패 - React Native Video 컴포넌트에서 해당 옵션을 설정했지만 작동하지 않음. - 이유: iOS의 기본 오디오 세션 정책상, mixWithOthers 기능이 비활성화되어 있으며, 이를 활성화하려면 네이티브 코드 수정이 필요함.
2. 네이티브 모듈에 mixWithOthers 브릿지 추가 → 실패 - VisionCamera 라이브러리에는 관련 기능이 있으나, Video 라이브러리에는 존재하지 않음. - 직접 브릿지를 연결해도 효과가 없었음.
3. 비디오 라이브러리 네이티브 코드에 옵션 추가 → 실패 - 직접 mixWithOthers 관련 설정을 Video 라이브러리에 추가했으나, 여전히 작동하지 않음.
4. disableAudioSessionManagement: true 설정 → 성공 - 라이브러리 내부의 옵션 중 disableAudioSessionManagement: true 설정을 발견함. - 이 옵션을 활성화하자 비디오와 카메라 오디오가 동시에 작동함.
카메라 녹화 및 영상 재생이 가능해짐. 라이브러리 내부 코드의 중요성을 확인함.
클라우드 프론트 CDN을 활용한 이미지/영상 캐싱
영상과 이미지의 로딩 속도가 느림.
영상과 이미지를 저장/캐싱 하는 방식을 고민함.
S3 버킷에서 영상/이미지 데이터를 직접 로드하는 초기 방식에서 클라우드 프론트의 CDN을 활용하여 영상/이미지 캐싱
S3에서 직접 내려받던 영상과 이미지를 CloudFront 캐시에서 받도록 변경함.
결과 및 회고
결과
Zustand 기반의 전역 상태 관리
response DTO를 활용한 응답 형식 일관성 유지 및 응답 최적화
ffmpeg를 활용한 영상 및 오디오 편집 방법 적용
네이티브 코드를 활용한 네이티브 기능 실행
CDN을 활용한 로딩 시간 단축
회고
백엔드와 프론트엔드를 잇는 구조를 직접 설계하고 구현함.
기능을 게시판별로 구현하지 않고 모듈로 분리하면 이후 기능 추가가 쉬워짐을 확인함.
AWS 기반 서버를 구축하며 VPC, CDN, ALB의 역할을 정리함.
ERD 설계, API 설계, 깃허브 브랜치·이슈 관리로 협업 방식을 익힘.
라이선스
