使用Spotify Web API和Web播放SDK,有谁知道什么时候歌曲的回放完成了,即歌曲已经结束了?
我知道网络播放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 (我还没有找到确切的位置,也没有找到原因)。堆栈表示dequeueUpdates / tryUpdate / _processUpdate / _appendUpdate。不过,我是个初学者,我得先学会如何对付火狐调试器。:)
发布于 2019-07-08 09:56:09
我的最后一个答案被打破了,所以我现在要添加新的解决方案,这是暂时可行的。
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是否在先前的轨道列表中。但现在位置检查出现了问题,因为在轨道完全结束之前,当前轨道似乎出现在以前的轨道列表中。但这在我的应用程序中并不是问题,因为命令总是有很小的延迟。
发布于 2018-06-30 12:17:09
编辑:由于某些原因,这不再有效了。看看我的另一个答案,这个答案现在起作用了。https://stackoverflow.com/a/51114848/8081009
这是我的解决办法。它大部分时间都能用。事实上,在我能想象到的任何场景中,我都没有打破它。因此,保持最后的状态,并检查它是否已进入暂停状态。希望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;
}
);发布于 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。
var alreadyPlayed = state.track_window.previous_tracks
if(alreadyPlayed.length > 0) {
player.pause()
}如果没有下一首曲目,当歌曲结束时,玩家将被暂停。
if(state.paused && state.position === 0) {
//song ended
ChooseNextSong()
}state回调多次被触发,但我只想调用ChooseNextSong()一次,所以每次触发时都会增加startCheck。
if(state.paused && state.position === 0) {
//song ended
startCheck++
if(startCheck === 1) {
ChooseNextSong()
}
}检查歌曲是否已启动
if(state.position === 0 && alreadyPlayed.length === 0 && !state.paused)
{
//song started
startCheck = 0
}https://stackoverflow.com/questions/49805871
复制相似问题