두 영상이 싱크 맞춤과 이퀄라이저 조정을 거쳐 ffmpeg 필터 체인으로 병합되고, 다운 스케일링 후 S3에 업로드됨.
영상 편집 화면
배경
연주 영상을 둘로 합치는 ‘합주’하기 기능을 구현하기 위해서 입력된 동영상의 싱크를 맞추고 이퀄라이저를 조절하여 영상을 병합하는 과정이 필요함.
구현 방식
검은 화면을 먼저 배치하고, 클립마다 구간을 잘라 크기를 맞춘 뒤 그 위에 차례로 겹치도록 필터를 구성함. 오디오는 클립별 음량과 이퀄라이저를 적용한 뒤 하나로 섞음. S3 업로드와 비디오 컴포넌트 충돌을 막기 위한 다운 스케일링*에도 ffmpeg를 사용함.
Recho / 주요 기능·개발 과정
컴포넌트 리팩토링
팀원 4명이 따로 구현한 기능을 공통 컴포넌트로 분리·통합해 하나의 흐름으로 연결하고, 새 페이지는 기존 컴포넌트 조합으로 구성함.
리팩토링된 컴포넌트
배경
팀원들이 각자 구현한 기능(영상 업로드, 영상 동시 재생/녹화, ffmpeg 라이브러리 네이티브 이식, 영상 병합 및 편집)을 하나로 연결된 기능으로 리팩토링해야 함.
구현 방식
각 페이지별 공통 컴포넌트를 분리하고 특정 함수들은 리팩토링하고 새로운 페이지를 만들어 관련 컴포넌트 및 기능으로 재구성함.
결과
팀원 4명이 각각 구현한 기능을 공통 컴포넌트로 통합해 하나의 흐름으로 연결함. 이후 새 페이지는 기존 컴포넌트를 조합해 구성함.
Recho / 주요 기능·개발 과정
합주 세션 모집 게시판 구현
악기 파트를 배열 컬럼 대신 별도 엔티티로 — 모집글 > 악기 파트 > 지원자의 3단 구조.
합주 모집 게시판 및 합주 모집 등록 화면
배경
합주를 위해 사람을 모집하는 게시판을 구현해야 함. 글 작성자는 악기와 인원 수를 정해 올리고, 지원자가 하나의 세션에 신청하는 구조임. 악기 파트를 배열 칼럼으로 저장하면 지원자의 신청 파트가 배열 인덱스로 기록됨. 글 작성자가 중간 파트를 삭제하면 이후 파트의 인덱스가 한 칸씩 이동함. 이에 따라 기존 지원자가 다른 악기에 연결됨.
구현 방식
따라서 악기 파트를 별도 엔티티로 분리해 모집글 - 파트 - 지원자 3단 구조로 관리함. 파트 엔티티에 악기명과 모집 인원, 현재 인원을 두어 파트별로 인원을 셈. 모집글 수정은 Nest.js 서비스에서 기존 파트와 요청 파트를 ID로 비교해 추가·수정·삭제로 나눈 뒤 한 트랜잭션으로 반영함.
결과
게시물을 수정해도 지원자와 파트의 연결이 유지됨.
Seoul Meari
프로젝트 개요
2025.08 ~ 2025.09
시민이 남기는 AR 방명록, AI가 설명하는 도슨트, 과거로 돌아가는 VR 역사 체험 및 이를 바탕으로 한 AI 도시 진단을 결합한 소셜 플랫폼
전체 데이터를 기준으로 빈자리가 있는 첫 번째 행에 배치하는 first-fit 방식을 사용해, 팬·줌 시에도 사건 카드가 같은 행에 유지됨
라벨 폭 정밀 측정
Canvas2D measureText로 한글·CJK·혼용 텍스트의 실제 폭을 정확히 측정함
줌·팬 인터랙션
100%(fit) ~ 5000% 범위의 앵커 줌, 두 손가락 스크롤 팬, ⌘/Ctrl + 휠 줌, 터치 핀치 줌이 모두 지원됨
드래그 앤 드롭
카드 이동과 기간 조절을 드래그와 키보드로 지원하며, 원본 데이터를 바꾸지 않고 콜백으로 새 시간 값을 전달함
헤드리스 & 가상화
useTimeline 훅으로 엔진만 따로 쓸 수 있고, 가상화로 사건 2만 개도 약 200개의 DOM 노드로 렌더링함
Controlled / Uncontrolled
viewportStart/End props를 사용해 외부 시간바와 양방향으로 연동하거나, 뷰포트를 컴포넌트 내부에서 관리할 수 있음
@mogiyoon/react-stable-timeline / 주요 기능·개발 과정
줌·팬 때마다 행이 바뀌는 문제를 확인하고 직접 구현함
행 이동의 원인이 세부 옵션이 아니라 화면 구간 기준 재계산 구조에 있어, vis-timeline을 제거하고 행 고정 모드를 포함해 직접 구현함.
배경
도감의 연표에 사용할 타임라인 컴포넌트를 처음에는 vis-timeline으로 구성함. 같은 시간대의 사건이 겹치지 않도록 여러 행에 나누는 기능은 정상적으로 동작함. 그러나 화면에 보이는 구간만 기준으로 행을 매번 다시 계산하는 구조여서, 줌·팬을 할 때 사건 카드가 다른 행으로 이동했음.
검토 과정
한번 정한 행은 줌·팬 뒤에도 유지되는 편이 사용하기 쉽다고 판단함.
구현 방식
세부 옵션으로 해결할 수 있는 문제가 아니라 행을 정하는 기준 자체의 문제였음. 이에 vis-timeline을 제거하고, 행을 고정하는 모드를 포함한 타임라인을 직접 구현함.
두 영상이 싱크 맞춤과 이퀄라이저 조정을 거쳐 ffmpeg 필터 체인으로 병합되고, 다운 스케일링 후 S3에 업로드됨.
영상 편집 화면
배경
연주 영상을 둘로 합치는 ‘합주’하기 기능을 구현하기 위해서 입력된 동영상의 싱크를 맞추고 이퀄라이저를 조절하여 영상을 병합하는 과정이 필요함.
구현 방식
검은 화면을 먼저 배치하고, 클립마다 구간을 잘라 크기를 맞춘 뒤 그 위에 차례로 겹치도록 필터를 구성함. 오디오는 클립별 음량과 이퀄라이저를 적용한 뒤 하나로 섞음. S3 업로드와 비디오 컴포넌트 충돌을 막기 위한 다운 스케일링*에도 ffmpeg를 사용함.
4
Recho / 주요 기능·개발 과정
컴포넌트 리팩토링
팀원 4명이 따로 구현한 기능을 공통 컴포넌트로 분리·통합해 하나의 흐름으로 연결하고, 새 페이지는 기존 컴포넌트 조합으로 구성함.
리팩토링된 컴포넌트
배경
팀원들이 각자 구현한 기능(영상 업로드, 영상 동시 재생/녹화, ffmpeg 라이브러리 네이티브 이식, 영상 병합 및 편집)을 하나로 연결된 기능으로 리팩토링해야 함.
구현 방식
각 페이지별 공통 컴포넌트를 분리하고 특정 함수들은 리팩토링하고 새로운 페이지를 만들어 관련 컴포넌트 및 기능으로 재구성함.
결과
팀원 4명이 각각 구현한 기능을 공통 컴포넌트로 통합해 하나의 흐름으로 연결함. 이후 새 페이지는 기존 컴포넌트를 조합해 구성함.
5
Recho / 주요 기능·개발 과정
합주 세션 모집 게시판 구현
악기 파트를 배열 컬럼 대신 별도 엔티티로 — 모집글 > 악기 파트 > 지원자의 3단 구조.
합주 모집 게시판 및 합주 모집 등록 화면
배경
합주를 위해 사람을 모집하는 게시판을 구현해야 함. 글 작성자는 악기와 인원 수를 정해 올리고, 지원자가 하나의 세션에 신청하는 구조임. 악기 파트를 배열 칼럼으로 저장하면 지원자의 신청 파트가 배열 인덱스로 기록됨. 글 작성자가 중간 파트를 삭제하면 이후 파트의 인덱스가 한 칸씩 이동함. 이에 따라 기존 지원자가 다른 악기에 연결됨.
구현 방식
따라서 악기 파트를 별도 엔티티로 분리해 모집글 - 파트 - 지원자 3단 구조로 관리함. 파트 엔티티에 악기명과 모집 인원, 현재 인원을 두어 파트별로 인원을 셈. 모집글 수정은 Nest.js 서비스에서 기존 파트와 요청 파트를 ID로 비교해 추가·수정·삭제로 나눈 뒤 한 트랜잭션으로 반영함.
결과
게시물을 수정해도 지원자와 파트의 연결이 유지됨.
6
Seoul Meari
프로젝트 개요
2025.08 ~ 2025.09
시민이 남기는 AR 방명록, AI가 설명하는 도슨트, 과거로 돌아가는 VR 역사 체험 및 이를 바탕으로 한 AI 도시 진단을 결합한 소셜 플랫폼
전체 데이터를 기준으로 빈자리가 있는 첫 번째 행에 배치하는 first-fit 방식을 사용해, 팬·줌 시에도 사건 카드가 같은 행에 유지됨
라벨 폭 정밀 측정
Canvas2D measureText로 한글·CJK·혼용 텍스트의 실제 폭을 정확히 측정함
줌·팬 인터랙션
100%(fit) ~ 5000% 범위의 앵커 줌, 두 손가락 스크롤 팬, ⌘/Ctrl + 휠 줌, 터치 핀치 줌이 모두 지원됨
드래그 앤 드롭
카드 이동과 기간 조절을 드래그와 키보드로 지원하며, 원본 데이터를 바꾸지 않고 콜백으로 새 시간 값을 전달함
헤드리스 & 가상화
useTimeline 훅으로 엔진만 따로 쓸 수 있고, 가상화로 사건 2만 개도 약 200개의 DOM 노드로 렌더링함
Controlled / Uncontrolled
viewportStart/End props를 사용해 외부 시간바와 양방향으로 연동하거나, 뷰포트를 컴포넌트 내부에서 관리할 수 있음
9
@mogiyoon/react-stable-timeline / 주요 기능·개발 과정
줌·팬 때마다 행이 바뀌는 문제를 확인하고 직접 구현함
행 이동의 원인이 세부 옵션이 아니라 화면 구간 기준 재계산 구조에 있어, vis-timeline을 제거하고 행 고정 모드를 포함해 직접 구현함.
배경
도감의 연표에 사용할 타임라인 컴포넌트를 처음에는 vis-timeline으로 구성함. 같은 시간대의 사건이 겹치지 않도록 여러 행에 나누는 기능은 정상적으로 동작함. 그러나 화면에 보이는 구간만 기준으로 행을 매번 다시 계산하는 구조여서, 줌·팬을 할 때 사건 카드가 다른 행으로 이동했음.
검토 과정
한번 정한 행은 줌·팬 뒤에도 유지되는 편이 사용하기 쉽다고 판단함.
구현 방식
세부 옵션으로 해결할 수 있는 문제가 아니라 행을 정하는 기준 자체의 문제였음. 이에 vis-timeline을 제거하고, 행을 고정하는 모드를 포함한 타임라인을 직접 구현함.