Plan
Premium
Country
Germany
Device
Web Playback SDK (Google Chrome Version 101.0.4951.41 (Official Build) (64-bit))
Operating System
Ubuntu 20.04
My Question or Issue
Hi there,
I use the Web Playback SDK for playback in an Angular app. About 1 in 5 times, after loading the app, when I play a song, I see a 400 response from an "events/item_ready" endpoint that the SDK seems to call internally. Note that I await the "ready" event before initializing playback. It does not seem to affect playback functionality at all, but it will be re-thrown every time I initialize playback on another song once the player/api-wrapper is in that state.
This is a request I copied from the Network tab that produced such a 400 response (I removed the auth token for this post):
fetch("https://cpapi.spotify.com/v1/client/112b9410aed1d0834f4ea0aca1e6429ce12b59a9/event/item_ready", { "headers": { "accept": "*/*", "accept-language": "de,en-US;q=0.9,en;q=0.8", "authorization": "Bearer *****", "content-type": "application/json", "sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"101\", \"Google Chrome\";v=\"101\"", "sec-ch-ua-mobile": "?0", "sec-ch-ua-platform": "\"Linux\"", "sec-fetch-dest": "empty", "sec-fetch-mode": "cors", "sec-fetch-site": "cross-site" }, "referrer": "https://sdk.scdn.co/", "referrerPolicy": "strict-origin-when-cross-origin", "body": "{\"timestamp\":1652174002349,\"player_state\":{\"playback_id\":\"5f560042b9e0258a708ec1774387e1ee\",\"duration\":252818,\"current_position\":0,\"paused\":false,\"playbackQuality\":{\"hifi_status\":\"NONE\",\"audio_quality\":\"VERY_HIGH\"}},\"playback_descriptor_id\":\"CIDQDxANGgVBVURJTw==\",\"initial_loading_stats\":{}}", "method": "POST", "mode": "cors", "credentials": "include" });
This is my player initialization logic:
private async initPlayerIfNecessary(): Promise<void> {
if (this.isPlayerInitialized) {
return Promise.resolve();
}
await this.createPlayer();
await Promise.all([ this.connectPlayer(), this.waitForPlayerReady() ]);
this.isPlayerInitialized = true;
}
private async createPlayer(): Promise<void> {
const token = await this.retrieveAccessToken();
console.log('Got access token');
this.player = new Spotify.Player({
name: 'MyPlayer',
getOAuthToken: (cb: (token: string) => void) => cb(token),
});
}
private async connectPlayer() {
const success: boolean = await this.player.connect();
if (!success) {
return Promise.reject('The Web Playback SDK could not connect to Spotify!');
}
console.log('The Web Playback SDK successfully connected to Spot ify!');
return Promise.resolve();
}
private async waitForPlayerReady() {
const data: WebPlaybackInstance = await waitForEventWithTimeout(this.player, 'ready', 2000);
console.log('Ready with Device ID', data.device_id);
this.deviceId = data.device_id;
}
I then use the spotifyWebApi to initialize playback with this function:
async play(trackId: string): Promise<void> {
await this.initPlayerIfNecessary();
const selectedUri = `spotify:track:${trackId}`;
const options = {
device_id: this.deviceId,
uris: [selectedUri],
offset: {
uri: selectedUri
}
};
return this.playNew(options);
}
@spotifyAuthProtected()
private playNew(options: PlayParameterObject): Promise<void> {
return spotifyWebApi.play(options);
}
For brevity, I chose not to go into the details of the @spotifyAuthProtected decorator or some other referenced functions.
Is this behavior a bug in the SDK or am I missing something in my implementation?