🎧
받아둔 플레이리스트를 파일로 갖고 싶은데 마땅한 도구가 없었습니다. 그래서 직접 만들고, 남들도 한 줄로 설치할 수 있게 다듬었습니다.
왜 만들었나
유튜브 플레이리스트를 곡 단위 MP3로, 그것도 가수 - 제목.mp3처럼 정리된 이름과 앨범아트까지 담아 저장하고 싶었습니다. 기존 도구들은 CLI뿐이거나, 태그가 비어 있거나, 특정 OS만 지원하는 경우가 많았습니다. 필요한 걸 직접 만들기로 하고, 설치 장벽까지 없애는 것을 목표로 잡았습니다.
어떻게 동작하나
- URL 붙여넣기: 실행하면 클립보드의 유튜브 URL을 자동으로 인식해 채워 넣고, 입력 후에는 백그라운드로 "제목 · n곡" 미리보기를 보여줍니다.
- 변환: 저장 폴더와 음질(128/192/320kbps)을 고르고 시작하면 yt-dlp로 받아, mutagen으로 아티스트·제목·앨범아트(원본 비율)를 파일에 임베드합니다.
- 중복 방지: 저장 폴더의 아카이브 파일에 받은 항목을 기록해, 같은 URL을 다시 돌려도 새 곡만 받습니다.
직접 부딪힌 문제: 다운로드 중 앱이 죽는다
다운로드 도중 앱이 불규칙하게 강제 종료됐습니다. 크래시 리포트 네 건이 모두 SIGSEGV였지만 죽는 위치가 매번 달라 원인을 좁히기 어려웠습니다. 리포트의 faulting thread가 워커 스레드인데 그 스택에 Qt 페인트 코드가 있는 것을 단서로, 진행률 시그널을 람다에 연결한 게 문제임을 확인했습니다.
PySide6에서 시그널을 람다·일반 함수에 연결하면 큐잉 없이 워커 스레드에서 직접 실행돼, UI 위젯을 워커 스레드가 건드리게 됩니다. 시그널 슬롯을 전부 QObject 바운드 메서드로 바꿔 메인 스레드에서 실행되도록 고치자 재현이 사라졌습니다.
설치까지가 제품
개인 도구라도 "받아서 바로 쓰기"가 되어야 한다고 봐서, uv 기반 원클릭 설치 스크립트를 붙였습니다(mac·Linux는 curl | sh, Windows는 PowerShell 한 줄). ffmpeg가 없으면 정적 빌드를 자동으로 받아 캐시에 두고, macOS에서는 신호등 버튼을 살린 프레임리스 글래스 창에 라이트/다크를 시스템 설정에 따라 자동 전환합니다.