Skip to content

Creating AI Addons ko

ivLis edited this page Jan 22, 2026 · 1 revision

AI 애드온 개발

English

ivLyrics용 커스텀 AI 제공자 애드온을 만드는 방법을 설명합니다.


개요

AI 애드온은 번역, 발음 표기, 메타데이터 번역, TMI(Track Music Info) 기능을 제공합니다. AIAddonManager에 등록되며 사용자가 활성화/비활성화할 수 있습니다.


애드온 구조

기본 템플릿

(function() {
    'use strict';

    const addon = {
        // 필수: 고유 식별자
        id: 'my-ai-provider',

        // 필수: 표시 이름
        name: 'My AI Provider',

        // 필수: 제작자 이름
        author: 'Your Name',

        // 필수: 설명 (문자열 또는 다국어 객체)
        description: {
            en: 'My custom AI provider for translation',
            ko: '번역을 위한 커스텀 AI 제공자'
        },

        // 필수: 지원하는 기능
        supports: {
            translate: true,
            metadata: true,
            tmi: false
        },

        // 선택: 설정 UI
        getSettingsUI: function() {
            // React 컴포넌트 또는 null 반환
            return null;
        },

        // 선택: 애드온 초기화
        init: async function() {
            console.log('My AI Provider initialized');
        },

        // supports.translate = true인 경우 필수
        translate: async function(params) {
            // params: { lyrics, sourceLang, targetLang, mode }
            // 반환: { lines: [...], error: null } 또는 { error: 'message' }
        },

        // supports.metadata = true인 경우 필수
        translateMetadata: async function(params) {
            // params: { title, artist, lang }
            // 반환: { title, artist } 또는 null
        },

        // supports.tmi = true인 경우 필수
        generateTMI: async function(params) {
            // params: { title, artist, album, lyrics }
            // 반환: { content: '...', error: null }
        }
    };

    // AIAddonManager가 사용 가능할 때까지 대기
    function register() {
        if (window.AIAddonManager) {
            window.AIAddonManager.register(addon);
        } else {
            setTimeout(register, 100);
        }
    }
    register();
})();

필수 필드

id

  • 고유 식별자 문자열
  • 소문자와 하이픈 사용
  • 예시: 'my-ai-provider'

name

  • 설정에 표시되는 이름
  • 예시: 'My AI Provider'

author

  • 크레딧을 위한 제작자 이름
  • 예시: 'Your Name'

description

단순 문자열 또는 다국어 객체:

// 단순
description: '설명 텍스트'

// 다국어
description: {
    en: 'English description',
    ko: '한국어 설명',
    ja: '日本語の説明'
}

supports

애드온이 제공하는 기능을 정의하는 객체:

supports: {
    translate: true,    // 가사 번역
    metadata: true,     // 제목/아티스트 번역
    tmi: false          // 트랙 정보 생성
}

메서드

translate(params)

가사를 대상 언어로 번역합니다.

매개변수:

{
    lyrics: [
        { text: 'Line 1', startTime: 0 },
        { text: 'Line 2', startTime: 5000 }
    ],
    sourceLang: 'ja',           // 감지된 소스 언어
    targetLang: 'ko',           // 사용자의 대상 언어
    mode: 'translate' | 'phonetic'  // 번역 또는 로마자 표기
}

반환:

// 성공
{
    lines: [
        { text: 'Translated line 1' },
        { text: 'Translated line 2' }
    ],
    error: null
}

// 오류
{
    lines: null,
    error: '오류 메시지'
}

translateMetadata(params)

곡 제목과 아티스트 이름을 번역합니다.

매개변수:

{
    title: 'Original Song Title',
    artist: 'Original Artist Name',
    lang: 'ko'  // 대상 언어
}

반환:

// 성공
{
    title: '번역된 제목',
    artist: '번역된 아티스트'
}

// 실패
null

generateTMI(params)

트랙에 대한 흥미로운 정보를 생성합니다.

매개변수:

