2012-11-04 30 views
2

我正在寫一個C#包裝libspotfiy周圍,並有軌道玩的問題。從我所知道的,當我要開始流媒體會話中的第一次軌道,我應該叫Libspotify玩的問題

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

這是我在做什麼,並能正常工作。當我想玩別的東西時,問題就開始了。隨着曲目的繼續演奏,我打算如何演奏新曲目?我應該打電話

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

然後再調用新一輪加載/播放?我問,因爲當我這樣做時,我經常看到我的程序在我調用卸載時掛起,或者用虛假的參數調用播放。我正在使用get_audio_buffer_stats回調。我有適當的線程同步,所以我想知道如果我不正確地唱api?

回答

4

這也正是官方的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庫根本沒有實現 - 它不是必需的。

如果這還不夠,請嘗試獲取掛起的堆棧跟蹤。如果你在調試器中捕獲它,打停頓通常足夠好。

+0

我的代碼通過簡單地發信號通知另一個線程來響應notify_main_thread回調,所以它完全沒有阻塞。 –

+0

如何用600多個字符對此進行響應? –

0

我的代碼通過簡單地發信號給另一個線程來響應notify_main_thread回調,所以它完全沒有阻塞。

我似乎已經解決了一些事情,但我仍然有點困惑。我確實刪除了get_audio_buffer_stats回調。然而,似乎有用的東西是在調用sp_session_player_unload之前停止在music_delivery回調中做任何事情。

我鎖定了我在music_delivery回調中所做的evrything,以及保護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線程之外進行的所有回調,情況會如此嗎?)

+0

你的觀察結果是正確的,你的'notify_main_thread'方法非常好。我實際上甚至會說,你不應該用任何「主線程」方法保護你的'music_delivery',包括'sp_session_player_unload'。 – iKenndac

+0

好吧,但我不需要確保在任何非主線程回調期間不調用libspotify方法? –

+0

您需要確保libspotify方法不會從多個線程同時被調用。如果你的非主線程回調實現不直接調回libspotify,你可以在主線程中同時進行,沒有任何問題。 – iKenndac