使用Spotify Web API / Playback SDK

时间:2018-04-12 21:07:20

标签: spotify

使用Spotify Web API和Web Playback SDK,是否有人知道检测曲目播放何时结束的好方法,即歌曲结束了?

我知道Web Playback SDK中有一些名为player_state_changed的事件,但事件中提供的数据似乎对我没有帮助。

在我的网络应用中,下一首要播放的歌曲是自发确定的。如果我只能确定当前曲目到达终点时,那将是很好的。因此,没有播放列表。相反,应用程序会播放系列中的单曲,并且应该确定当前曲目结束时的下一首歌曲。

与此同时,我在这里尝试使用此代码:

var bCallingNextSong = false;

player.addListener('player_state_changed', state => { 
    if (state != null && 
        state.position == 0 && 
        state.duration == 0 && 
        state.paused == true) { 

        if (!bCallingNextSong) {
            playNextSong();
        }
    }
});


function playNextSong() {
   $.ajax({
            url:"playback.php", //the page containing php script
            type: "post", //request type,
            dataType: 'json',
            data: {action: "next", device: deviceId},
            success: function(result) {
                bCallingNextSong = false;
            },
            error: function(XMLHttpRequest, textStatus, errorThrown) {  
                bCallingNextSong = false;
            } 
    });     
}

playback.php

switch ($action) {

    case "next":
        //some blackbox magic here to determine next song, do logging etc.
        //but for now just play the same song over and over

        $api->play($deviceId, ['uris' => "spotify:track:0eGsygTp906u18L0Oimnem"],]);

        echo json_encode(array("answer"=>"played next"));
        break;  

// more code
}

然而,这通常会(但不总是)抛出一个InvalidStateError(我还没找到确切的地方,也没有找到原因)。 Stack表示dequeueUpdates / tryUpdate / _processUpdate / _appendUpdate。然而,我是初学者,我必须先学习如何应对Firefox Debugger .. :)

3 个答案:

答案 0 :(得分:1)

这是我的解决方案。它在大多数时间都有效。实际上,在我能想到的任何情况下,我都不会把它弄坏。因此,保持最后一个状态,并检查它是否已进入暂停状态。希望Spotify可以通过赛道结束活动简化我们的工作。如果他们这样做,那就太好了。这仍然比每隔1秒钟左右轮询一次/ me / player /当前正在播放的端点要好。

this.player.addListener(
    'player_state_changed',
    state => 
    {
      console.log(state);
      if(this.state && !this.state.paused && state.paused && state.position === 0) {
        console.log('Track ended');
        this.setTrackEnd(true);
      }
      this.state = state;
    }
  );

答案 1 :(得分:0)

您应该使用player_state_changed事件并查看正在播放的曲目以查看曲目是否已更改。您可以在playerStateObject.track_window.current_track中找到当前曲目。

可能的实现可能如下所示:

let currentTrack = '';

player.on('player_state_changed', state => {
    if( state.track_window.current_track.id != currentTrack ) {
        // The track changed!
        currentTrack = state.track_window.current_track.id;
    }
});

答案 2 :(得分:0)

我的最后一个答案被打破了,所以我现在将添加可以立即使用的新解决方案。

this.player.addListener('player_state_changed', (state) => {
    console.log(state);
    if (
      this.state
      && state.track_window.previous_tracks.find(x => x.id === state.track_window.current_track.id)
      && !this.state.paused
      && state.paused
      ) {
      console.log('Track ended');
      this.setTrackEnd(true);
    }
    this.state = state;
  });

那么与上一个解决方案有什么不同?我检查current_track是否在上一个曲目列表中。但是,位置检查现在出现了问题,因为当前曲目似乎在曲目完全结束之前出现在先前的曲目列表中。但这并不是我的应用程序中的问题,因为命令的延迟总是很小。