-
-
Notifications
You must be signed in to change notification settings - Fork 12
Creating Lyrics Addons ko
ivLis edited this page Jan 22, 2026
·
1 revision
ivLyrics용 커스텀 가사 제공자 애드온을 만드는 방법을 설명합니다.
가사 애드온은 다양한 소스에서 가사를 제공합니다. LyricsAddonManager에 등록되며 사용자가 활성화/비활성화하고 우선순위를 설정할 수 있습니다.
(function() {
'use strict';
const addon = {
// 필수: 고유 식별자
id: 'my-lyrics-provider',
// 필수: 표시 이름
name: 'My Lyrics Provider',
// 필수: 제작자 이름
author: 'Your Name',
// 필수: 설명
description: {
en: 'Fetch lyrics from My Service',
ko: 'My Service에서 가사 가져오기'
},
// 필수: 지원하는 가사 유형
supports: {
karaoke: false, // 단어별 싱크
synced: true, // 줄별 싱크
unsynced: true // 타이밍 없음
},
// 선택: ivLyrics Sync 지원
supportsIvSync: false,
// 선택: 설정 UI
getSettingsUI: function() {
return null;
},
// 선택: 애드온 초기화
init: async function() {
console.log('My Lyrics Provider initialized');
},
// 필수: 가사 가져오기
getLyrics: async function(info) {
// info: { uri, title, artist, album, duration }
// 반환: LyricsResult 또는 null
}
};
function register() {
if (window.LyricsAddonManager) {
window.LyricsAddonManager.register(addon);
} else {
setTimeout(register, 100);
}
}
register();
})();- 고유 식별자 문자열
- 소문자와 하이픈 사용
- 예시:
'my-lyrics-provider'
- 설정에 표시되는 이름
- 예시:
'My Lyrics Provider'
- 제작자 이름
- 예시:
'Your Name'
문자열 또는 다국어 객체:
description: {
en: 'English description',
ko: '한국어 설명'
}제공자가 반환할 수 있는 가사 유형 정의:
supports: {
karaoke: false, // 단어별 하이라이팅
synced: true, // 줄 수준 타임스탬프
unsynced: true // 일반 가사
}{
type: 'unsynced',
provider: 'my-lyrics-provider',
lines: [
{ text: '가사 첫 번째 줄' },
{ text: '가사 두 번째 줄' },
{ text: '' }, // 간격을 위한 빈 줄
{ text: '가사 세 번째 줄' }
]
}{
type: 'synced',
provider: 'my-lyrics-provider',
lines: [
{
startTime: 0, // 밀리초
endTime: 3500, // 밀리초 (선택)
text: '첫 번째 줄'
},
{
startTime: 3500,
endTime: 7000,
text: '두 번째 줄'
}
]
}{
type: 'karaoke',
provider: 'my-lyrics-provider',
lines: [
{
startTime: 0,
endTime: 3500,
text: '첫 번째 줄 단어들',
words: [
{ startTime: 0, endTime: 800, text: '첫' },
{ startTime: 800, endTime: 1500, text: '번째' },
{ startTime: 1500, endTime: 2500, text: '줄' },
{ startTime: 2500, endTime: 3500, text: '단어들' }
]
}
]
}async getLyrics(info) {
// info 객체 내용:
// - uri: Spotify 트랙 URI (예: 'spotify:track:xxx')
// - title: 트랙 제목
// - artist: 아티스트 이름
// - album: 앨범 이름
// - duration: 트랙 길이 (밀리초)
}// 가사 성공
return {
type: 'synced',
provider: 'my-lyrics-provider',
lines: [...]
};
// 가사를 찾지 못함
return null;
// 오류 (null 반환, 선택적으로 오류 로그)
console.error('가사 가져오기 실패:', error);
return null;(function() {
'use strict';
const addon = {
id: 'my-lrc-provider',
name: 'My LRC Provider',
author: 'Developer',
description: 'LRC 형식 가사 가져오기',
supports: {
karaoke: false,
synced: true,
unsynced: true
},
getLyrics: async function(info) {
try {
// 검색 URL 생성
const url = new URL('https://api.example.com/lyrics');
url.searchParams.set('track', info.title);
url.searchParams.set('artist', info.artist);
const response = await fetch(url.toString());
if (!response.ok) {
return null;
}
const data = await response.json();
if (!data.lyrics) {
return null;
}
// LRC 형식 파싱
if (data.syncedLyrics) {
return this.parseSyncedLyrics(data.syncedLyrics);
} else if (data.plainLyrics) {
return this.parsePlainLyrics(data.plainLyrics);
}
return null;
} catch (error) {
console.error('[MyLRCProvider] 오류:', error);
return null;
}
},
parseSyncedLyrics: function(lrcText) {
const lines = [];
const regex = /\[(\d{2}):(\d{2})\.(\d{2,3})\](.*)/g;
let match;
while ((match = regex.exec(lrcText)) !== null) {
const minutes = parseInt(match[1]);
const seconds = parseInt(match[2]);
const ms = parseInt(match[3].padEnd(3, '0'));
const text = match[4].trim();
const startTime = (minutes * 60 + seconds) * 1000 + ms;
lines.push({ startTime, text });
}
// 종료 시간 계산
for (let i = 0; i < lines.length - 1; i++) {
lines[i].endTime = lines[i + 1].startTime;
}
if (lines.length > 0) {
lines[lines.length - 1].endTime =
lines[lines.length - 1].startTime + 5000;
}
return {
type: 'synced',
provider: 'my-lrc-provider',
lines
};
},
parsePlainLyrics: function(text) {
const lines = text.split('\n').map(line => ({
text: line.trim()
}));
return {
type: 'unsynced',
provider: 'my-lrc-provider',
lines
};
}
};
function register() {
if (window.LyricsAddonManager) {
window.LyricsAddonManager.register(addon);
} else {
setTimeout(register, 100);
}
}
register();
})();애드온별 설정 가져오기/저장:
// 설정 가져오기
const value = window.LyricsAddonManager.getAddonSetting(
'my-lyrics-provider',
'settingKey',
'defaultValue'
);
// 설정 저장
window.LyricsAddonManager.setAddonSetting(
'my-lyrics-provider',
'settingKey',
'newValue'
);manifest.json에 애드온 추가:
{
"subfiles_extension": [
"Addon_Lyrics_MyProvider.js"
]
}- 애드온 파일 생성
- manifest.json에 추가
-
spicetify apply실행 - 설정 > Lyrics Providers 열기
- 제공자 활성화 및 우선순위 조정
- 노래를 재생하여 테스트
- 검색 정확도: 제목/아티스트에 퍼지 매칭 사용
- 폴백: 여러 검색 전략 시도
- 오류 처리: 오류 시 우아하게 null 반환
- 성능: 가능하면 결과 캐싱
- 속도 제한: API 제한 준수
사용자가 제공자 순서를 재정렬할 수 있습니다. 매니저는 가사를 반환할 때까지 순서대로 제공자를 시도합니다:
사용자 우선순위: [Spotify, MyProvider, LRCLIB]
1. Spotify 시도 → 가사 없음 → 계속
2. MyProvider 시도 → 가사 반환 → 중지