My Girlfriend's Dead — 팬메이드 애니메이션
2026코드만으로 그린 161초짜리 애니메이션. 곡에 맞춰 실시간으로 재생됩니다.
- Role
- 스토리보드, 캐릭터 리그, 소품, 애니메이션, 타이밍까지 전부
- Stack
- Canvas 2D Vanilla JS YouTube IFrame API Node
문제
2분 30초짜리 펑크 곡을 위한 비공식 뮤직비디오입니다. 애니메이션 툴도, 에셋 파이프라인도, 예산도 없이 만들어야 했습니다. 빠른 보컬을 따라가면서 웃겨야 했고, 동시에 저작권 문제에서도 안전해야 했습니다. 곡을 제가 통제하는 서버에 올릴 수는 없었으니까요.
첫 버전은 실패했습니다. 곡 구조를 BPM으로 추측해서 장면 10개를 전체 길이에 늘려 붙였고, 웃음이 터지지 않았습니다. 화면은 곡과 어긋났고, 장면 하나가 너무 오래 멈춰 있었습니다.
접근
- 추측 대신 측정. 보컬을 Whisper에 넣고 실제 프레이즈 경계를 뽑아냈습니다. 마디 계산이 아니라 그 경계에 맞춰 타임라인을 잘랐습니다.
- 장면이 아니라 숏. 36개의 숏으로 나눴고 평균 4.5초입니다. 가사 한 줄이 바뀔 때마다 화면도 함께 바뀝니다.
- 그림이 아니라 리그. 전부 캔버스 위의 평면 도형입니다. 골반 관절이 있는 뼈대, 교체 가능한 머리, 움직이는 팔다리를 만들고 포즈 함수 하나로 모든 숏을 처리했습니다.
- 장면은 시간의 함수.
drawFrame(ctx, t)가 곡 시간을 숏에 매핑해 그립니다. 같은 코드가 웹 페이지와 오프라인 MP4 렌더를 모두 담당합니다. 애니메이션은 단 하나의 버전만 존재합니다. - 음원은 YouTube에 그대로 둡니다. 공식 플레이어를 임베드하고 매 프레임
getCurrentTime()을 읽습니다. 재호스팅도, 화면에 가사를 띄우는 일도 없습니다.
결과
- 161초 전체를 덮는 36개의 숏, 비는 프레임 없음
- 같은 소스에서 브라우저와 1280×720 H.264 MP4(30fps) 양쪽으로 렌더
- 커밋 하나로 두 호스트에 배포: GitHub Pages, Cloudflare Pages
배운 것
- 타이밍이 곧 웃음입니다. 이걸 웃기게 만든 수정은 전부 타이밍 수정이었습니다. 오디오에서 실제 프레이즈 경계를 뽑아낸 것이 어떤 재작업보다 효과가 컸습니다.
- 제약이 설계를 밀어줍니다. 장면이 시간의 함수라서 아무 초로나 이동해 바로 확인할 수 있었습니다. 덕분에 반복 수정 비용이 싸졌고, 실제로 계속 고칠 수 있었습니다.
- 저작권선은 분명하게. 팬 작품이라도 권리자를 존중해야 합니다. 곡은 공식 플레이어에서 스트리밍하고, 그림은 직접 그리고, 가사는 절대 재현하지 않습니다.
typosbro.me/girlfriends-dead에서 볼 수 있습니다. 소스는 사이트 저장소에 있습니다.