이렇게 생긴 플레이어를 만들었다!
노래의 플레이 버튼을 누르면 전곡 재생도 가능하다 👍🏻
노래 재생에 처음 성공했을 때 느꼈던 감동은 아직도 잊을 수 없다 🤦🏻♀️
관련 내용이 한글로 정리된 게 없어서 Spotify SDK 공식 문서 보고 한땀한땀 만들었다... 우당탕탕 고뇌했던 과정을 기록하기 위해 글을 쓴다.
참고로 백엔드 분이 따로 계셨어서, 로그인은 백엔드에서 구현을 했습니다.
앱 내에스포티파이로 로그인
기능이 구현되어 있어야 해요! 스포티파이에서 지급하는 access token이 필요합니다.
혹은 아래 링크에서 임시 토큰을 지급 받으실 수 있습니다. 유효 기간이 1시간이라 1시간 마다 버튼을 클릭해 새로운 토큰을 복사해야 합니다.
https://developer.spotify.com/documentation/web-playback-sdk/quick-start/
Spotify API를 활용한 노래 추천 서비스
를 구현하는 게 우리 팀의 목표였다.
프론트가 구현해야 하는 기능은 크게 두 가지였다.
두번째 기능을 내가 맡았고, 이를 위해 spotify sdk 사용 방법을 공부했다.
https://developer.spotify.com/documentation/ 에 들어가보면 여러 종류의 APIs와 SDKs가 있는데, 이 중 WEB API와 WEB PLAYBACK SDK를 사용해야 한다.
플레이어 생성은 WEB Playback SDK로 해야 하고, 플레이어 조작(원하는 노래 재생하기, pause, resume)은 WEB API를 사용해야 했다.
Spotify for Developers 사이트에서는 WEB PLAYBACK SDK를 다음과 같이 소개하고 있다.
The Spotify Web Playback SDK is a client-side only JavaScript library that allows you to create a new player in Spotify Connect, stream and control audio tracks from Spotify inside your website application, and get metadata about the current playback.
내 웹사이트 내에서 Spotify를 사용한 뮤직 플레이어를 만들 수 있는 자바스크립트 라이브러리!
아래와 같이 구성했다.
WebPlayback
: 컨테이너 컴포넌트로, 이 컴포넌트 내에서 플레이어 생성 및 플레이어 상태 관리가 이뤄진다.Playlist
: props로 받은 노래 정보를 SingleSong
컴포넌트로 변환한다.SingleSong
: props로 받은 개별 노래 정보를 화면에 나타낸다. 유저가 재생 버튼을 클릭하면 onPlay 함수를 호출한다.Player
: props로 현재 플레이어의 상태 정보를 받아 화면에 나타낸다. 유저가 재생 버튼을 클릭하면 onPlay/onPause 함수를 호출한다.Web Playback SDK를 내 앱에 설치하기 위해 script 코드를 추가해야 했다.
NextJS를 사용했기 때문에, React처럼 html의 head,body에 직접 접근할 수 없었다.
대신 NextJS에서 제공하는 Script
컴포넌트를 사용해 스크립트 코드를 추가할 수 있었다.
_app.tsx
에 코드를 추가해 주었다.
import type { AppProps } from "next/app";
import Script from "next/script";
function MyApp({ Component, pageProps: { session, ...pageProps } }: AppProps) {
return (
<>
<Script src="https://sdk.scdn.co/spotify-player.js" />
<Component {...pageProps} />
</>
);
}
export default MyApp;
https://developer.spotify.com/documentation/web-playback-sdk/quick-start/
가이드에 나와있는 플레이어 initialization 코드는 아래와 같다.
<!DOCTYPE html>
<html>
<head>
<title>Spotify Web Playback SDK Quick Start</title>
</head>
<body>
<h1>Spotify Web Playback SDK Quick Start</h1>
<button id="togglePlay">Toggle Play</button>
<script src="https://sdk.scdn.co/spotify-player.js"></script>
<script>
window.onSpotifyWebPlaybackSDKReady = () => {
const token = '[My access token]';
const player = new Spotify.Player({
name: 'Web Playback SDK Quick Start Player',
getOAuthToken: cb => { cb(token); },
volume: 0.5
});
// Ready
player.addListener('ready', ({ device_id }) => {
console.log('Ready with Device ID', device_id);
});
// Not Ready
player.addListener('not_ready', ({ device_id }) => {
console.log('Device ID has gone offline', device_id);
});
player.addListener('initialization_error', ({ message }) => {
console.error(message);
});
player.addListener('authentication_error', ({ message }) => {
console.error(message);
});
player.addListener('account_error', ({ message }) => {
console.error(message);
});
document.getElementById('togglePlay').onclick = function() {
player.togglePlay();
};
player.connect();
}
</script>
</body>
</html>
문제
결론
WebPlayback
의 useEffect에 위 코드를 넣었다. getOAuthToken
콜백 함수에 넣어줄 때 문자열 맨 처음과 끝에 있는 ""를 벗겨서 넣어줘야 한다. useEffect(() => {
const script = document.createElement("script");
script.src = "https://sdk.scdn.co/spotify-player.js";
script.async = true;
document.body.appendChild(script);
window.onSpotifyWebPlaybackSDKReady = () => {
const player = new window.Spotify.Player({
name: "Web Playback SDK",
getOAuthToken: (cb: any) => {
// Run code to get a fresh access token
cb(token?.replace(/\"/g, "")); // 이 token은 로그인 시에 백엔드에서 받아 온 access token이다.
},
volume: 0.5,
});
player.addListener("ready", ({ device_id }) => {
console.log("Ready with Device ID", device_id);
});
player.addListener("not_ready", ({ device_id }) => {
console.log("Device ID has gone offline", device_id);
});
player.addListener("player_state_changed", (state) => {
if (!state) {
return;
}
console.log("state changed", state);
});
player.connect();
};
}, [token]);
플레이어를 만들긴 했는데 그래서 이걸 어떻게 사용하냐!
는 다음글에서 알아보겠다
구현 코드 궁금하면 여기 보라고까지 해놨는데 다음 글로 넘기니 민망ㅎ
잘 보았어요 저도 시간있을때 만들어 봐야겠어요