|
3 | 3 | <head> |
4 | 4 | <title>Spotify Dev Player</title> |
5 | 5 | <style> |
6 | | - body { |
7 | | - font-family: Arial, sans-serif; |
8 | | - max-width: 800px; |
9 | | - margin: 2rem auto; |
10 | | - padding: 0 1rem; |
11 | | - } |
12 | | - .credentials { |
13 | | - display: flex; |
14 | | - flex-direction: column; |
15 | | - gap: 1rem; |
16 | | - margin-bottom: 2rem; |
17 | | - } |
18 | | - input { |
19 | | - padding: 0.5rem; |
20 | | - width: 100%; |
21 | | - } |
22 | | - button { |
23 | | - padding: 0.5rem 1rem; |
24 | | - cursor: pointer; |
25 | | - margin: 0.5rem; |
26 | | - } |
27 | | - .hidden { |
28 | | - display: none; |
29 | | - } |
30 | | - #status { |
31 | | - margin: 1rem 0; |
32 | | - padding: 1rem; |
33 | | - background: #f0f0f0; |
34 | | - } |
| 6 | + body { font-family: Arial, sans-serif; max-width: 800px; margin: 2rem auto; padding: 0 1rem; } |
| 7 | + .credentials { display: flex; flex-direction: column; gap: 1rem; margin-bottom: 2rem; } |
| 8 | + input { padding: 0.5rem; width: 100%; } |
| 9 | + button { padding: 0.5rem 1rem; cursor: pointer; margin: 0.5rem; } |
| 10 | + .hidden { display: none; } |
| 11 | + #status { margin: 1rem 0; padding: 1rem; background: #f0f0f0; } |
35 | 12 | </style> |
36 | 13 | </head> |
37 | 14 | <body> |
38 | 15 | <div id="setup" class="credentials"> |
39 | 16 | <input type="text" id="clientId" placeholder="Enter Spotify Client ID"> |
40 | 17 | <button onclick="startAuth()">Initialize Player</button> |
41 | 18 | </div> |
42 | | - |
43 | 19 | <div id="player" class="hidden"> |
44 | 20 | <div id="status">Status: Initializing...</div> |
45 | 21 | <div> |
|
68 | 44 | statusDiv.textContent = `Status: ${message}`; |
69 | 45 | } |
70 | 46 |
|
| 47 | + function getUrlParameter(name) { |
| 48 | + const urlParams = new URLSearchParams(window.location.search); |
| 49 | + return urlParams.get(name); |
| 50 | + } |
| 51 | + |
71 | 52 | window.onSpotifyWebPlaybackSDKReady = () => { |
72 | 53 | const params = getHashParams(); |
73 | 54 | if (params.access_token) { |
|
79 | 60 | const clientId = document.getElementById('clientId').value; |
80 | 61 | const state = Math.random().toString(36).substring(7); |
81 | 62 | const scope = 'streaming user-read-email user-read-private user-modify-playback-state'; |
82 | | - |
83 | | - const authUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}` + |
84 | | - `&response_type=token` + |
85 | | - `&redirect_uri=${encodeURIComponent(redirectUri)}` + |
86 | | - `&scope=${encodeURIComponent(scope)}` + |
87 | | - `&state=${state}`; |
88 | | - |
| 63 | + const authUrl = `https://accounts.spotify.com/authorize?client_id=${clientId}&response_type=token&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scope)}&state=${state}`; |
89 | 64 | window.location.href = authUrl; |
90 | 65 | } |
91 | 66 |
|
92 | 67 | function getHashParams() { |
93 | 68 | const hashParams = {}; |
94 | 69 | const hash = window.location.hash.substring(1); |
95 | 70 | const params = hash.split('&'); |
96 | | - |
97 | 71 | params.forEach(param => { |
98 | 72 | const [key, value] = param.split('='); |
99 | 73 | hashParams[key] = decodeURIComponent(value); |
100 | 74 | }); |
101 | | - |
102 | 75 | return hashParams; |
103 | 76 | } |
104 | 77 |
|
105 | 78 | function initializePlayer(token) { |
106 | 79 | document.getElementById('setup').classList.add('hidden'); |
107 | 80 | document.getElementById('player').classList.remove('hidden'); |
108 | | - |
109 | 81 | updateStatus('Initializing player...'); |
110 | 82 |
|
111 | 83 | playerInstance = new Spotify.Player({ |
|
114 | 86 | volume: 0.5 |
115 | 87 | }); |
116 | 88 |
|
117 | | - // Error handling |
118 | 89 | playerInstance.addListener('initialization_error', ({ message }) => { |
119 | 90 | updateStatus(`Initialization Error: ${message}`); |
120 | 91 | }); |
|
133 | 104 | updateStatus(`Playback Error: ${message}`); |
134 | 105 | }); |
135 | 106 |
|
136 | | - // Playback status updates |
137 | 107 | playerInstance.addListener('player_state_changed', state => { |
138 | 108 | if (state) { |
139 | | - updateStatus(` |
140 | | - Track: ${state.track_window.current_track.name} |
141 | | - Artist: ${state.track_window.current_track.artists[0].name} |
142 | | - Playing: ${!state.paused} |
143 | | - `); |
| 109 | + updateStatus(`Track: ${state.track_window.current_track.name} | Artist: ${state.track_window.current_track.artists[0].name} | Playing: ${!state.paused}`); |
144 | 110 | } |
145 | 111 | }); |
146 | 112 |
|
147 | | - // Update the 'ready' listener in initializePlayer(): |
148 | 113 | playerInstance.addListener('ready', ({ device_id }) => { |
149 | 114 | updateStatus(`Ready with Device ID: ${device_id}`); |
150 | | - |
151 | | - // Transfer playback automatically |
152 | 115 | fetch('https://api.spotify.com/v1/me/player', { |
153 | 116 | method: 'PUT', |
154 | 117 | headers: { |
|
157 | 120 | }, |
158 | 121 | body: JSON.stringify({ |
159 | 122 | device_ids: [device_id], |
160 | | - play: false // Set to true if you want to auto-play |
| 123 | + play: false |
161 | 124 | }) |
162 | | - }) |
163 | | - .then(response => { |
164 | | - if (response.status === 204) { |
165 | | - updateStatus('Successfully transferred playback to this device'); |
166 | | - } else { |
167 | | - updateStatus('Failed to transfer playback: ' + response.status); |
| 125 | + }).then(response => { |
| 126 | + if (response.status === 204) { |
| 127 | + updateStatus('Successfully transferred playback'); |
| 128 | + const trackId = getUrlParameter('track'); |
| 129 | + if (trackId) { |
| 130 | + playTrackById(trackId, token); |
168 | 131 | } |
169 | | - }) |
170 | | - .catch(error => { |
171 | | - updateStatus('Error transferring playback: ' + error); |
172 | | - }); |
| 132 | + } |
| 133 | + }); |
173 | 134 | }); |
174 | 135 |
|
175 | | - // Not Ready |
176 | 136 | playerInstance.addListener('not_ready', ({ device_id }) => { |
177 | 137 | updateStatus(`Device ID has gone offline: ${device_id}`); |
178 | 138 | }); |
179 | 139 |
|
180 | | - // Connect to the player |
181 | 140 | playerInstance.connect(); |
182 | 141 | } |
183 | 142 |
|
184 | | - // Player Controls |
| 143 | + async function playTrackById(trackId, token) { |
| 144 | + try { |
| 145 | + const response = await fetch('https://api.spotify.com/v1/me/player/play', { |
| 146 | + method: 'PUT', |
| 147 | + headers: { |
| 148 | + 'Authorization': `Bearer ${token}`, |
| 149 | + 'Content-Type': 'application/json' |
| 150 | + }, |
| 151 | + body: JSON.stringify({ |
| 152 | + uris: [`spotify:track:${trackId}`] |
| 153 | + }) |
| 154 | + }); |
| 155 | + if (response.status === 204) { |
| 156 | + updateStatus('Started playing track'); |
| 157 | + } else { |
| 158 | + updateStatus('Failed to play track: ' + response.status); |
| 159 | + } |
| 160 | + } catch (error) { |
| 161 | + updateStatus('Error playing track: ' + error); |
| 162 | + } |
| 163 | + } |
| 164 | + |
185 | 165 | async function handlePlay() { |
186 | 166 | const result = await playerInstance.resume(); |
187 | 167 | updateStatus(`Play result: ${JSON.stringify(result)}`); |
|
210 | 190 | async function getCurrentState() { |
211 | 191 | const state = await playerInstance.getCurrentState(); |
212 | 192 | if (state) { |
213 | | - updateStatus(` |
214 | | - Current track: ${state.track_window.current_track.name} |
215 | | - Artist: ${state.track_window.current_track.artists[0].name} |
216 | | - Position: ${state.position} |
217 | | - Paused: ${state.paused} |
218 | | - `); |
| 193 | + updateStatus(`Current track: ${state.track_window.current_track.name} | Artist: ${state.track_window.current_track.artists[0].name} | Position: ${state.position} | Paused: ${state.paused}`); |
219 | 194 | } else { |
220 | 195 | updateStatus('No current state available'); |
221 | 196 | } |
|
235 | 210 | const params = getHashParams(); |
236 | 211 | const token = params.access_token; |
237 | 212 | const trackUri = document.getElementById('trackUri').value; |
238 | | - |
239 | 213 | try { |
240 | 214 | const response = await fetch('https://api.spotify.com/v1/me/player/play', { |
241 | 215 | method: 'PUT', |
|
247 | 221 | uris: [trackUri] |
248 | 222 | }) |
249 | 223 | }); |
250 | | - |
251 | 224 | if (response.status === 204) { |
252 | 225 | updateStatus('Started playing track'); |
253 | 226 | } else { |
|
0 commit comments