ScorePlayer
요약
악보 파일(MusicXML)을 넣으면 오선지가 오른쪽에서 왼쪽으로 흐르고, 그 위를 파티클이 통통 튀며 지금 연주 중인 자리를 짚는다. 가사가 있으면 음절이 음표 아래에 붙어 같이 흐른다.
이 장면을 화면에서 보는 게 목적이 아니라, 배경이 투명한 영상 파일로 뽑는 게 목적이다. 뽑아서 연주 영상 위에 얹는다.
제작 동기
노래방 화면의 바운싱볼처럼 “지금 여기를 부르는 중”을 악보 위에서 보여주고 싶었다. 연주 영상을 올릴 때 악보가 같이 흐르면 보는 사람이 따라가기 쉬운데, 그걸 매번 영상 편집으로 만들 수는 없다.
앞서 만든 소리꽃 KeyBloom이 MIDI로 파티클 영상을 뽑는 도구였고, 그 영상을 투명 배경으로 받아 편집에 얹어 쓰고 있었다. ScorePlayer는 그 방식의 악보 버전이다.
예전에 한 번 만들다 만 프로젝트이기도 하다. 그때는 화면에 그리는 것까지만 보고 시작했는데, 정작 필요한 건 영상 파일이었다. 이번에는 최종 산출물을 투명 영상으로 못박고 시작한다.
목표 설정
두 단계로 나눴고 순서를 바꾸지 않는다.
- Phase 1 · 라이브 렌더러 — 정적 오선 → 음표 배치 → 스크롤 → 악보 파일 파싱 → 재생 소리 → 바운싱볼 → 가사. 화면에서 곡 하나가 박자에 맞춰 끝까지 흐르는 것까지.
- Phase 2 · 알파 영상 추출 — 같은 장면을 프레임 단위로 뽑아 투명 영상으로 인코딩.
추출을 뒤로 미룬 이유는 그릴 장면이 있어야 뽑을 게 있기 때문이고, 렌더가 흔들리는 동안 추출을 붙이면 두 곳을 동시에 디버깅하게 되기 때문이다.
대신 시작부터 지키는 규칙을 정했다. 최종 목표가 추출인데 구조를 잘못 잡으면 거기로 못 넘어가기 때문이다.
- 장면을 그리는 함수와 화면에 붙이는 것을 나눈다. 같은 장면을 화면에도, 프레임 단위로도 그릴 수 있어야 한다.
- 파일 형식은 어댑터가 흡수하고, 그리는 쪽은 공통 자료구조만 본다.
- 박자는 프레임 수가 아니라 경과 시간으로 센다. 재생 중 시각은 소리가 정하고, 추출 중 시각은 프레임 번호가 정한다.
- 오선·음표는 벡터로 그리고 픽셀 좌표를 손으로 찍지 않는다. 4K로 뽑을 때 선이 뭉개진다.
- 단(오선)은 처음부터 배열로 둔다. 주로 쓸 형태가 피아노 두 단이다.
범위 밖으로 밀어 둔 것도 정했다 — 실시간 건반 입력, 악보 편집, 정식 조판(이음줄·아티큘레이션 등), 로그인·서버·결제. 가사 입력만 예외로 두는데, 피아노 악보에는 가사가 없는 경우가 많아서다.
주요 작업
- 기획 문서와 작업 규칙을 먼저 세웠다. 위의 아키텍처 규칙이 여기서 나왔다.
- 입력 형식을 악보 파일 하나로 좁혔다. 연주 파일(MIDI)은 악보를 그리는 데 필요한 정보가 없어서 전부 추론해야 하는데, 그 추론은 악보 프로그램도 깔끔하게 못 한다.
- 가사를 기능으로 넣고, 악보에 가사가 없을 때 직접 넣는 방식을 정했다. 붙여넣으면 음절을 음표에 순서대로 배정하고 어긋난 자리를 보정한다.
- 투명 영상 추출이 실제로 되는지 실험으로 확인했다. 코덱 여섯 가지를 뽑아 편집 프로그램에서 직접 열어 보고 ProRes 4444로 확정했으며, 인코더 옵션을 조절해 네 배 빠르게 만들었다.
- 스택을 Rust로 확정했다. 4K 악보 한 장을 그리는 데 프레임당 4.5ms로 인코딩(43ms)의 10분의 1이라, 그리기는 CPU로 충분하다는 게 근거였다.
- MusicXML 어댑터를 붙여 첫 동작판(MVP)을 만들었다. 압축된 악보 파일(.mxl)까지 열면 악보가 흐르고, 해상도를 골라 투명 영상으로 뽑는다.
- 실제 악보를 열어 표기를 채웠다 — 음자리표·조표·임시표·쉼표·이음줄·붙임점·꼬리·빔. 기호가 반 칸씩 어긋나 앉던 문제는 악보 전용 폰트(Bravura)로 기준을 바꾸면서 사라졌다.
- 미리보기에 재생 소리를 붙였다. 박자 확인용 합성음이고, 재생 중 시각을 소리 쪽에서 받아와 볼과 화면이 소리를 따라간다.
- ⏳ 가사 직접 입력과 보정 화면 — Phase 1에서 남은 큰 조각이다.
- ⏳ 구간만 뽑는 기능 — 긴 곡을 통째로 뽑으면 파일이 너무 크다.
- ⏳ 박자표 기호·잇단음표, 두 단을 넘나드는 빔.
결과
⏳ 진행 중. Phase 1(라이브 렌더러)에서 가사 직접 입력 하나만 남은 상태다.
악보 파일을 열면 피아노 두 단 악보가 흐르고, 볼이 박자에 맞춰 튀며 소리가 따라 울린다. 같은 장면을 투명 영상으로 뽑을 수 있다. 추출은 실험 때 잰 대로 5분짜리 곡이 4K로 13분·5.3GB, 1080p로 5분·2.3GB라, 긴 곡을 위한 구간 추출이 다음 순서에 올라 있다.