2013-07-22 2 views
0

Недавно я начал использовать libspotify и писал простой мир привет, основанный на образцовом коде jukebox.h.Libspotify простой мир привет

Мой код в настоящее время выглядит следующим образом:

#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 = &notify_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; 
} 

Проблема заключается в том, что sp_playlistcontainer_num_playlists возвращается 0, даже если мой счет около 10 списков воспроизведения.

Моя система: Windows 7 x64 с MinGW.

Что я делаю неправильно?

ответ

1

Если вы ищете источник jukebox.c, вам необходимо убедиться, что контейнер воспроизведения полностью загружен, прежде чем пытаться запросить его для плейлистов. Так что если я правильно понял, вы должны добавить обратный вызов для container_loaded.
Я также думаю, что вы должны настроить обратный вызов, чтобы вы были уведомлены о том, что пользователь вошел в систему и когда вы вошли в систему, вы должны попытаться получить контейнер списка воспроизведения. Нечто подобное могло бы помочь:

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, 
    &notify_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 */ 
} 
+0

Спасибо, за ответ, это не помогло, но я видел некоторые журнал: ChannelError (1, 1, ссылка-треки), то же самое с плейлистами, кулисными дорожек и списков воспроизведения –

+0

Извините, я написал обратный вызов для сеанса callback log_message. Полные сообщения здесь: http://pastebin.com/r7cwGhFY –

+0

@das_j - Я обновил свой ответ, я думаю, вы должны добавить обратный вызов для 'logged_in', а затем, когда вы полностью вошли в систему, вы должны попытаться получить контейнер списка воспроизведения. – Cyclonecode

Смежные вопросы