这个问题听起来很简单,但我找不到检查音轨uri是否正确的方法。
例如,通过给定的有效曲目uri spotify:track:5Z7ygHCo02SUrFmcgpwsKW播放曲目的正常过程是:
1) 通过sp_link_create_from_string(const char*$track_uri)获取sp_link*
2) 通过sp_link_as_track(sp_link*)获取sp_track*
3) sp_track_add_ref(sp_track*)
4) 如果sp_track_error()返回sp_error_OK或sp_error _IS_LOADING,但元数据已更新且
SP_ERROR_OK,然后SP_session_player_load和SP_session_player_play来加载和播放曲目。
5) sp_track_release()和sp_session_player_unload()。
当我尝试使用正确的uri进行播放时sp_track_error()返回sp_error_IS_LOADING,
metadata_updated永远不会被调用,当然程序也会挂起。我检查了很多uri
并得到相同的结果。
我是否遗漏了什么或误解了API?
这是主循环:
pthread_mutex_lock(&g_notify_mutex);
for(;;)
{
if (next_timeout == 0)
{
while(!g_notify_do && !g_playback_done)
{
pthread_cond_wait(&g_notify_cond, &g_notify_mutex);
}
}
else
{
struct timespec ts;
#if _POSIX_TIMERS > 0
clock_gettime(CLOCK_REALTIME, &ts);
#else
struct timeval tv;
gettimeofday(&tv, NULL);
TIMEVAL_TO_TIMESPEC(&tv, &ts);
#endif
printf("%dn",next_timeout);
if((ts.tv_nsec+(next_timeout % 1000) * 1000000)>=1000000000)
{
ts.tv_nsec += (next_timeout % 1000) * 1000000-1000000000;
ts.tv_sec += next_timeout / 1000+1;
}
else
{
ts.tv_sec += next_timeout / 1000;
ts.tv_nsec += (next_timeout % 1000) * 1000000;
}
pthread_cond_timedwait(&g_notify_cond, &g_notify_mutex, &ts);
}
g_notify_do = 0;
pthread_mutex_unlock(&g_notify_mutex);
g_currenttrack= sp_link_as_track(sp_link_create_from_string(spotify:track:1NrJYpdAi7uosDRPmSYrsG));
sp_track_add_ref(g_currenttrack);
if (sp_track_error( g_currenttrack) == SP_ERROR_OK) {
sp_session_player_load(g_sess, g_currenttrack);
sp_session_player_play(g_sess, 1);
}
do
{
sp_session_process_events(g_sess, &next_timeout);
}
while (next_timeout == 0);
pthread_mutex_lock(&g_notify_mutex);
}
我发现metadata_update被主循环调用,但当轨道创建后,这个循环将持续很长时间(大约290秒)。
除非调用sp_session_process_events()
,否则不会调用metadata_updated
。代码停滞300s的原因是登录后,sp_session_process_events()
将下一个调用超时设置为300s。在第3步之后,您可以强制使用自己的notify主线程,这样可以解决问题。不幸的是,我不知道为什么libspotify此时不发送通知主线程。我想我们都错过了什么。