Libspotify 播放问题

Posted

技术标签:

【中文标题】Libspotify 播放问题【英文标题】:Libspotify playing problems 【发布时间】:2012-10-24 18:33:25 【问题描述】:

我正在围绕 libspotfiy 编写 C# 包装器,但在播放曲目时遇到了问题。据我所知,当我想在会话中第一次开始流式传输曲目时,我应该调用

sp_session_player_load(sessionHandle, trackHandle)
sp_session_player_play(sessionHandle, true);

这就是我正在做的事情,而且效果很好。当我想玩其他东西时,问题就开始了。有一首曲目仍在播放,我该怎么做才能播放新曲目?我应该打电话吗

sp_session_player_play(sessionHandle, false);
sp_session_player_unload(sessionHandle);

在此之前调用新一轮的加载/播放?我问是因为当我这样做时,我经常看到我的程序在我调用 unload 时挂起,或者使用 false 参数调用 play。我正在使用 get_audio_buffer_stats 回调。我有适当的线程同步,所以我想知道我是否错误地唱了 api?

【问题讨论】:

【参考方案1】:

这正是官方 Mac 和 ios 库所做的,并且运行良好:

第一次玩时:

sp_session_player_load(sessionHandle, trackHandle)
sp_session_player_play(sessionHandle, true);

再次播放时:

sp_session_player_play(sessionHandle, false);
sp_session_player_unload(sessionHandle);
sp_session_player_load(sessionHandle, trackHandle)
sp_session_player_play(sessionHandle, true);

不过,您可以检查以下几点:

我见过的最常见的挂起是由于程序如何实现notify_main_thread 回调。当您收到此信息时,您必须以 非阻塞 方式在主线程上安排调用sp_session_process_events。即,您的 notify_main_thread 实现应该在另一个线程上调用 sp_session_process_events 之前返回。

尝试取出您的 get_audio_buffer_stats 实现。这个 Mac/iOS 库根本没有实现这一点 - 它不是必需的。

如果这还不够,请尝试获取挂起的堆栈跟踪。如果你在调试器中捕获它,点击暂停通常就足够了。

【讨论】:

我的代码通过简单地向另一个线程发出信号来响应 notify_main_thread 回调,因此它完全是非阻塞的。 超过 600 个字符如何回复?【参考方案2】:

我的代码通过简单地向另一个线程发出信号来对 notify_main_thread 回调作出反应,因此它完全是非阻塞的。

我似乎已经解决了一些问题,但我仍然有些困惑。我确实删除了 get_audio_buffer_stats 回调。然而,似乎有帮助的事情是在调用 sp_session_player_unload 之前停止在 music_delivery 回调中执行任何操作。

我在music_delivery 回调中所做的所有事情都被锁定了,同样的锁定保护了sp_session_player_unload。所以似乎在执行 sp_session_player_unload 时,libspotify 中的另一个线程会触发 music_delivery 回调,这自然要等待 sp_session_player_unload 完成。看来这可能会导致死锁。

我认为通过确保music_delivery 回调和其他libspotify 函数(即sp_session_player_unload)应该由同一个互斥锁保护,我做了正确的事情?也许在 music_delivery 中正确的做法是立即返回,如果尝试获取锁失败,则报告没有采样? (那么在 process_events 线程之外进行的所有回调都会是这种情况吗?)

【讨论】:

您的观察是正确的,您的notify_main_thread 方法非常好。实际上我想说的是,您根本不应该使用与任何“主线程”方法相同的互斥锁来保护您的 music_delivery,包括 sp_session_player_unload 好的,但我不需要确保在任何非主线程回调期间都没有调用任何 libspotify 方法? 您需要确保不会从多个线程同时调用 libspotify 方法。如果你的非主线程回调实现不直接回调到 libspotify,你可以同时在主线程中进行,没有问题。

以上是关于Libspotify 播放问题的主要内容,如果未能解决你的问题,请参考以下文章

libspotify 和本地 MP3 文件

使用 libspotifydotnet (Spotify - libspotify) 流式传输音频

从 nodeJS 模块调用时,libspotify 注销崩溃

android java的libspotify 12是不是存在任何lib?

获取Spotify播放列表内容的意外结果

是否可以使用 Spotify API 播放整首歌曲?