카테고리 없음

커버송에는 왜 가사 싱크가 없을까? 궁금해서 직접 만들어봤습니다

csiimnida 2026. 9. 15. 23:42

스포티파이를 사용하며 노래 가사가 나오는 시스템을 확인했습니다.

 

이를 보며 노래 가사 관련 궁금증이 생겼습니다.

가사 출처가 어디인지….
싱크는 어떻게 맞추는지….

그래서 저는 찾아봤고, 쉽게 답을 찾을 수 있게 됐습니다.

 

줄별 시각이 있는 LRC라는 포맷이 있고,


LRCLIB이라는 가사 OpenDB가 있었습니다.

 

 

여기까지는 간단했습니다. LRCLIB에 곡 제목과 아티스트를 넘기면 LRC를 주고,
재생 시각과 비교하며 줄을 넘기면 끝입니다.

그런데 또다른 궁금증이 생겼습니다.

 

커버송에는 가사가 없는데
왜 없을까?
못하는건가?

 

 

직접 만들어보면 알겠다 싶었습니다.
그래서 커버송 영상(유튜브)을 주면 그 곡의 가사를 찾아주는 걸 만들어보기로 했습니다.

 

만들어보니 이유를 알았습니다

OpenDB에 요청하려면 곡 제목과 아티스트가 필요합니다.
그런데 제가 가진 건 유튜브 영상 제목뿐입니다. 그리고 유튜브 제목은 이렇게 생겼습니다.

【음율】곡명 / covered by 가수명
Ditto - NewJeans
[MV] 아이유(IU) _ 좋은 날 (Official)

 

처음에는 단순 if문으로 제목과 가사를 찾았습니다. 대괄호를 떼고, covered by 뒤를 잡고,
Official이나 4K 같은 장식을 걷어내고… 그렇게 만든 if문이15개까지 늘었습니다.
그리고 벽에 부딪혔습니다.

 

if문으로는 절대 안 되는 게 두 가지 있었습니다.

첫째, 커버곡의 원곡 아티스트입니다. 가사는 원곡의 것이라 원곡자로 찾아야 하는데,
커버 영상 제목에는 부른 사람 이름만 있습니다. 없는 정보를 정규식으로 뽑을 방법은 없습니다.

 

둘째, 어느 쪽이 곡명인지입니다. Ditto - NewJeans가 곡-아티스트 순인지
아티스트-곡 순인지, 문자열만 봐서는 알 수 없습니다.

 

그리고 사용자 입장에서는 가사가 없는 것보다 가사가 틀린 게 훨씬 나쁩니다.

커버송에 싱크가 없는 건 못해서가 아니라, 곡을 특정하기가 어렵기 때문이었습니다.

 

그래서 AI를 붙였습니다

Google의 Gemini API를 골랐습니다. 이 작업은 곡당 한두 번이고 결과를 캐시하니
호출량이 작아서 무료 티어를 선택했습니다.

 

유튜브 제목에서 곡명과 원곡 아티스트를 뽑습니다.
여기서 제일 중요했던 건 프롬프트에 넣은 이 한 줄이었습니다.

 

This is a lookup key, not a guess: if you are not reasonably sure of a field, use null rather than inventing something. A null field is handled fine downstream.

 

 

모르면 null을 써라, null이어도 뒤에서 알아서 처리한다는 뜻입니다.


이걸 넣기 전과 후가 확실히 달랐습니다. AI 모델은 빈칸을 싫어합니다.

모르는 곡이 나오면 그럴듯한 이름을 지어냈습니다. 빈칸을 허락해 줘야 지어내지 않습니다.

 

만들어보니 이유를 알았습니다

이젠 커버송을 검색하면 가사가 뜹니다.

AI가 원곡을 짚어주면, 그다음부터는 원래 되던 일이었습니다.
LRCLIB에 넘길 곡 제목과 아티스트가 생기니까요.

제가 부딪힌 문제는 곡을 특정하는 일이었습니다.

 

 

긴 글 읽어주셔서 감사합니다.

 

깃허브 : https://github.com/csiimnida/CsiMusic_AI