곡 보관함과 악보 학습 기능을 보완

업로드 형식을 MIDI와 MusicXML과 MXL 및 PDF로 확장하고 파일별 검증을 추가했다.

AlphaTab 악보 자산과 Nginx MIME 설정을 보완해 운영에서 오선과 음표가 표시되도록 수정했다.

공개 도메인 클래식과 난이도별 연습 편곡 7개를 같은 제목별로 묶고 출처와 운영 검증 결과를 문서화했다.

검사: TypeScript 검사와 Vitest 67개 및 Vite 운영 빌드 통과. 운영 브라우저 악보 표시와 네 가지 업로드 검증 형식 확인.
백업: /home/syskiller/piano/backups/bach-to-basics/20261003-1545-sheet-upload
운영 반영: 완료
This commit is contained in:
이창현
2026-10-03 16:15:00 +09:00
parent c918f02685
commit 0522e48013
35 changed files with 83181 additions and 123 deletions
+35 -16
View File
@@ -2,7 +2,7 @@
## 기능 범위
Bach to Basics의 기존 파일 가져오기 기능을 유지하면서 서버 곡 보관함을 추가했다. 비회원은 전체 공개 MIDI를 바로 연주할 수 있다. 회원은 MIDI를 올리고 공개 범위와 회원 등급을 지정할 수 있다.
Bach to Basics의 기존 파일 가져오기 기능을 유지하면서 서버 곡 보관함을 추가했다. 비회원은 전체 공개 곡과 악보를 바로 연주할 수 있다. 회원은 MIDI와 악보를 올리고 공개 범위와 회원 등급을 지정할 수 있다.
공개 범위는 다음 네 단계다.
@@ -28,22 +28,32 @@ Bach to Basics의 기존 파일 가져오기 기능을 유지하면서 서버
## 화면 진입
학습 화면 상단에 다음 메뉴를 항상 표시한다.
학습 화면 상단에 계정 상태에 맞는 메뉴를 표시한다.
- `곡 보관함`: 공개 샘플과 접근 가능한 회원 곡을 검색하고 연주한다.
- `로그인·가입`: 로그인과 회원 가입을 전환한다. 로그인 뒤에는 내 계정과 비밀번호 변경 및 회원 탈퇴를 관리한다.
- `관리자`: 비회원에게는 관리자 로그인 안내를 표시한다. 관리자 로그인 뒤에는 회원 등급과 역할 및 이용 상태를 관리하는 회원 관리 화면으로 바로 이동한다.
- `로그인·회원가입`: 비회원에게 표시한다. 창 안에서 로그인과 회원 가입을 전환한다.
- `내 계정`: 로그인한 회원에게 표시한다. 비밀번호 변경과 회원 탈퇴를 관리한다.
- `관리자 패널`: 관리자 권한으로 로그인했을 때만 표시한다. 회원 등급과 역할 및 이용 상태를 관리하는 화면으로 바로 이동한다.
390픽셀 모바일 화면에서는 첫 줄에 회원 메뉴를 배치하고 둘째 줄에 화면 전환 메뉴와 MIDI 장치를 배치한다. PWA 시작 문서와 서비스 워커는 새 배포를 즉시 확인하도록 설정한다. 예전 화면이 열린 상태라면 한 번 새로고침하면 새 서비스 워커가 활성화된다.
390픽셀 모바일 화면에서는 첫 줄에 회원 메뉴를 배치하고 둘째 줄에 화면 전환 메뉴와 MIDI 장치를 배치한다. 이전 서비스 워커가 로그인과 관리자 메뉴의 오래된 화면을 계속 제공하는 문제가 있어 오프라인 캐시를 해제했다. 설치형 바로가기는 유지하며 온라인 접속 때는 항상 최신 HTML과 해시 자산을 사용한다.
## MIDI 업로드
## 연주 시작과 음표 표시
- 허용 확장자: `.mid`, `.midi`
- 최대 파일 크기: 10MB
곡을 맨 처음부터 재생하면 시계를 3초 전부터 움직인다. 이 준비 시간 동안 첫 음표가 건반 쪽으로 내려오며 화면 가운데에 3부터 1까지 남은 시간을 표시한다. 실제 MIDI 음은 원래 시작 시각인 0초부터 재생하므로 첫 음을 놓치지 않고 준비할 수 있다. 중간 위치에서 다시 재생할 때는 준비 시간을 반복하지 않는다.
화면 건반을 누를 때와 MIDI 파일을 재생할 때는 같은 피아노 샘플 엔진과 현재 선택한 악기를 사용한다. 검은 건반에 대응하는 내려오는 음표는 손 구분 색상을 유지하되 흰 건반 음표보다 명도를 낮춰 구분한다.
## 곡과 악보 업로드
- 허용 확장자: `.mid`, `.midi`, `.xml`, `.musicxml`, `.mxl`, `.pdf`
- 최대 파일 크기: 25MB
- 회원별 최대 파일 수: 100개
- 회원별 최대 보관 용량: 500MB
- 파일 이름에서 디렉터리 요소 제거
- `MThd` 헤더 확인
- MIDI는 `MThd` 헤더 확인
- MusicXML은 안전한 XML 파서로 루트 악보 구조 확인
- MXL은 압축 경로와 내부 파일 수 및 해제 용량과 주 악보 구조 확인
- PDF는 파일 서명 확인
- 임의 저장 이름과 SHA-256 해시 기록
- 곡 제목과 아티스트 및 설명
- 난이도와 장르 및 편곡 형태
@@ -58,14 +68,23 @@ Bach to Basics의 기존 파일 가져오기 기능을 유지하면서 서버
## 공개 샘플
상업 가요를 복제하지 않고 직접 만든 다음 연습곡을 전체 공개 샘플로 제공한다.
Mutopia Project가 공개 도메인으로 배포하는 실제 클래식 MIDI를 전체 공개 샘플로 제공한다. 출처와 파일별 권리 표시는 `THIRD_PARTY_SAMPLES.md`에 기록한다.
- 첫눈이 내리는 밤: 입문 멜로디
- 첫눈이 내리는 밤: 중급 양손 반주
- 파란 바람 산책: 쉬운 가요풍 멜로디
- 아침의 작은 왈츠: 중급 피아노 독주
- 미뉴에트 사장조 BWV Anh. 114: 입문 오른손과 쉬운 양손 원곡
- 미뉴에트 내림마장조 WoO 82: 쉬운 오른손과 중급 양손 원곡
- 엘리제를 위하여 WoO 59: 입문 오른손과 쉬운 양손 및 고급 원곡
같은 제목의 난이도와 편곡 형태를 한 묶음에서 고르는 동작은 `첫눈이 내리는 밤`의 두 버전으로 확인한다.
같은 제목의 난이도와 편곡 형태는 한 묶음에서 선택한다. 공개 도메인 원곡에서 만든 단계별 연습 편곡은 `scripts/build_sample_variants.mjs`로 다시 만들 수 있다.
## 악보 표시
MIDI를 선택하면 서버에서 MusicXML로 변환한 뒤 AlphaTab으로 오선 악보를 표시한다. 배포 파일에는 다음 자산을 포함한다.
- Bravura SMuFL 악보 글꼴과 OFL 고지
- AlphaTab 전용 Worker와 AudioWorklet 및 코어 모듈
- `.mjs` 파일의 `application/javascript` MIME 설정
운영 환경에서는 악보 렌더링을 UI 스레드에서 처리한다. Vite 번들과 별도 Worker가 렌더링 자원을 서로 다르게 초기화해 빈 악보가 되던 문제를 피하기 위한 설정이다.
## 초기 관리자
@@ -90,7 +109,7 @@ Bach to Basics의 기존 파일 가져오기 기능을 유지하면서 서버
2. 회원 가입과 로그인 및 로그아웃을 확인한다.
3. 비공개 곡이 다른 회원과 비회원에게 보이지 않는지 확인한다.
4. 회원 공개와 지정 공유 및 최소 등급 제한을 확인한다.
5. MIDI 업로드와 한글 제목 및 태그 검색을 확인한다.
5. MIDI와 MusicXML과 MXL 및 PDF 업로드와 한글 제목 및 태그 검색을 확인한다.
6. 같은 제목의 멜로디와 반주 버전을 각각 불러온다.
7. 비밀번호 변경 후 기존 세션이 끝나는지 확인한다.
8. 시험 회원 탈퇴 후 계정과 업로드가 제거되는지 확인한다.
+27
View File
@@ -0,0 +1,27 @@
# 기본 공개 샘플 출처
곡 보관함의 기본 샘플은 Mutopia Project에서 공개 도메인으로 배포하는 MIDI 자료다. 회원이 올린 파일과 구분하기 위해 서버 시작 시 `seed_key`가 있는 기본 자료로 등록한다.
| 표시 제목 | 작곡가 | 원본 페이지 | 파일 | 권리 표시 |
| --- | --- | --- | --- | --- |
| 미뉴에트 사장조 BWV Anh. 114 | 크리스티안 페촐트 | <https://www.mutopiaproject.org/cgibin/piece-info.cgi?id=75> | `minuet-bwv-anh-114.mid` | Public Domain |
| 미뉴에트 내림마장조 WoO 82 | 루트비히 판 베토벤 | <https://www.mutopiaproject.org/cgibin/piece-info.cgi?id=904> | `menuett-woo-82.mid` | Public Domain |
| 엘리제를 위하여 WoO 59 | 루트비히 판 베토벤 | <https://www.mutopiaproject.org/cgibin/piece-info.cgi?id=931> | `fur-elise.mid` | Public Domain |
Mutopia Project의 배포 안내는 <https://www.mutopiaproject.org/legal.html>에서 확인할 수 있다. 원본 악보의 작곡 저작권과 MIDI 조판 자료의 표시를 혼동하지 않도록 각 곡의 원본 페이지도 함께 기록한다.
## 난이도별 연습 편곡
같은 곡을 단계별로 익힐 수 있도록 위 공개 도메인 MIDI에서 다음 연습 편곡을 만들었다. 원곡의 제목과 작곡가는 유지한다. 곡 보관함에서는 같은 제목 아래에 난이도와 형태가 다른 버전으로 표시한다.
| 원곡 | 단계 | 편곡 내용 | 파일 |
| --- | --- | --- | --- |
| 미뉴에트 사장조 BWV Anh. 114 | 입문 | 느린 오른손 선율 | `minuet-bwv-anh-114-beginner.mid` |
| 미뉴에트 사장조 BWV Anh. 114 | 쉬움 | 양손 원곡 | `minuet-bwv-anh-114.mid` |
| 미뉴에트 내림마장조 WoO 82 | 쉬움 | 느린 오른손 선율 | `menuett-woo-82-easy.mid` |
| 미뉴에트 내림마장조 WoO 82 | 중급 | 양손 원곡 | `menuett-woo-82.mid` |
| 엘리제를 위하여 WoO 59 | 입문 | 첫 주제 오른손 선율 | `fur-elise-beginner.mid` |
| 엘리제를 위하여 WoO 59 | 쉬움 | 첫 주제와 단순화한 왼손 근음 | `fur-elise-easy.mid` |
| 엘리제를 위하여 WoO 59 | 고급 | 전체 양손 원곡 | `fur-elise.mid` |
편곡 파일은 `node scripts/build_sample_variants.mjs`로 다시 만들 수 있다. 원본 MIDI가 바뀌면 생성 결과도 달라지므로 반영 전에 파일 크기와 음표 수와 실제 재생을 다시 검사한다.