유튜브 가사 자막 자동 생성|챕터까지 만드는 VocalUploader
YouTubeUploader 이야기를 몇 편 쓰고 나니 자연스럽게 다음 질문이 생겼다.
“그럼 보컬 곡은 어떻게 올리지?”
처음 YouTubeUploader를 만들 때 염두에 둔 것은 보컬이 없는 긴 플레이리스트 영상이었다. 하지만 보컬 곡도 하나둘 만들기 시작하면서, 여러 곡을 이어 붙인 모음집 형태의 영상도 올리고 싶어졌다.
문제는 기존 프로그램만으로는 처리하기 어려운 일이 많다는 것이었다. 영상 안에 곡이 하나가 아니라 여러 개 들어가고, 각 곡의 시작 지점에 맞춰 챕터를 나눠야 했다. 무엇보다 보컬 곡에는 가사를 자막으로 넣는 기능이 필요했다.
그래서 여러 곡의 챕터를 계산하고 가사를 음원에 맞춰주는 유튜브 가사 자막 자동 생성 프로그램을 만들었다. 이름은 VocalUploader다.

유튜브 가사 자막 자동 생성에 필요한 세 가지 작업
곡 파일을 순서대로 불러오면 VocalUploader가 처리하는 일은 크게 세 가지다.
첫 번째는 전체 타임라인과 유튜브 챕터를 만드는 일이다.
프로그램이 각 곡의 재생 시간을 확인하고 누적 시각을 계산하면, 몇 분 몇 초부터 어떤 곡이 시작되는지를 보여주는 챕터 목록이 자동으로 만들어진다.
유튜브에서 챕터로 인식되려면 첫 타임스탬프가 00:00으로 시작해야 하고, 최소 3개 이상의 타임스탬프가 순서대로 들어가야 한다. 각 챕터의 길이도 10초 이상이어야 한다. 프로그램은 이 조건을 확인해 문제가 있으면 업로드 전에 경고하도록 만들었다.
두 번째는 가사를 노래에 맞춰 자막으로 만드는 일이다.
각 음원 파일과 같은 이름의 가사 텍스트 파일을 준비해두면 된다. 예를 들어 01_rainy_night.mp3가 있다면 같은 폴더에 01_rainy_night.txt를 함께 넣는 방식이다.
이 유튜브 가사 자막 자동 생성 과정에서 가장 중요한 기능이 바로 강제정렬이다.
프로그램은 음원과 가사를 Whisper 계열의 AI 모델에 전달해 각 가사 줄이 노래의 어느 지점에서 시작되고 끝나는지 찾아낸다.
이 작업을 강제정렬(forced alignment)이라고 한다. 음성을 처음부터 받아쓰게 하는 것이 아니라, 이미 정확한 가사가 주어진 상태에서 시간만 맞추는 방식이다. 그래서 일반적인 음성 인식보다 가사의 타이밍을 안정적으로 찾을 수 있다.
가사 파일에 [Verse], [Chorus], [Bridge] 같은 곡의 구조를 표시하는 태그가 들어 있어도 자막에서는 자동으로 제외한다.
각 곡의 가사 타이밍을 찾은 다음에는 이를 전체 모음집 영상의 시간으로 다시 환산한다. 두 번째 곡이 영상 시작 후 3분 20초에 시작한다면, 그 곡의 모든 자막 시간에도 3분 20초를 더하는 식이다.
이 과정을 모든 곡에 적용해 하나로 합치면 영상 전체를 아우르는 SRT 자막 파일이 완성된다.
세 번째는 번역과 유튜브 업로드다.
영어 제목과 설명을 입력하면 미리 설정한 언어로 자동 번역한다. 완성된 영상 파일을 선택하면 영상과 함께 언어별 제목·설명, 챕터, 영어 자막을 유튜브에 한 번에 등록한다.
기본적인 번역과 업로드 방식은 기존 YouTubeUploader와 같다. 다만 두 프로그램의 코드를 다시 살펴보다 보니 재미있는 차이도 발견했다.
YouTubeUploader는 번역 과정에서 챕터, 해시태그, 고유명사처럼 번역하면 안 되는 부분을 보호하는 방식을 여러 번 수정하며 안정화했다. 반면 VocalUploader에는 그보다 이전에 만들었던 코드가 일부 남아 있었다.
같은 프로그램에서 출발했지만 필요한 기능을 그때그때 덧붙이다 보니, 어느새 서로 다른 속도로 자라고 있었던 것이다.
권한 문제인 줄 알았는데 파일이 바뀌지 않았다
유튜브 가사 자막 자동 생성 기능을 실제 업로드 과정에 연결하자, 영상과 제목·설명은 정상적으로 등록되는데 자막만 올라가지 않는 문제가 생겼다.
처음에는 단순한 권한 문제처럼 보였다.
유튜브에 영상을 올리거나 제목과 설명을 수정하는 권한과 자막 트랙을 등록하는 권한은 구분되어 있다. 기존 프로그램이 요청하던 권한 설정만으로는 자막을 등록하는 captions.insert 호출이 승인되지 않았고, 자막 관련 작업에 필요한 youtube.force-ssl 권한을 요청 목록에 추가해야 했다.
새로운 API를 따로 활성화할 필요는 없었다. 이미 사용 중인 YouTube Data API v3에 포함된 권한이어서 코드의 스코프 목록에 항목을 추가하면 됐다.
코드를 수정한 뒤 기존 로그인 정보가 저장된 token.json을 삭제하고 프로그램을 다시 실행했다. 그러면 이전 권한으로 발급받은 토큰이 사라지고, 새로운 권한에 동의하는 로그인 화면이 다시 나타나는 구조였다.
그런데 재로그인까지 마쳤는데도 자막 등록은 계속 실패했다. 새로 생성된 token.json을 확인해보니 권한 목록에 youtube.force-ssl이 들어 있지 않았다.
코드는 분명히 고쳤고 로그인 화면도 다시 열렸는데, 프로그램은 여전히 새 권한을 요청하지 않고 있었다.
토큰이 실제로 새로 생성됐는지, 실행 중인 코드에 수정한 내용이 들어 있는지, 로그인 화면에 새로운 권한 항목이 나타났는지를 하나씩 확인했다.
그제야 원인을 찾았다.
수정된 코드 파일을 실제 프로그램이 설치된 폴더에 제대로 덮어쓰지 않았던 것이다. 코드는 수정되어 있었지만, 프로그램이 실행하고 있던 것은 여전히 이전 버전의 파일이었다.
그러니 token.json을 몇 번 지우고 다시 로그인해도 결과가 달라질 리 없었다. 프로그램은 처음부터 새로운 권한을 요청한 적이 없었기 때문이다.
수정된 파일을 정확한 폴더에 덮어쓰고 다시 토큰을 삭제한 뒤 프로그램을 실행했다. 이번에는 로그인 화면에 자막 관련 권한 항목이 나타났다. 권한을 승인하자 자막도 정상적으로 등록됐다.
에러 메시지는 권한이 부족하다고 알려주고 있었지만, 진짜 문제는 그보다 한 단계 앞에 있었다.
“내가 수정한 코드가 실제로 실행되고 있는가?”
너무 당연해 보여서 오히려 늦게 확인한 부분이었다.
완성했지만 자막 기능은 아직 대기 중이다
여기까지 자막 기능을 완성했지만, 실제 보컬 모음집을 올릴 때는 아직 직접 만든 SRT 자막을 사용하지 않고 있다.
VocalUploader로 챕터와 업로드 작업은 처리할 수 있지만, 자막 기능만큼은 실전 사용을 미뤄둔 상태다.
물론 유튜브 자동 자막이 노래 가사를 완벽하게 받아쓰는 것은 아니다. 보컬의 음색이나 반주 상태에 따라 가사를 잘못 인식하거나 아예 자막이 만들어지지 않을 수도 있다.
다만 긴 음악 모음집에서 시청자가 가사 자막을 실제로 얼마나 사용할지 아직 판단하기 어려웠다. 직접 만든 SRT를 매번 검토하고 등록해야 할 필요성도 당장은 크게 느끼지 못했다.
대신 이 기능이 꼭 필요해질 만한 용도가 하나 있다.
Shorts다.
Shorts에서는 유튜브 가사 자막 자동 생성 기능의 활용도가 더 높아질 수 있다.
짧은 노래 클립에서는 가사가 화면에 직접 나타나는 것이 중요하다. 이때는 유튜브 플레이어의 자동 자막만으로는 부족하고, 영상 편집에 사용할 정확한 자막 타이밍이 필요하다.
VocalUploader가 만든 SRT를 영상 편집 프로그램으로 가져오면 각 가사 줄을 음원에 맞춰 직접 배치하는 작업을 크게 줄일 수 있다. 곡 전체가 아니라 짧은 구간만 사용하더라도 강제정렬의 원리는 같다.
그래서 VocalUploader의 유튜브 가사 자막 자동 생성 기능은 실패하거나 버려진 기능이 아니다.
완성됐지만 아직 알맞은 쓰임을 기다리고 있는 기능에 가깝다.
도구뿐 아니라 작업 방식도 바뀌었다
파일을 잘못된 폴더에 옮겼던 일은 이후 프로그램을 만드는 방식까지 다시 생각하게 했다.
당시에는 대화창에서 수정된 코드를 받아 내가 직접 파일을 내려받고, 프로그램 폴더에 옮기고, 기존 파일을 교체한 뒤 다시 실행했다. 그 과정에는 언제든 다른 버전의 파일을 옮기거나 엉뚱한 위치에 저장할 가능성이 있었다.
코드 자체가 정확해도 실제 실행 파일이 바뀌지 않으면 아무 소용이 없었다.
그렇다고 곧바로 작업 방식을 바꾼 것은 아니었다. VocalUploader를 만든 뒤에도 유튜브 채널에 등록된 제목과 설명을 여러 언어로 관리하는 채널 로컬리제이션 프로그램을 같은 방식으로 한 번 더 만들었다.
그 작업까지 마치고 나서야 대화창에서 코드를 받아 내가 직접 파일을 옮기는 방식에서 벗어났다. 이후 프로그램부터는 Claude Code가 실제 프로그램 폴더를 확인하고, 필요한 파일을 직접 수정하고, 실행 결과까지 점검하는 방식으로 작업하기 시작했다.
VocalUploader는 보컬 모음집을 자동으로 올리기 위해 만든 도구였다. 하지만 돌이켜보면 새로운 기능 하나를 추가한 것보다, 자동화 도구를 만드는 과정에도 더 안전하고 효율적인 작업 흐름이 필요하다는 사실을 깨닫게 한 프로그램에 가까웠다.
그리고 작업 방식이 바뀌자, 그다음부터 만들 수 있는 프로그램의 범위도 조금씩 달라지기 시작했다. 그 이야기는 VocalUploader 이후에 만든 도구들과 함께 다음 글에서 이어가려고 한다.
Rain on Porcelain에서 더 알아보기
구독을 신청하면 최신 게시물을 이메일로 받아볼 수 있습니다.