music.crowny.org — 크라우니 중앙 음악 허브 (스트리밍 + 음원발매 + 노래방)
개요
크라우니마을 생태계의
중앙 음악 허브. 에덴고·크라우니OS가 음원을 각자 배치하던 비효율(싸이월드 BGM 시대의 교훈)을 끝내고, music이 음원을 중앙화해 다른 서비스가
/api/music/*로 끌어쓴다. 3기둥:
①음악 스트리밍 ②음원 발매/배급(mixtape.so식) ③노래방(golden 시니어 장비 연동).
- 도메인/포트: music.crowny.org → :9886 (gateway.yaml SSOT), golden.crowny.org → :9967(신규 할당)
- 디렉토리:
/Users/ef/crowny-music, /Users/ef/crowny-golden
- 빌드: 울트라 워크플로우(opus 설계 4 + opus 종합 1 + sonnet 빌드 4 + sonnet 검증 3 = 12 에이전트, 721k 토큰)
- 첫 발매 아티스트: 한선피아노
무엇을 했나
3기둥 구현
- 스트리밍: Spotify식 라이브러리/플레이어/플레이리스트 + 연속재생/셔플/미니플레이어. 싸이월드식 프로필BGM·도토리(맘/포네) 후원 레이어. 중앙화 BGM API(
/api/music/bgm, 서비스키 게이트)로 에덴고·크라우니OS가 소비. 일반브라우저 mp3 + 크라우니브라우저 CAF7 더블.
- 음원 발매/배급: 7단계 상태기계(초안→메타입력→커버업로드→검수→배급대기→라이브→정산), 4상 검수판정(티/옴/타/음), 균형3진 식별자 발급(CRR/CRM, 예:
CRR-AOO-26-00001), 배급채널 추상화(외부 플랫폼명 거명 0 — 가/나/다 채널), 정산(재생 1회=5맘, 크라우니 수수료 15%, 1맘=255포네), 아티스트 대시보드.
- 노래방: LRC 가사싱크·간이채점·리더보드. 카탈로그는 발매/스트리밍과 단일 SSOT 공유(중복배치 금지). golden(:9967)은 별도 서버로 music의
/api/karaoke/*·오디오를 역프록시 — 시니어 모드(초대형글씨·고대비·번호선택·핀치줌 허용).
아키텍처
server.js(Node, 단일 라우팅 게이트) = 공유 커머스 엔진(../crowny-commerce-engine/엔진.js) 재사용: 회원·관리자·서비스키·정적서빙·오디오 206 Range 스트리밍. 비즈니스 로직 SSOT는 한선씨 17엔진(.한선→.toau, selfHeal 재컴파일).
- 라우터
routes/{music,release,karaoke}.js lazy try-require → 병렬빌드 무충돌.
검증 결과
- 한선씨 17엔진 전부 컴파일 ✓ (발매상태기계는 VM함정
목록꺼내 미존재 → 배열[i]로 수정 후 통과)
- 서버 기동·핵심 API 200, 오디오 Range 206, BGM 서비스키 게이트 401 ✓
- 게이트웨이 핫리로드로 양 도메인 라우팅 ✓
- freestyle 실음원(1.2MB) 재생 200 검증 ✓
수정한 버그(검증→교정)
routes/release.js: 공유엔진은 http export인데 httpx로 구조분해 → POST 진입 크래시. http: httpx 별칭 + 절대경로 require→상대경로.
server.js: 미매칭 라우트 null 반환 후 무응답 hang → === null 시 404 폴백(release·karaoke).
- 세 기둥 진입점 404(병렬빌더 파일명 불일치):
/music/(index.html 없음→library+stream 통합), /artist/(허브 index 신설), /karaoke/golden(→ golden.crowny.org 외부 링크). karaoke.css @import /music.css→/css/music.css.
- 디자인토큰 위반(하드코딩 색) 전부 crowny.org SSOT var로, 모바일 터치타깃 28/40/36px→44px.
관련 파일
- 백엔드:
/Users/ef/crowny-music/server.js, routes/{music,release,karaoke}.js, api/stream.js
- 한선씨 엔진:
/Users/ef/crowny-music/한선/*.한선 (17개, 학습DB music_* 등록)
- 프론트:
public/{index.html, music/, artist/, karaoke/, css/}
- golden:
/Users/ef/crowny-golden/{server.js, 한선/*, public/*}
- 데이터 SSOT:
data/index/tracks-shard-0.jsonl(스트리밍 리스트), data/카탈로그.jsonl(발매 SSOT), data/tracks.seed.json(앨범/아티스트)
- CLAUDE.md:
/Users/ef/crowny-music/CLAUDE.md
잔여 이슈
- 한선피아노 마스터 2곡(courage to change, 사랑하기때문에) 오디오 미배치: Desktop 원본이 이 환경에서 iCloud evicted라 cp/cat 타임아웃(per-file eviction). 메타데이터·가사·카탈로그 엔트리는 완비. 사용자 Mac에서 두 파일을 iCloud 다운로드 후
cd /Users/ef/crowny-music && bash deploy.sh 실행하면 자동 배치(deploy.sh에 cp 로직 존재). 현재는 freestyle(로컬 1.2MB)가 실 재생 시드.
- 카탈로그 3중 소스 분기(병렬빌더 산물): tracks-shard-0.jsonl(스트리밍 리스트가 읽음) / 카탈로그.jsonl(발매 SSOT) / tracks.seed.json(앨범). 신곡 추가 시 3곳 동기 필요 → 차후 시드적재.한선이 셋을 단일 생성하도록 통합 권장.
- 부팅 영속성 미설치: LaunchAgent(org.crowny.music/golden)는 자동영속 차단됨(사용자 명시 필요). 현재 세션 백그라운드 기동만. 영속하려면 plist 작성 후
launchctl load -w.
- 크라우니마을 생태계 UI는 별도(사용자 지시) — 현재는 일반 사이트 디자인.
생태계 연동
- 에덴고/크라우니OS:
X-Service-Key로 /api/music/bgm·/api/catalog 소비 → BGM 중앙화.
- 보상화폐: 맘/포네(crowny-pay), 후원·정산 연동.
추가: 발매확인 큐 도구 (2026-06-28)
사용자 요청 — "음원 파일 찾아서, 아이디 공개한 사용자가 '확인' 명령만 하면 런칭".
- 사용:
./확인 (탐색+대기열) / ./확인 확인 <번호|전체> (런칭) / ./확인 소스 추가 <경로>
- 판정 SSOT:
한선/발매확인.한선(컴파일됨) — 4상: 등록아티스트+로컬파일+메타 → 티(런칭) / iCloud미다운로드·메타부족 → 옴 / 파일없음 → 타 / 미등록 → 음.
- 집행:
tools/발매확인.js — dd 1블록 프로브로 iCloud evicted 감지, temp→rename 안전복사(0바이트 오염 차단), 3개 카탈로그 소스(shard/카탈로그.jsonl/seed) 일괄 갱신 + 오디오 배치 + 라이브.
- 탐색소스:
data/발매소스.json (inbox/ 폴더 + Desktop hansunpiano 패턴).
- 검증: Desktop 16파일 탐색 → JIIN.S(14MB 실음원) 런칭 →
/api/music/tracks 즉시 반영, 스트림 200. courage/사랑하기때문에는 iCloud evicted라 ⏳ 표시(다운로드 후 확인).
- 함정: macOS 파일명 NFD → 한글 trackId 뭉개짐 →
normalize('NFC') 필수. crownyc stderr 노이즈 → stdio:['ignore','pipe','ignore'].