C++ Libspotify简单问候世界
我最近开始使用libspotify,并根据jukebox.h的示例代码编写了一个简单的hello world 我的代码当前如下所示:C++ Libspotify简单问候世界,c++,audio-streaming,libspotify,C++,Audio Streaming,Libspotify,我最近开始使用libspotify,并根据jukebox.h的示例代码编写了一个简单的hello world 我的代码当前如下所示: #include <stdio.h> #include "libspotify/api.h" #include "Key.h" #include "Password.h" #include <stdlib.h> #include <pthread.h> #include <time.h> #define true
#include <stdio.h>
#include "libspotify/api.h"
#include "Key.h"
#include "Password.h"
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#define true 1
#define false 0
sp_session *g_session;
bool g_notify_do;
static pthread_mutex_t g_notify_mutex;
static pthread_cond_t g_notify_cond;
#define DEBUG 1
__stdcall static void debug(const char *format, ...) {
if (!DEBUG)
return;
va_list argptr;
va_start(argptr, format);
vprintf(format, argptr);
printf("\n");
}
void assertSpotify(sp_error error, char *details) {
if (error != SP_ERROR_OK) {
debug("Fatal error: %s", details);
exit(1);
}
}
__stdcall static void notify_main_thread(sp_session *sess) {
pthread_mutex_lock(&g_notify_mutex);
g_notify_do = 1;
pthread_cond_signal(&g_notify_cond);
pthread_mutex_unlock(&g_notify_mutex);
}
__stdcall static void logged_in(sp_session *sess, sp_error error) {
assertSpotify(error, "Could not log in.");
sp_playlistcontainer *pc = sp_session_playlistcontainer(sess);
printf("Looking at %d playlists\n", sp_playlistcontainer_num_playlists(pc));
}
int main(void) {
sp_error err;
static sp_session_callbacks session_callbacks = {};
static sp_session_config spconfig = {};
int next_timeout = 0;
printf("Starting up...\n");
session_callbacks.notify_main_thread = ¬ify_main_thread;
session_callbacks.logged_in = &logged_in;
spconfig.api_version = SPOTIFY_API_VERSION;
spconfig.cache_location = "tmp";
spconfig.settings_location = "tmp";
spconfig.application_key = g_appkey;
spconfig.application_key_size = g_appkey_size;
spconfig.user_agent = "Hello-World";
spconfig.callbacks = &session_callbacks;
pthread_mutex_init(&g_notify_mutex, NULL);
pthread_cond_init(&g_notify_cond, NULL);
err = sp_session_create(&spconfig, &g_session);
assertSpotify(err, "Could not create Spotify Session.");
debug("Session created.");
err = sp_session_login(g_session, spotify_user, spotify_pw, 0, NULL); //Defined in Password.h
assertSpotify(err, "Could not log in.");
debug("Username: %s", sp_session_user_name(g_session));
err = sp_session_set_connection_type(g_session, SP_CONNECTION_TYPE_WIRED );
assertSpotify(err, "Could not set connection type.");
pthread_mutex_lock(&g_notify_mutex);
while (true) {
if (next_timeout == 0) {
while(!g_notify_do)
pthread_cond_wait(&g_notify_cond, &g_notify_mutex);
} else {
time_t now = time(NULL);
struct timespec ts;
ts.tv_sec = now;
ts.tv_sec = now / 1000000;
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 = false;
pthread_mutex_unlock(&g_notify_mutex);
do {
sp_session_process_events(g_session, &next_timeout);
} while (next_timeout == 0);
pthread_mutex_lock(&g_notify_mutex);
}
return 0;
}
#包括
#包括“libspotify/api.h”
#包括“Key.h”
#包括“Password.h”
#包括
#包括
#包括
#定义真1
#定义false 0
sp_会话*g_会话;
bool g___do;
静态pthread_mutex_t g_notify_mutex;
静态pthread_cond_t g_通知_cond;
#定义调试1
__stdcall静态无效调试(常量字符*格式,…){
如果(!调试)
返回;
va_列表参数;
va_开始(argptr,格式);
vprintf(格式,argptr);
printf(“\n”);
}
void assertSpotify(sp_错误,字符*详细信息){
如果(错误!=SP\U错误\U正常){
调试(“致命错误:%s”,详细信息);
出口(1);
}
}
__stdcall静态无效通知主线程(sp会话*sess){
pthread_mutex_lock(&g_notify_mutex);
g_notify_do=1;
pthread_cond_信号(&g_notify_cond);
pthread_mutex_unlock(&g_notify_mutex);
}
__stdcall静态无效已登录(sp会话*sess,sp错误){
assertSpotify(错误,“无法登录”);
sp_播放列表容器*pc=sp_会话_播放列表容器(sess);
printf(“查看%d个播放列表,\n”,sp_播放列表容器_num_播放列表(pc));
}
内部主(空){
sp_错误;
静态sp_会话_回调会话_回调={};
静态sp_session_config spconfig={};
int next_timeout=0;
printf(“启动…\n”);
session\u callbacks.notify\u main\u thread=¬ify\u main\u thread;
session_callbacks.logged_-in=&logged_-in;
spconfig.api_version=SPOTIFY_api_version;
spconfig.cache_location=“tmp”;
spconfig.settings_location=“tmp”;
spconfig.application\u key=g\u appkey;
spconfig.application\u key\u size=g\u appkey\u size;
spconfig.user_agent=“Hello World”;
spconfig.callbacks=&session\u回调;
pthread_mutex_init(&g_notify_mutex,NULL);
pthread_cond_init(&g_notify_cond,NULL);
err=sp\u session\u create(&spconfig,&g\u session);
assertSpotify(错误,“无法创建Spotify会话”);
调试(“会话已创建”);
err=sp_session_login(g_session,spotify_user,spotify_pw,0,NULL);//在Password.h中定义
assertSpotify(错误,“无法登录”);
调试(“用户名:%s”,sp_会话_用户名(g_会话));
err=sp会话设置连接类型(g会话、sp连接类型);
assertSpotify(错误,“无法设置连接类型”);
pthread_mutex_lock(&g_notify_mutex);
while(true){
如果(下一次超时==0){
而(!g_notify_do)
pthread_cond_wait(&g_notify_cond,&g_notify_mutex);
}否则{
time\u t now=时间(空);
结构timespects;
ts.tv_sec=现在;
ts.tv_sec=now/1000000;
ts.tv_sec+=下一个_超时/1000;
ts.tv\U nsec+=(下一个\U超时%1000)*1000000;
pthread_cond_timedwait(&g_notify_cond,&g_notify_mutex,&ts);
}
g_notify_do=假;
pthread_mutex_unlock(&g_notify_mutex);
做{
sp_会话_进程_事件(g_会话和下一个_超时);
}while(next_timeout==0);
pthread_mutex_lock(&g_notify_mutex);
}
返回0;
}
问题是,sp\u playlicanner\u num\u playlists
返回0
,即使我的帐户有大约10个播放列表
我的系统:带MinGW的Windows 7 x64
我做错了什么?查看播放列表的来源似乎应该确保播放列表容器已完全加载,然后再尝试查询播放列表。
因此,如果我理解正确,您应该为已加载的容器添加一个回调
我还认为您应该设置一个回调,以便在用户登录时收到通知,并且在登录时您应该尝试获取播放列表容器。类似这样的事情可能会有所帮助:
static sp_playlistcontainer_callbacks pc_callbacks = {
NULL, /* playlist_added */
NULL, /* playlist_removed */
NULL, /* playlist_moved */
&container_loaded,
};
static sp_session_callbacks session_callbacks = {
&logged_in,
¬ify_main_thread,
NULL, /* music_delivery */
NULL, /* metadata_updated */
NULL, /* play_token_lost */
NULL, /* log_message */
NULL /* end_of_track */
};
static void container_loaded(sp_playlistcontainer *pc, void *userdata)
{
// container is fully loaded now it should be safe to query the container
int num_playlists = sp_playlistcontainer_num_playlists(pc);
}
static void logged_in(sp_session *sess, sp_error error)
{
// get playlist when user is logged in
sp_playlistcontainer *pc = sp_session_playlistcontainer(sess);
// add callbacks
sp_playlistcontainer_add_callbacks(
pc,
&pc_callbacks,
NULL);
/* rest of code */
}
谢谢,对于你的回答,这没有帮助,但我看到了一些日志:ChannelError(1,1,link tracks),与播放列表、链接曲目和播放列表相同。对不起,我为会话回调日志消息写了一个回调。这里的完整消息:@das_j-我更新了我的答案,我认为您应该为登录的
添加一个回调,然后在完全登录后,您应该尝试获取播放列表容器。