{
    title: 'Song Title',
    artist: 'Artist Name',
    album: 'Album Name',
    lyrics: '전체 가사 텍스트'
}

반환:

{
    content: '이 곡에 대한 흥미로운 사실들...',
    error: null
}

설정 UI

사용자 설정을 위한 인터페이스 제공:

getSettingsUI: function() {
    const React = Spicetify.React;
    const { useState, useEffect } = React;

    return function SettingsComponent() {
        const [apiKey, setApiKey] = useState('');

        useEffect(() => {
            // 저장된 API 키 로드
            const saved = window.AIAddonManager.getAddonSetting(
                'my-ai-provider',
                'apiKey',
                ''
            );
            setApiKey(saved);
        }, []);

        const handleSave = () => {
            window.AIAddonManager.setAddonSetting(
                'my-ai-provider',
                'apiKey',
                apiKey
            );
        };

        return React.createElement('div', null,
            React.createElement('input', {
                type: 'password',
                value: apiKey,
                onChange: (e) => setApiKey(e.target.value),
                placeholder: 'API 키 입력'
            }),
            React.createElement('button', {
                onClick: handleSave
            }, '저장')
        );
    };
}

설정 가져오기

AIAddonManager를 사용하여 애드온별 설정을 가져오거나 저장:

// 설정 가져오기
const apiKey = window.AIAddonManager.getAddonSetting(
    'my-ai-provider',  // 애드온 ID
    'apiKey',          // 설정 키
    ''                 // 기본값
);

// 설정 저장
window.AIAddonManager.setAddonSetting(
    'my-ai-provider',
    'apiKey',
    'new-value'
);

예제: 간단한 OpenAI 애드온

(function() {
    'use strict';

    const addon = {
        id: 'my-openai',
        name: 'My OpenAI',
        author: 'Developer',
        description: 'OpenAI 기반 번역',
        
        supports: {
            translate: true,
            metadata: false,
            tmi: false
        },

        getSettingsUI: function() {
            // ... 설정 UI 구현
        },

        translate: async function(params) {
            const apiKey = window.AIAddonManager.getAddonSetting(
                'my-openai', 'apiKey', ''
            );

            if (!apiKey) {
                return { error: 'API 키가 설정되지 않았습니다' };
            }

            try {
                const response = await fetch(
                    'https://api.openai.com/v1/chat/completions',
                    {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'Authorization': `Bearer ${apiKey}`
                        },
                        body: JSON.stringify({
                            model: 'gpt-3.5-turbo',
                            messages: [{
                                role: 'user',
                                content: `다음 가사를 ${params.targetLang}로 번역해주세요:\n${
                                    params.lyrics.map(l => l.text).join('\n')
                                }`
                            }]
                        })
                    }
                );

                const data = await response.json();
                const translated = data.choices[0].message.content;
                const lines = translated.split('\n').map(text => ({ text }));

                return { lines, error: null };
            } catch (error) {
                return { error: error.message };
            }
        }
    };

    function register() {
        if (window.AIAddonManager) {
            window.AIAddonManager.register(addon);
        } else {
            setTimeout(register, 100);
        }
    }
    register();
})();

파일 배치

애드온 파일을 ivLyrics 디렉토리에 넣고 manifest.json에 추가:

{
    "subfiles_extension": [
        "Addon_AI_MyProvider.js"
    ]
}

테스트

  1. 애드온 파일 추가
  2. manifest.json 업데이트
  3. spicetify apply 실행
  4. Spotify를 열고 설정 > AI Providers 확인
  5. 제공자를 활성화하고 번역 테스트

모범 사례

  1. 오류 처리: 항상 오류를 포착하고 우아하게 반환
  2. 속도 제한: API 호출에 적절한 지연 구현
  3. 캐싱: API 사용량을 줄이기 위해 응답 캐싱 고려
  4. 다국어화: 여러 언어로 설명 제공
  5. API 키 보안: API 키를 절대 로그하거나 노출하지 않음

관련 문서

Clone this wiki locally