我正在用 C# 制作一个 .NET Spotify 客户端,使用 LibspotifyDotNet 来包装 libspotify 库,使用 Libspotify 版本 12.1.51。
第一次加载会话播放列表容器(即没有预先存在的设置位置)时,我遇到了一些奇怪的行为。该应用程序检查 libspotify 的函数以检查播放列表容器是否已加载,该函数返回 true,然后据此确定获取所有播放列表是安全的。当它请求播放列表容器中的播放列表数量时,它会得到 0,因此不会加载任何内容。在此之后的一段时间,我收到说播放列表已加载的回调,这确实意味着应用程序在后续运行时可以正常获取播放列表,但在第一次运行时不会。我最好在这个回调上设置一个额外的“isPlaylistReallyLoaded”标志吗?或者这里有什么问题?我将给出我的调试器输出,然后给出一些相关的方法。
调试输出
libspotify> 09:27:28.211 I [user_cache:135] UserCache::initiateGetUsers() will query for 1 users
libspotify> 09:27:28.231 I [ap:1752] Connecting to AP ap.gslb.spotify.com:4070
The thread 'Win32 Thread' (0x172c) has exited with code 0 (0x0).
libspotify> 09:27:28.264 E [c:/Users/spotify-buildagent/BuildAgent/work/1e0ce8a77adfb2dc/client/core/network/proxy_resolver_win32.cpp:215] WinHttpGetProxyForUrl failed
libspotify> 09:27:28.337 I [offline-mgr:2084] Storage has been cleaned
The thread 'Win32 Thread' (0x16f8) has exited with code 0 (0x0).
Itterating over loaded playlists
libspotify> 09:27:44.155 E [ap:1694] AP Socket Error: Undefined Error 0x4E20 (20000)
libspotify> 09:27:45.381 E [ap:3915] Connection error: 117
libspotify> 09:27:54.065 I [ap:1752] Connecting to AP ap.gslb.spotify.com:4070
0 playlists found
libspotify> 09:27:56.290 I [ap:1226] Connected to AP: 78.31.12.21:4070
libspotify> 09:28:03.035 I [user_cache:135] UserCache::initiateGetUsers() will query for 1 users
libspotify> 09:28:03.177 I [user_cache:135] UserCache::initiateGetUsers() will query for 100 users
libspotify> 09:28:03.271 W [core/playlist/playlist.h:45] Adding observer while updating
libspotify> 09:28:03.297 W [core/playlist/playlist.h:45] Adding observer while updating
libspotify> 09:28:03.325 W [core/playlist/playlist.h:45] Adding observer while updating
libspotify> 09:28:03.353 W [core/playlist/playlist.h:45] Adding observer while updating
playlist_added at position 0
playlist_added at position 1
playlist_added at position 2
playlist_added at position 3
playlist_added at position 4
playlist_added at position 5
playlist_added at position 6
playlist_added at position 7
playlist_added at position 8
container_loaded
libspotify> 09:28:03.644 W [core/playlist/playlist.h:45] Adding observer while updating
上面写着“迭代播放列表”的那一行是我检查播放列表的加载状态并发现为 true 并且将进入 GetAllPlaylists() 方法的地方。循环运行后输出显示 0 个播放列表的行,显示检查 sp_playlistcontainer_num_playlists 时返回了多少播放列表。声明“container_loaded”的行是对播放列表容器上的 container_loaded 回调的响应。
游戏中的方法
// this is the method that is called upon login to get the user's playlists
public static List<PlaylistContainer.PlaylistInfo> GetAllSessionPlaylists()
{
waitFor(delegate
{
return PlaylistContainer.GetSessionContainer().IsLoaded
&& PlaylistContainer.GetSessionContainer().PlaylistsAreLoaded;
}, REQUEST_TIMEOUT);
return PlaylistContainer.GetSessionContainer().GetAllPlaylists();
}
在 PlaylistContainer 模型类中
public static PlaylistContainer GetSessionContainer()
{
if (_sessionContainer == null) {
if (Session.GetSessionPtr() == IntPtr.Zero)
throw new InvalidOperationException("No valid session.");
_sessionContainer = new PlaylistContainer(libspotify.sp_session_playlistcontainer(Session.GetSessionPtr()));
}
return _sessionContainer;
}
public bool IsLoaded {
get {
return libspotify.sp_playlistcontainer_is_loaded(_containerPtr);
}
}
public bool PlaylistsAreLoaded {
get {
if (!this.IsLoaded)
return false;
int count = libspotify.sp_playlistcontainer_num_playlists(_containerPtr);
for (int i = 0; i < count; i++) {
if(libspotify.sp_playlistcontainer_playlist_type(_containerPtr, i) == libspotify.sp_playlist_type.SP_PLAYLIST_TYPE_PLAYLIST) {
using (Playlist p = Playlist.Get(libspotify.sp_playlistcontainer_playlist(_containerPtr, i))) {
if (!p.IsLoaded)
return false;
}
}
}
return true;
}
}
public List<PlaylistInfo> GetAllPlaylists() {
if (!GetSessionContainer().IsLoaded)
throw new InvalidOperationException("Container is not loaded.");
List<PlaylistInfo> playlists = new List<PlaylistInfo>();
Logger.WriteDebug("Itterating over loaded playlists");
int count = libspotify.sp_playlistcontainer_num_playlists(_containerPtr);
for (int i = 0; i < count; i++) {
if (libspotify.sp_playlistcontainer_playlist_type(_containerPtr, i) == libspotify.sp_playlist_type.SP_PLAYLIST_TYPE_PLAYLIST) {
IntPtr playlistPtr = libspotify.sp_playlistcontainer_playlist(_containerPtr, i);
playlists.Add(new PlaylistInfo() {
Pointer = playlistPtr,
PlaylistType = libspotify.sp_playlist_type.SP_PLAYLIST_TYPE_PLAYLIST,
ContainerPtr = _containerPtr,
Name = Functions.PtrToString(libspotify.sp_playlist_name(playlistPtr))
});
}
}
Logger.WriteDebug("{0} playlists found", count);
return playlists;
}
我从 Jamcast 插件(真正的唯一示例)中借用了很多我的 API 交互代码,并修复了我发现的问题。但作为 Spotify API 的新手,这似乎是一个很好的开始方式。我正在一点一点地重写它。所以作为一个额外的问题,是否值得我完全重写 Jamcast 的东西并在我把它放在那里之前重新开始?
我知道那里已经有很多了,但是如果您需要更多信息,请告诉我。我很感激你能给这个 libspotify noob 的任何帮助。