Created
April 21, 2021 15:23
-
-
Save tomjaimz/18c0e211ea979767ac7ac42640825e96 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="//sdk.scdn.co/spotify-player.js"></script> | |
</head> | |
<body> | |
<pre>Open Console</pre> | |
<script> | |
let token; | |
let sdkReady; | |
let player; | |
const name = `Minimal Anthem [${new Date.toISOString()}]`; | |
const ACTIONS = [ | |
'connect', | |
'disconnect', | |
'getCurrentState', | |
'getVolume', | |
'pause', | |
'resume', | |
'togglePlay', | |
'previousTrack', | |
'nextTrack', | |
'transfer', | |
]; | |
const EVENTS = [ | |
'initialization_error', | |
'authentication_error', | |
'account_error', | |
'playback_error', | |
'player_state_changed', | |
'ready', | |
'not_ready', | |
]; | |
const put = (url, body) => | |
fetch(`https://api.spotify.com/v1/${url}`, { | |
method: 'PUT', | |
body: JSON.stringify(body), | |
headers: { | |
'Authorization': `Bearer ${token}`, | |
'Content-Type': 'application/json', | |
}, | |
}); | |
const [ | |
uriRow, | |
uriInput, | |
uriButton, | |
tokenRow, | |
tokenInput, | |
useToken, | |
getToken, | |
] = ['p', 'input', 'button', 'p', 'input', 'button', 'button'].map( | |
document.createElement | |
); | |
uriInput.placeholer = 'Enter URL or URI'; | |
uriInput.id = 'uriInput'; | |
uriButton.onclick = () => { | |
if (token.length !== 160) { | |
hint('no token'); | |
return; | |
} | |
const inputValue = document.getElementById('uriInput').value; | |
const match = inputValue.match( | |
/https:\/\/open\.spotify\.com\/(.*)\/([^?]*)/ | |
); | |
const [, type, id] = match ? match : inputValue.split(':'); | |
const uri = `spotify:${type}:${id}`; | |
put( | |
`me/player/play`, | |
['track', 'episode'].includes(type) | |
? {uris: [uri]} | |
: {context_uri: uri} | |
); | |
}; | |
uriButton.innerText = 'Play'; | |
uriRow.append(uriInput, uriButton); | |
document.body.appendChild(uriRow); | |
tokenInput.placeholer = 'Enter Token'; | |
tokenInput.id = 'tokenInput'; | |
useToken.innerText = 'Use Token'; | |
useToken.onclick = () => { | |
const tokenInput = document.getElementById('tokenInput').value; | |
if (tokenInput.value.length !== 160) { | |
hint('invalid token'); | |
return; | |
} | |
token = tokenInput.value; | |
init(); | |
}; | |
getToken.onclick = () => { | |
window | |
.open( | |
'https://developer.spotify.com/documentation/web-playback-sdk/quick-start/', | |
'_blank' | |
) | |
.focus(); | |
}; | |
getToken.innerText = 'Get Token'; | |
tokenRow.append(tokenInput, useToken, getToken); | |
document.body.appendChild(tokenRow); | |
const hint = (v) => { | |
setTimeout(() => { | |
console.log( | |
`Try %c${v}%c first`, | |
'font-weight: bold', | |
'font-weight: normal' | |
); | |
}, 0); | |
}; | |
for (const action of ACTIONS) { | |
const button = document.createElement('button'); | |
button.onclick = async () => { | |
if (token.length !== 160) { | |
hint('no token'); | |
return; | |
} | |
if (!player) { | |
hint('player not ready'); | |
return; | |
} | |
console.log(action, await player[action]()); | |
}; | |
button.innerText = action; | |
document.body.appendChild(button); | |
} | |
const init = async () => { | |
if (!sdkReady) return; | |
if (!token) return; | |
const player = new Spotify.Player({ | |
name, | |
getOAuthToken: (fn) => fn(token), | |
}); | |
player.transfer = async () => { | |
if (token.length !== 160) { | |
hint('no token'); | |
return; | |
} | |
const {device_id} = player._options; | |
if (device_id) { | |
const response = await put('me/player', {device_ids: [device_id]}); | |
if (response.status === 404) { | |
const {message} = await response.json(); | |
if (message === 'Device not found') { | |
hint('connect'); | |
} | |
} | |
} else { | |
hint('connect'); | |
} | |
return device_id; | |
}; | |
for (const event of EVENTS) { | |
player.addListener(`${event}`, (body) => { | |
if (event === 'ready') { | |
player._options.device_id = body.device_id; | |
} | |
if ( | |
event === 'playback_error' && | |
body.message === 'Cannot perform operation; no list was loaded.' | |
) { | |
hint('transfer'); | |
} | |
console.log(event, body); | |
}); | |
} | |
}; | |
window.onSpotifyWebPlaybackSDKReady = () => { | |
sdkReady = true; | |
init(); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment