我正在编写一个围绕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时挂起,或者在调用play时使用false参数。我正在使用get_audio_buffer_stats回调。我已经准备好了适当的线程同步,所以我想知道我是否会不正确地使用api?
发布于 2012-11-05 18:48:23
这正是官方的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回调的方式。当你得到它的时候,你必须以非阻塞的方式在主线程上调度一个call so sp_session_process_events。也就是说,你的notify_main_thread实现应该在另一个线程调用sp_session_process_events之前返回。get_audio_buffer_stats实现。这个Mac/iOS库根本没有实现这一点--它不是必需的。如果这还不够,请尝试获取挂起的堆栈跟踪。如果在调试器中捕捉到它,点击pause通常就足够好了。
发布于 2012-11-06 01:50:32
我的代码通过简单地向另一个线程发送信号来响应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线程外部进行的所有回调是否都是这种情况?)
https://stackoverflow.com/questions/13223372
复制相似问题