작성 일자 : 2026-01-05얼마 전 호연이 형이 음악의 BPM과 Key를 찾을 수 있는 프로그램을 만들 수 있냐고 제의를 받았다.
프로그램 기획부터 설계 구현까지 진행했던 내용을 정리해보겠다. 또한 진행하면서 겪은 시행착오와 현재 마주한 한계점과 개선점 순서대로 정리해보겠다.
기획
처음 제의가 왔을 때 사용 목적에 대해 구체적으로 물어봤다. 목적을 이해했을 때 클라이언트는 유튜브 환경에서 음원을 자주 들으며, 즉석해서 BPM과 Key를 확인하기 원함.
그러면 스트리밍 환경이기 때문에 mp3, wav같은 파일을 직접 소지하지는 않을 것임.
웹 페이지 내에서 유튜브 링크 자체로만 파악이 가능한 설계가 필요함.
INPUT : 유튜브 링크 OUTPUT : BPM, Key
설계
화면 설계

필요 기술
1. yt-dlp : 유튜브로 부터 음원을 내려받는 도구
- 웹페이지 분석 후 실제 미디어 스트림(URL)을 찾아내고 그걸 다운로드함.
2. ffmpeg : 미디어를 읽고, 변환하고, 자르는 도구
- 오디오 디코딩
- 포맷 변환
- 샘플레이트 변경
- 채널 변경
- 길이 자르기
3. ibrosa : 오디오 파일을 숫자 배열로 바꿔서 음향을 분석하는 라이브러리
- 핵심 라이브러리
- 오디오 분석 필수
핵심
음악을 잘 모르는 나는 음정을 찾는 방식을 정하기 전, ‘사람’은 어떻게 음정을 찾는지 들었지만 그리 도움이 되진 못했다. 그래서 나보다 똑똑한 사람들이 모여있는 깃허브의 탐방을 시작했다.
역시 나보다 똑똑하신 분들이 이미 고민해둔 흔적을 찾아 이를 확인하고 공부하여 사용하였다.
git_url :https://github.com/Corentin-Lcs/music-key-finder
관련 paper (안읽어봄) : https://static1.1.sqspcdn.com/static/f/221758/23618809/1380667475290/KrumhanslKessler1982TracingPerceviedTonalOrg-SpatialRep-Keys.pdf
Highlight : Krumhansl–Schmuckler 알고리즘
곡에서 추출한 12개 음의 분포(크로마)를, 사람이 인지한 장·단조 키의 전형적인 분포(키 프로파일)와 비교해 가장 유사한 조성을 찾는 알고리즘.
1982년 Krumhansl & Kessler의 probe-tone 실험에서 나온 C장조 / C단조 기준의 ‘키 프로파일’을 가지고 시작한다.

-
preprocess_audio 음원을 숫자 배열로 가져오는 과정
-
compute_chroma_vector 음악은 음이 계속 바뀌고 세기도 다르다. 이까지 반영하기 위해 ‘에너지’라는 개념을 도입한다. 강도(얼마나 볼륨이 큰지) , 지속도 (얼마나 음이 길게 끌리는지) , 빈도 (간접적이지만 얼마나 자주 나오는지) 이들을 복합적으로 판단하여 에너지라는 값으로 각 음이 얼마나 영향이 높은지 파악하는 과정이다.
-
compute_ks_correlations 장조와 단조를 복합적으로 판단하여 상관관계를 구하는 과정이다. 위에서 구한 에너지와 처음에 나온 음정 프로파일을 바탕으로 상관관계를 구하게 된다.
이처럼 키는 돌아가기 때문에 나온 에너지 값들을 바탕으로 프로파일을 돌려서 유사도를 찾는다고 이해하면 편할 것 같다.
구현 완료
예시로 E key의 곡, bpm 68의 곡을 넣었다.
BPM 68 정상적으로 판단되며 예상 키도 0.895의 상관관계로 값이 나오게 된다.

시간 또한 10초 내외로 준수한 성능을 보여준다. (나름..?)
시행착오
-
Key 찾기의 부족한 정확도
- Krumhansl - Schmuckler 방식 도입
- 음원 시간 늘리기
-
느린 음원 추출 속도
- mp3 → wav로 변경
- 대부분 wav보다 mp3의 용량이 적기 때문에 mp3를 처음에 채택함.
- 하지만 wav로 나온걸 mp3로 다시 만들어내는 자원 낭비 발견함.
- wav추출 속도가 더 빠른 것을 확인하고 wav로 사용 결정
- Buffer 방식에서 Tempfile (임시 저장하는 방식)
- PC 메모리 내부에서 스트리밍 식으로 처리하면 더 빠를 것이라고 생각함.
- 여러 방식 시도 과정 속에서 Tempfile로 임시 저장하는 방식이 가장 빨랐음.
- 기존에는 26초 가량 걸리는 과정을 15초, 8초, 5초까지 줄였음. (PC+네트워크 상황에 따라 상이함)
- mp3 → wav로 변경
한계점
- 유튜브에서 음원 추출이 불가능함
- 배포환경 (Streamlit Cloud)의 유튜브 크롤링 금지 정책 (ip ban)
- yt-dlp 이후 tempfile or buffer을 사용 가능한지 미정.
- 정적 파일 배포하는 사이트여서 가능한지 미정임.
개선점
-
직접 음원을 넣는 방식? → 탈락
- 기획 취지와 달라짐 (편하고 빠르게)
- 이것 또한 서버에 파일을 올려야하기 때문에 가능성이 없을 수 있음.
- 속도 이슈도 있음.
-
배포 환경의 변경? → 고민중
- 제한된 환경 (Streamlit Cloud)에서 벗어나서 직접 배포?
- Docker로 말아야함
- AWS로 배포? (유료임, Freetier 다 사용함)