gbgordy
gbgordy

Reputation: 53

problem playing songs via the spotify web api and javascript

I am working on building a web-based application that interfaces with spotify. I started with C# and had no problem accessing the API, pulling my playlist and pulling tracks off of it but it seems you cannot play songs with the spotify Web API located here:

https://developer.spotify.com/documentation/web-api/

I then started looking at the Web Playback API located here:

https://developer.spotify.com/documentation/web-playback-sdk/

I intend to write most of it in c# because my c# is much stronger than my javascript. The c# piece is working. I can get an authorization token, pull my playlists and tracks. I intend to pass this information to the javascript.

I pulled the below javascript from the spotify developer page. I only kindof understand it so I don't know why it isn't working. Any help you can provide is greatly appreciated.

<script src="https://sdk.scdn.co/spotify-player.js"></script>

<script>

window.onSpotifyWebPlaybackSDKReady = () => {
  // You can now initialize Spotify.Player and use the SDK
};

const play = ({
  spotify_uri,
  playerInstance: {
    _options: {
      getOAuthToken,
      id
    }
  }
}) => {
  getOAuthToken(access_token => {
    fetch('https://api.spotify.com/v1/me/player/play', {
      method: 'PUT',
      body: JSON.stringify({ uris: [spotify_uri] }),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ${myaccesstoken}'
      },
    });
  });
};

play({
  playerInstance: new Spotify.Player({ name: "..." }),
  spotify_uri: 'spotify:track:7xGfFoTpQ2E7fRF5lN10tr',
});

</script>

Upvotes: 4

Views: 5832

Answers (1)

Bee
Bee

Reputation: 1296

tl;dr: Working snippet at the bottom of this answer!


You do this

play({
  playerInstance: new Spotify.Player({ name: "..." }),
  spotify_uri: 'spotify:track:7xGfFoTpQ2E7fRF5lN10tr',
});

outside of the following.

window.onSpotifyWebPlaybackSDKReady = () => {
  // You can now initialize Spotify.Player and use the SDK
};

Which means play is getting called right away without waiting for the Spotify Web Playback SDK to load. As the comment says Spotify.Player can be used as soon as the onSpotifyWebPlaybackSDKReady was called.


Another problem is that you actually never created a Spotify Connect device. Which is needed in order to use the Spotify Web API to control that exact device. This works by calling connect on the Spotify.Player instance. In order to know when connect is done and the player is ready to play songs you need to define a listener first as shown in the following.

player.addListener('ready', ({ device_id }) => {
  console.log('Ready with Device ID', device_id);
});

So you actually need two different Spotify APIs in order to achieve your goal. First you need the Spotify Web Playback SDK in order to create a Spotify Connect device (Spotify docs refer to it as player). Afterwards you can control this exact Spotify Connect device using Spotify's Web API.


The following snippet will play the song.

WARNING: This will play music within your browser without any control elements!

This snippet needs an access token which can be obtained here by clicking the green button saying Get Your Web Playback SDK Access Token. The token then needs to be copy-pasted into line 11 of the snippet replacing <YOUR_ACCESS_TOKEN_HERE>.

index.html

<!-- Load the Spotify Web Playback SDK -->
<script src="https://sdk.scdn.co/spotify-player.js"></script>

<script>
  // Called when the Spotify Web Playback SDK is ready to use
  window.onSpotifyWebPlaybackSDKReady = () => {

    // Define the Spotify Connect device, getOAuthToken has an actual token 
    // hardcoded for the sake of simplicity
    var player = new Spotify.Player({
      name: 'A Spotify Web SDK Player',
      getOAuthToken: callback => {
        callback('<YOUR_ACCESS_TOKEN_HERE>');
      },
      volume: 0.1
    });

    // Called when connected to the player created beforehand successfully
    player.addListener('ready', ({ device_id }) => {
      console.log('Ready with Device ID', device_id);

      const play = ({
        spotify_uri,
        playerInstance: {
          _options: {
            getOAuthToken,
            id
          }
        }
      }) => {
        getOAuthToken(access_token => {
          fetch(`https://api.spotify.com/v1/me/player/play?device_id=${id}`, {
            method: 'PUT',
            body: JSON.stringify({ uris: [spotify_uri] }),
            headers: {
              'Content-Type': 'application/json',
              'Authorization': `Bearer ${access_token}`
            },
          });
        });
      };

      play({
        playerInstance: player,
        spotify_uri: 'spotify:track:7xGfFoTpQ2E7fRF5lN10tr',
      });
    });

    // Connect to the player created beforehand, this is equivalent to 
    // creating a new device which will be visible for Spotify Connect
    player.connect();
  };
</script>

Upvotes: 5

Related Questions