When using spotify player, a problem occurs when trying to play the next track after the track has finished playing.
// WebPlayback.tsx
import { useEffect, useState } from 'react';
import { connect, useDispatch } from 'react-redux';
import Player from './pages/Player';
import { TrackState } from './pages/Settings';
import { PlayerContext } from './PlayerContext';
import {
clearTrackProgress,
moveNextPosition,
} from './store/reducers/rootReducer';
import getTokens from './utils/functions/getTokens';
import play from './utils/functions/play';
export interface IPlayerContext {
player: Spotify.Player | null;
deviceId: string;
}
interface WebPlaybackState {
currentPlayingPosition: number;
tracks: TrackState[];
}
function WebPlayback({ currentPlayingPosition, tracks }: WebPlaybackState) {
const dispatch = useDispatch();
const [player, setPlayer] = useState<Spotify.Player | null>(null);
const [deviceId, setDeviceId] = useState('');
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: 'Mucketlist Player SDK',
getOAuthToken: (cb) => {
cb(getTokens());
},
volume: 0.5,
});
setPlayer(player);
player.addListener('ready', ({ device_id }) => {
console.log('Ready with Device ID', device_id);
setDeviceId(device_id);
});
player.addListener('not_ready', ({ device_id }) => {
console.log('Device ID has gone offline', device_id);
});
player.addListener('player_state_changed', async (state) => {
if (!player) return;
console.log('Player state changed', state);
console.log('Playing Track', state.track_window.current_track.name);
if (state.position >= state.duration) {
dispatch(clearTrackProgress());
dispatch(moveNextPosition(1));
play({
spotify_uri: tracks[currentPlayingPosition + 1].uri,
device_id: deviceId,
playerInstance: player,
});
}
});
player.connect();
};
}, []);
return (
<PlayerContext.Provider value={{ player, deviceId }}>
<Player />
</PlayerContext.Provider>
);
}
const mapStateToProps = (state: WebPlaybackState) => {
return {
currentPlayingPosition: state.currentPlayingPosition,
tracks: state.tracks,
};
};
export default connect(mapStateToProps)(WebPlayback);
// play function
import axios, { AxiosError } from 'axios';
import getTokens from './getTokens';
interface PlayProps {
spotify_uri: string;
device_id: string;
playerInstance: {
_options: Spotify.PlayerInit;
};
}
const play = ({
spotify_uri,
device_id,
playerInstance: {
_options: { getOAuthToken },
},
}: PlayProps) => {
getOAuthToken(async (accessToken: string) => {
console.log(device_id);
try {
console.log(getTokens());
await axios.put(
`https://api.spotify.com/v1/me/player/play?device_id=${device_id}`,
{
uris: [spotify_uri],
},
{
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${getTokens()}`,
},
}
);
} catch (error) {
if (error instanceof AxiosError) handlePlayerStateError(error);
}
});
};
const handlePlayerStateError = (error: AxiosError) => {
if (error.status === '502') {
console.log('502 error');
}
if (error.status === '404') {
console.log('404 error');
}
};
export default play;
When the player's state changes, I wanted to implement a function in which the next track is played if the current time is equal to or greater than the length of the track. However, you can see that device_id is not recognized with the following error.
PUT https://api.spotify.com/v1/me/player/play?device_id= 404
I would like to know why the device_id state is not recognized.