使用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 .. :)
答案 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是否在上一个曲目列表中。但是,位置检查现在出现了问题,因为当前曲目似乎在曲目完全结束之前出现在先前的曲目列表中。但这并不是我的应用程序中的问题,因为命令的延迟总是很小。