首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spotify Web API / playback检测轨道回放的结束

使用Spotify Web API / playback检测轨道回放的结束
EN

Stack Overflow用户
提问于 2018-04-12 21:07:20
回答 4查看 3.3K关注 0票数 3

使用Spotify Web API和Web播放SDK,有谁知道什么时候歌曲的回放完成了,即歌曲已经结束了?

我知道网络播放SDK中有一些名为player_state_changed的事件,但是事件中提供的数据似乎对我没有多大帮助。

在我的网络应用程序中,下一首要播放的歌曲是非常自然地决定的。如果我能确定的话,这将是很好的,当目前的轨道已经达到它的结束。因此,没有播放列表。相反,该应用程序会连续播放单曲,并在当前歌曲结束时确定下一首歌曲。

同时,我在这里用下面的代码进行了尝试:

代码语言:javascript
复制
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

代码语言:javascript
复制
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 (我还没有找到确切的位置,也没有找到原因)。堆栈表示dequeueUpdates / tryUpdate / _processUpdate / _appendUpdate。不过,我是个初学者,我得先学会如何对付火狐调试器。:)

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-07-08 09:56:09

我的最后一个答案被打破了,所以我现在要添加新的解决方案,这是暂时可行的。

代码语言:javascript
复制
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是否在先前的轨道列表中。但现在位置检查出现了问题,因为在轨道完全结束之前,当前轨道似乎出现在以前的轨道列表中。但这在我的应用程序中并不是问题,因为命令总是有很小的延迟。

票数 1
EN

Stack Overflow用户

发布于 2018-06-30 12:17:09

编辑:由于某些原因,这不再有效了。看看我的另一个答案,这个答案现在起作用了。https://stackoverflow.com/a/51114848/8081009

这是我的解决办法。它大部分时间都能用。事实上,在我能想象到的任何场景中,我都没有打破它。因此,保持最后的状态,并检查它是否已进入暂停状态。希望Spotify将通过跟踪结束事件来减轻我们的工作。如果他们这么做就太好了。这仍然比每1秒左右轮询他们/me/player/当前播放端点要好。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2022-04-02 22:38:48

我也有同样的问题,我就是这样解决的。

当一首歌播放完后,它将被添加到state.track_window.previous_tracks列表中

只有当有下一个音轨并开始播放时,state.track_window.previous_tracks才会被填充。

但是每次调用api来播放新的曲目时,它都会清除state.track_window.previous_tracks & state.track_window.next_tracks列表。

如果有下一个轨道,我希望停止并选择自己的下一个轨道,然后调用api。

代码语言:javascript
复制
var alreadyPlayed = state.track_window.previous_tracks

if(alreadyPlayed.length > 0) {
  player.pause()
}

如果没有下一首曲目,当歌曲结束时,玩家将被暂停。

代码语言:javascript
复制
if(state.paused && state.position === 0) {
  //song ended
  ChooseNextSong()
}

state回调多次被触发,但我只想调用ChooseNextSong()一次,所以每次触发时都会增加startCheck

代码语言:javascript
复制
if(state.paused && state.position === 0) {
  //song ended
  startCheck++
  if(startCheck === 1) {
    ChooseNextSong()
  }
}

检查歌曲是否已启动

代码语言:javascript
复制
if(state.position === 0 && alreadyPlayed.length === 0 && !state.paused) 
{
  //song started
  startCheck = 0
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49805871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档