【问题标题】:libspotify:how to play a track from a track uri?libspotify:如何从曲目 uri 播放曲目?
【发布时间】:2013-08-08 06:51:56
【问题描述】:

这个问题听起来很简单,但我找不到检查轨道 uri 是否正确的方法。

例如,通过给定的有效曲目 uri spotify:track:5Z7ygHQo02SUrFmcgpwsKW 播放曲目的正常过程是:

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 但 metadata_updated 和

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("%d\n",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);
}

我发现主循环调用了元数据更新,但是当轨道创建后,这个循环会挂起很长一段时间(大约 290 秒)。

【问题讨论】:

  • 你有没有按要求调用sp_session_process_events的事件循环?
  • 当然。而且上面的所有动作都在循环中,对吗?
  • 听起来不错。我认为您可以并且应该在添加对 sp_track 的引用后释放 sp_link,但这不应停止播放曲目,这仅意味着您可能会泄漏资源。我发现第 4 步有点难以理解——也许你在那里漏掉了一个字?你能澄清一下这一切发生在你的主循环中的时间吗?您是否在 libspotify 的回调期间调用这些函数?您是说它对某些轨道 uri 有效,但对其他轨道 uri 无效,还是根本不起作用?
  • 我已经添加了主循环的代码。任何 uri 返回 SP_ERROR_IS_LOADING,并且从未调用 metadata_updated。

标签: spotify libspotify


【解决方案1】:

metadata_updated 不会被调用,除非sp_session_process_events() 被调用。您的代码停滞 300 秒的原因是登录后,sp_session_process_events() 将下一次调用超时设置为 300 秒。在第 3 步之后,您可以强制自己的通知主线程,这将解决问题。不幸的是,我不知道为什么 libspotify 此时不发送通知主线程。我想我们都在这里遗漏了一些东西。

【讨论】:

    猜你喜欢
    • 2023-03-27
    • 1970-01-01
    • 2013-08-07
    • 2013-03-21
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多