/* initializes some needed variables */ void init(void) { FILE *f = fopen("log.spotify", "wb"); fclose(f); sp_error error; sp_session *session; username = malloc(sizeof(char)*30); password = malloc(sizeof(char)*30); audio_init(&g_audiofifo); session_config.application_key_size = g_appkey_size; pthread_mutex_init(¬ify_mutex, NULL); pthread_cond_init(¬ify_cond, NULL); pthread_cond_init(&promt_cond, NULL); queue_entry = malloc(sizeof(q_entry)); queue_entry->size = 0; queue_entry->is_playing = FALSE; queue_entry->head = NULL; queue_entry->tail = NULL; /* create the spotify session */ error = sp_session_create(&session_config, &session); if (error != SP_ERROR_OK) { fprintf(stderr, "Error: unable to create spotify session: %s\n", sp_error_message(error)); return; } g_session = session; }
int main(void) { sp_error error; sp_session *session; // create the spotify session spconfig.application_key_size = g_appkey_size; error = sp_session_create(&spconfig, &session); if (error != SP_ERROR_OK) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(error)); return 1; } // initialize audio audio_init(&g_audiofifo); // log in g_logged_in = 0; sp_session_login(session, username, password, 0, NULL); // main loop g_playing = 0; g_running = 1; int next_timeout = 0; while (g_running) { sp_session_process_events(session, &next_timeout); if (g_logged_in && !g_playing) { run_search(session); g_playing = 1; } } return 0; }
sp_session * mocksp_session_create(const sp_session_config *config, sp_connectionstate connectionstate, int offline_time_left, sp_offline_sync_status *sync_status, int offline_num_playlists, int offline_tracks_to_sync, sp_playlist *inbox) { sp_session *session = ALLOC(sp_session); sp_session_config *cloned_config = ALLOC(sp_session_config); if (config) { config = MEMCPY(cloned_config, config, sp_session_config); } cloned_config->application_key = "appkey_good"; sp_session_create(cloned_config, &session); session->connectionstate = connectionstate; session->offline_time_left = offline_time_left; if (sync_status) { session->offline_sync_status = ALLOC(sp_offline_sync_status); MEMCPY(session->offline_sync_status, sync_status, sp_offline_sync_status); } session->offline_num_playlists = offline_num_playlists; session->offline_tracks_to_sync = offline_tracks_to_sync; session->inbox = inbox; return session; }
SpotifySession::SpotifySession() : loggedInEvent(CreateEvent(NULL, FALSE, FALSE, NULL)), threadData(spotifyCS), decoderOwner(NULL) { processEventsEvent = CreateEvent(NULL, FALSE, FALSE, NULL); threadData.processEventsEvent = processEventsEvent; threadData.sess = getAnyway(); memset(&initOnce, 0, sizeof(INIT_ONCE)); static sp_session_callbacks session_callbacks = {}; static sp_session_config spconfig = {}; PWSTR path; if (SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &path)) throw pfc::exception("couldn't get local app data path"); size_t num; char lpath[MAX_PATH]; if (wcstombs_s(&num, lpath, MAX_PATH, path, MAX_PATH)) { CoTaskMemFree(path); throw pfc::exception("couldn't convert local app data path"); } CoTaskMemFree(path); if (strcat_s(lpath, "\\foo_input_spotify")) throw pfc::exception("couldn't append to path"); spconfig.api_version = SPOTIFY_API_VERSION, spconfig.cache_location = lpath; spconfig.settings_location = lpath; spconfig.application_key = g_appkey; spconfig.application_key_size = g_appkey_size; spconfig.user_agent = "spotify-foobar2000-faux-" MYVERSION; spconfig.userdata = this; spconfig.callbacks = &session_callbacks; session_callbacks.logged_in = &logged_in; session_callbacks.notify_main_thread = ¬ify_main_thread; session_callbacks.music_delivery = &music_delivery; session_callbacks.play_token_lost = &play_token_lost; session_callbacks.end_of_track = &end_of_track; session_callbacks.log_message = &log_message; session_callbacks.message_to_user = &message_to_user; session_callbacks.start_playback = &start_playback; { LockedCS lock(spotifyCS); if (NULL == CreateThread(NULL, 0, &spotifyThread, &threadData, 0, NULL)) { throw pfc::exception("Couldn't create thread"); } assertSucceeds("creating session", sp_session_create(&spconfig, &sp)); } }
void *start_spotify(void *arg) { printf("Spotify: Started\n"); int next_timeout = 0; sp_error err; /* Create session */ session_config.application_key_size = g_appkey_size; err = sp_session_create(&session_config, &session); if(err != SP_ERROR_OK) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); return NULL; } sp_session_login(session, username, password, 1); for (;;) { if (next_timeout == 0) { while(!g_notify_do && !g_playback_done) pthread_cond_wait(&g_notify_cond, &g_notify_mutex); } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &ts); #else struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); #endif 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 = 0; pthread_mutex_unlock(&g_notify_mutex); if (g_playback_done) { // track_ended(); g_playback_done = 0; } do { sp_session_process_events(session, &next_timeout); } while (next_timeout == 0); pthread_mutex_lock(&g_notify_mutex); } }
/** * We'll spawn off a new thread which will be the 'spotify main thread' */ static void *spotify_init_thread(void *arg) { gazify_t *gazify = (gazify_t *)arg; sp_session_config config; sp_error error; sp_session *session; /// The application key is specific to each project, and allows Spotify /// to produce statistics on how our service is used. extern const char g_appkey[]; /// The size of the application key. extern const size_t g_appkey_size; memset(&config, 0, sizeof(config)); // Always do this. It allows libspotify to check for // header/library inconsistencies. config.api_version = SPOTIFY_API_VERSION; // The path of the directory to store the cache. This must be specified. // Please read the documentation on preferred values. config.cache_location = "tmp"; // The path of the directory to store the settings. // This must be specified. // Please read the documentation on preferred values. config.settings_location = "tmp"; // The key of the application. They are generated by Spotify, // and are specific to each application using libspotify. config.application_key = g_appkey; config.application_key_size = g_appkey_size; // This identifies the application using some // free-text string [1, 255] characters. config.user_agent = "Gazeify"; // Register the callbacks. config.callbacks = &callbacks; audio_init(&g_audiofifo); error = sp_session_create(&config, &session); if (SP_ERROR_OK != error) { fprintf(stderr, "failed to create session: %s\n", sp_error_message(error)); return (void*)2; } gazify->session = session; // Login using the credentials given on the command line. sp_session_login(session, gazify->username, gazify->password); spotify_loop(arg); return NULL; }
static sp_session * create_session(PyObject *client, PyObject *settings) { sp_session_config config; sp_session* session; sp_error error; memset(&config, 0, sizeof(config)); config.api_version = SPOTIFY_API_VERSION; config.userdata = (void*)client; config.callbacks = &g_callbacks; config.cache_location = ""; config.user_agent = "pyspotify-fallback"; config_data(settings, "application_key", &config.application_key, &config.application_key_size); config_string(settings, "cache_location", &config.cache_location); config_string(settings, "settings_location", &config.settings_location); config_string(settings, "user_agent", &config.user_agent); config_string(client, "proxy", &config.proxy); config_string(client, "proxy_username", &config.proxy_username); config_string(client, "proxy_password", &config.proxy_password); debug_printf("cache_location = %s", config.cache_location); debug_printf("settings_location = %s", config.settings_location); debug_printf("user_agent = %s", config.user_agent); debug_printf("proxy = %s", config.proxy); debug_printf("proxy_username = %s", config.proxy_username); debug_printf("proxy_password = %s", config.proxy_password); debug_printf("application_key_size = %zu", config.application_key_size); if (PyErr_Occurred() != NULL) { return NULL; } if (strlen(config.user_agent) > 255) { PyErr_SetString(SpotifyError, "user_agent may not be longer than 255."); return NULL; } if (config.application_key_size == 0) { PyErr_SetString(SpotifyError, "application_key must be provided."); return NULL; } debug_printf("creating session..."); /* TODO: Figure out if we should ever release the session */ error = sp_session_create(&config, &session); if (error != SP_ERROR_OK) { PyErr_SetString(SpotifyError, sp_error_message(error)); return NULL; } session_constructed = 1; g_session = session; return session; }
bool Session::connect() { if (!m_session) { sp_session_config config; Logger::printOut("Creating session"); config.api_version = SPOTIFY_API_VERSION; Logger::printOut("API version:"); char* version = new char[20]; Logger::printOut(itoa(SPOTIFY_API_VERSION, version, 10)); //the api is not copying the string so create a new c string CStdString location = Settings::getCachePath(); char * cstr; cstr = new char [location.size()+1]; strcpy (cstr, location.c_str()); config.cache_location = cstr; config.settings_location = cstr; config.tracefile = NULL; config.application_key = g_appkey; config.application_key_size = g_appkey_size; config.user_agent = "spotyXBMC2"; config.device_id = "XBMC htpc"; sp_session_callbacks cb = m_sessionCallbacks.getCallbacks(); config.callbacks = &cb; config.compress_playlists = true; config.dont_save_metadata_for_playlists = false; config.initially_unload_playlists = false; sp_error error = sp_session_create(&config, &m_session); if (SP_ERROR_OK != error) { Logger::printOut("Failed to create session: error:"); Logger::printOut(sp_error_message(error)); m_session = NULL; return false; } //set high bitrate if (Settings::useHighBitrate()) sp_session_preferred_bitrate(m_session, SP_BITRATE_320k); sp_session_set_connection_type(m_session, SP_CONNECTION_TYPE_WIRED); sp_session_set_connection_rules(m_session, SP_CONNECTION_RULE_NETWORK); sp_session_set_volume_normalization(m_session, Settings::useNormalization()); sp_session_login(m_session, Settings::getUserName().c_str(), Settings::getPassword().c_str(), true); m_isEnabled = true; Logger::printOut("Logged in, returning"); return true; } return false; }
int main() { struct mg_server *server = mg_create_server(NULL, event_handler); mg_set_option(server, "Partyfy", "."); mg_set_option(server, "listening_port", "8080"); const char *username = "******"; //size_t size; char *password = getpass("Enter the password for the account\n"); sp_session *sp; spconfig.application_key_size = g_appkey_size; sp_error err = sp_session_create(&spconfig, &sp); if(SP_ERROR_OK != err) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); exit(1); } g_sess = sp; pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); sp_session_login(g_sess, username, password, 0, NULL); // See if the user logged in successfully printConnectionState(); int timeout = 0; sp_connectionstate state = sp_session_connectionstate(g_sess); while (state != SP_CONNECTION_STATE_LOGGED_IN) { sp_session_process_events(g_sess, &timeout); printf("Logging in...\n"); usleep(100000); state = sp_session_connectionstate(g_sess); } //audio_init(&g_audiofifo); printf("Logged in\n"); for(;;) { mg_poll_server(server, 1000); sp_session_process_events(g_sess, &timeout); //while(!g_notify_do) // pthread_cond_wait(&g_notify_cond, &g_notify_mutex); //g_notify_do = 0; //pthread_mutex_unlock(&g_notify_mutex); //if(g_playback_done) { // g_playback_done = 0; //} //pthread_mutex_lock(&g_notify_mutex); } mg_destroy_server(&server); }
int session_create() { //pthread_mutex_init(&g_notify_mutex, NULL); //pthread_cond_init(&g_notify_cond, NULL); spconfig.application_key_size = g_appkey_size; sp_error error = sp_session_create(&spconfig, &g_session); if (SP_ERROR_OK != error) { printf("session_create - Unable to create session: %s\n", sp_error_message(error)); return 1; } return 0; }
sp_error session_init(sp_session **session) { sp_error error; spconfig.application_key = &_binary_src_appkey_key_start; spconfig.application_key_size = (size_t)(&_binary_src_appkey_key_end - &_binary_src_appkey_key_start); if((error = sp_session_create(&spconfig, session)) != SP_ERROR_OK) { return error; } char *username = get_username(); char *password = get_password(); char *bitrate = get_bitrate(); sp_bitrate preferred_bitrate; if (bitrate != NULL) { if (strcmp(bitrate, "160") == 0) { preferred_bitrate = SP_BITRATE_160k; } else if (strcmp(bitrate, "320") == 0) { preferred_bitrate = SP_BITRATE_320k; } else if (strcmp(bitrate, "96") == 0) { preferred_bitrate = SP_BITRATE_96k; } else { preferred_bitrate = SP_BITRATE_160k; } } else { preferred_bitrate = SP_BITRATE_160k; } sp_session_preferred_bitrate(*session, preferred_bitrate); error = sp_session_login(*session, username, password, 0, NULL); /* * Don't keep a copy of the password in memory. */ memset(password, 0, strlen(password)); free(password); free(username); return error; }
// // -- Spotify stuff ------------------------------------------------------------------------------- // static int initialize_spotify(struct owl_state* state) { TRACE("initialize_spotify\n"); const sp_session_callbacks session_callbacks = { .logged_in = &logged_in_callback, .logged_out = &logged_out_callback, .notify_main_thread = ¬ify_main_thread_callback }; const sp_session_config session_config = { .api_version = SPOTIFY_API_VERSION, .cache_location = ".cache/libspotify/", .settings_location = ".config/libspotify/", .application_key = g_appkey, .application_key_size = g_appkey_size, .callbacks = &session_callbacks, .user_agent = USER_AGENT, .userdata = (void*)state, }; const int error = sp_session_create(&session_config, &(state->spotify_state->session)); if (SP_ERROR_OK != error) { ERROR("Failed to create Spotify session: %s\n", sp_error_message(error)); return -1; } return OWL_OK; } // // -- Actions ------------------------------------------------------------------------------------- // // // Action handler to retrieve application state // static void state_action(struct owl_state *state) { TRACE("Retrieving state....\n"); struct evbuffer *content_buffer = evbuffer_new(); evbuffer_add_printf(content_buffer, "{ \"state\" : %d }", state->state); evhttp_add_header(evhttp_request_get_output_headers(state->http_request), "Content-type", "application/json; charset=UTF-8"); evhttp_send_reply(state->http_request, HTTP_OK, USER_AGENT, content_buffer); evbuffer_free(content_buffer); }
sp_error Session::Initialise( Config& config ) { sp_session_config spConfig; spConfig.api_version = SPOTIFY_API_VERSION; // app specified configuration spConfig.application_key = config.m_appKey; spConfig.application_key_size = config.m_appKeySize; spConfig.cache_location = config.m_cacheLocation; spConfig.settings_location = config.m_settingsLocation; spConfig.user_agent = config.m_userAgent; // locally specified configuration sp_session_callbacks callbacks; memset( &callbacks, 0, sizeof(callbacks) ); callbacks.connection_error = callback_connection_error; callbacks.end_of_track = callback_end_of_track; callbacks.get_audio_buffer_stats = callback_get_audio_buffer_stats; callbacks.logged_in = callback_logged_in; callbacks.logged_out = callback_logged_out; callbacks.log_message = callback_log_message; callbacks.message_to_user = callback_message_to_user; callbacks.metadata_updated = callback_metadata_updated; callbacks.music_delivery = callback_music_delivery; callbacks.notify_main_thread = callback_notify_main_thread; callbacks.play_token_lost = callback_play_token_lost; callbacks.start_playback = callback_start_playback; callbacks.stop_playback = callback_stop_playback; callbacks.streaming_error = callback_streaming_error; callbacks.userinfo_updated = callback_userinfo_updated; spConfig.callbacks = &callbacks; spConfig.userdata = this; spConfig.compress_playlists = config.m_compressPlaylists; spConfig.dont_save_metadata_for_playlists = config.m_dontSaveMetadataForPlaylists; spConfig.initially_unload_playlists = config.m_initiallyUnloadPlaylists; sp_error error = sp_session_create( &spConfig, &m_pSession ); return error; }
bool SpotWorker::start(QString username, QString password) { QByteArray cachePath, settingsPath; cachePath = settings.value("spotify/cache").toString().toLocal8Bit(); settingsPath = settings.value("spotify/settings").toString().toLocal8Bit(); sp_session_config config; config.api_version = SPOTIFY_API_VERSION; config.cache_location = strdup(cachePath.data()); config.settings_location = strdup(settingsPath.data()); config.application_key = g_appkey; config.application_key_size = g_appkey_size; config.user_agent = "libspotify-client"; config.callbacks = &g_callbacks; config.compress_playlists = false; config.dont_save_metadata_for_playlists = false; config.initially_unload_playlists = false; config.device_id = NULL; config.tracefile = NULL; sp_error error = sp_session_create(&config, ¤tSession); if (SP_ERROR_OK != error) { fprintf(stderr, "failed to create session: %s\n", sp_error_message(error)); return false; } // TODO: add callback for error checking to adjust to API changes sp_session_login(currentSession, username.toUtf8().data(), password.toUtf8().data(), true); eventTimer = new QTimer(); connect(eventTimer, SIGNAL(timeout()), SLOT(processEvents())); eventTimer->start(3000); watchDog_ = new QTimer(); connect(watchDog_, SIGNAL(timeout()), SLOT(streamingStopped())); soundSaver_ = new SoundSaver(); alsaWorker_ = new AlsaWorker(); DEBUG printf("Spotworker started with soundSaver and alsaWorker constructed\n"); return true; }
int session_init(void) { sp_session_config config; sp_error error; sp_session *session; sp_session_callbacks callbacks; extern const char g_appkey[]; extern const size_t g_appkey_size; memset(&config, 0, sizeof(config)); memset(&callbacks, 0, sizeof(callbacks)); debug("logging in\n"); if (g_session != NULL) return -1; callbacks.logged_in = &logged_in; callbacks.logged_out = &logged_out; callbacks.connection_error = &connection_error; callbacks.notify_main_thread = ¬ify_main_thread; callbacks.log_message = &log_message; config.api_version = SPOTIFY_API_VERSION; config.cache_location = "/tmp"; config.settings_location = "/tmp"; config.application_key = g_appkey; config.application_key_size = g_appkey_size; config.user_agent = USER_AGENT; config.callbacks = &callbacks; debug("attempting to create session\n"); error = sp_session_create(&config, &session); if (error != SP_ERROR_OK) { debug("failed to create session\n"); fprintf(stderr, "failed to create session: %s\n", sp_error_message(error)); return -2; } debug("session created\n"); g_session = session; return 0; }
/** createSession spotifyWebApi uses custom sessionConfig to not mess with callbacks that are defined. Initilize them as sp_config and create session **/ bool SpotifySession::createSession() { m_config = sp_session_config(); if(!m_sessionConfig.application_key.isEmpty() || m_sessionConfig.g_app_key != NULL) { m_config.api_version = SPOTIFY_API_VERSION; m_config.cache_location = m_sessionConfig.cache_location; m_config.settings_location = m_sessionConfig.settings_location; m_config.application_key = ( m_sessionConfig.application_key.isEmpty() ? m_sessionConfig.g_app_key : m_sessionConfig.application_key); m_config.application_key_size = m_sessionConfig.application_key_size; m_config.user_agent = m_sessionConfig.user_agent; m_config.callbacks = &SpotifyCallbacks::callbacks; m_config.tracefile = m_sessionConfig.tracefile; m_config.device_id = m_sessionConfig.device_id; m_config.compress_playlists = false; m_config.dont_save_metadata_for_playlists = false; m_config.initially_unload_playlists = false; if( !m_sessionConfig.proxyString.isEmpty() ) m_config.proxy = m_sessionConfig.proxyString; if( !m_sessionConfig.proxy_user.isEmpty() ) m_config.proxy_username = m_sessionConfig.proxy_user; if( !m_sessionConfig.proxy_pass.isEmpty() ) m_config.proxy_password = m_sessionConfig.proxy_pass; } m_config.userdata = this; sp_error err = sp_session_create( &m_config, &m_session ); if ( SP_ERROR_OK != err ) { qDebug() << "Failed to create spotify session: " << sp_error_message( err ); return false; } return true; }
sp_error session_init(sp_session **session) { sp_error error; spconfig.application_key = &_binary_src_appkey_key_start; spconfig.application_key_size = (size_t)(&_binary_src_appkey_key_end - &_binary_src_appkey_key_start); if((error = sp_session_create(&spconfig, session)) != SP_ERROR_OK) { return error; } char *username = get_username(); char *password = get_password(); error = sp_session_login(*session, username, password, 0, NULL); /* * Don't keep a copy of the password in memory. */ memset(password, 0, strlen(password)); free(password); free(username); return error; }
void QSpotifySession::init() { memset(&m_sp_callbacks, 0, sizeof(m_sp_callbacks)); m_sp_callbacks.logged_in = callback_logged_in; m_sp_callbacks.logged_out = callback_logged_out; m_sp_callbacks.metadata_updated = callback_metadata_updated; m_sp_callbacks.connection_error = callback_connection_error; m_sp_callbacks.notify_main_thread = callback_notify_main_thread; m_sp_callbacks.music_delivery = callback_music_delivery; m_sp_callbacks.play_token_lost = callback_play_token_lost; m_sp_callbacks.log_message = callback_log_message; m_sp_callbacks.end_of_track = callback_end_of_track; m_sp_callbacks.userinfo_updated = callback_userinfo_updated; m_sp_callbacks.offline_error = callback_offline_error; m_sp_callbacks.connectionstate_updated = callback_connectionstate_updated; m_sp_callbacks.scrobble_error = callback_scrobble_error; QString dpString = settings.value("dataPath").toString(); dataPath = (char *) calloc(strlen(dpString.toLatin1()) + 1, sizeof(char)); strcpy(dataPath, dpString.toLatin1()); memset(&m_sp_config, 0, sizeof(m_sp_config)); m_sp_config.api_version = SPOTIFY_API_VERSION; m_sp_config.cache_location = dataPath; m_sp_config.settings_location = dataPath; m_sp_config.application_key = g_appkey; m_sp_config.application_key_size = g_appkey_size; m_sp_config.user_agent = "CuteSpot"; m_sp_config.callbacks = &m_sp_callbacks; sp_error error = sp_session_create(&m_sp_config, &m_sp_session); if (error != SP_ERROR_OK) { fprintf(stderr, "failed to create session: %s\n", sp_error_message(error)); m_sp_session = nullptr; return; } Q_ASSERT(m_sp_session); sp_session_set_cache_size(m_sp_session, 0); // Remove stored login information from older version of MeeSpot if (settings.contains("username")) { settings.remove("username"); settings.remove("password"); } // Remove old volume information if (settings.contains("volume")) { settings.remove("volume"); } m_offlineMode = settings.value("offlineMode", false).toBool(); checkNetworkAccess(); StreamingQuality quality = StreamingQuality(settings.value("streamingQuality", int(LowQuality)).toInt()); setStreamingQuality(quality); StreamingQuality syncQuality = StreamingQuality(settings.value("syncQuality", int(HighQuality)).toInt()); setSyncQuality(syncQuality); bool syncMobile = settings.value("syncOverMobile", false).toBool(); setSyncOverMobile(syncMobile); QString storedLogin = getStoredLoginInformation(); if (!storedLogin.isEmpty()) { login(storedLogin); } bool shuffle = settings.value("shuffle", false).toBool(); setShuffle(shuffle); bool repeat = settings.value("repeat", false).toBool(); setRepeat(repeat); bool repeatOne = settings.value("repeatOne", false).toBool(); setRepeatOne(repeatOne); bool volumeNormalizeSet = settings.value("volumeNormalize", true).toBool(); setVolumeNormalize(volumeNormalizeSet); m_lfmLoggedIn = false; // Flush cache regularly as we might get killed by life cycle manager / OOM killer QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(flush())); timer->start(60000); connect(this, SIGNAL(offlineModeChanged()), m_playQueue, SLOT(onOfflineModeChanged())); new MPRISMediaPlayer(this); new MPRISMediaPlayerPlayer(this); QDBusConnection::sessionBus().registerObject(QString("/org/mpris/MediaPlayer2"), this, QDBusConnection::ExportAdaptors); QDBusConnection::sessionBus().registerService("org.mpris.MediaPlayer2.CuteSpot"); }
// ---------------------------------------------------------------------------- // bool SpotifyEngine::connect( LPCSTR username, LPCSTR password, LPCSTR blob ) { sp_error err; if ( !m_spotify_session ) { // Create a new Spoty session err = sp_session_create( &spconfig, &m_spotify_session); if ( SP_ERROR_OK != err ) { m_spotify_error.Format( "Unable to create session: %s", sp_error_message(err) ); return false; } } m_login_state = LOGIN_WAIT; err = sp_session_login( m_spotify_session, username, password, 1, blob ); if (SP_ERROR_OK != err) { m_spotify_error.Format( "Unable to log in: %s", sp_error_message(err) ); return false; } // We appear to get a "successful" login callback immediately after the sp_session_login(), // then, eventually, a bad login. This wait is to help combat that odd behavior by sucking up // both messages. It is, obviously, highly timing dependant. ULONG future = GetCurrentTime() + (2 * 1000); while ( GetCurrentTime() < future && getLoginState() != LOGIN_FAILED ) { int next_timeout = 0; do { sp_session_process_events( m_spotify_session, &next_timeout ); } while (next_timeout == 0); Sleep( 100 ); } future = GetCurrentTime() + (60 * 1000); while ( getLoginState() == LOGIN_WAIT ) { int next_timeout = 0; do { sp_session_process_events( m_spotify_session, &next_timeout ); } while (next_timeout == 0); if ( GetCurrentTime() > future ) { m_spotify_error = "Login timed-out"; break; } Sleep( 100 ); } if ( m_login_state != LOGIN_SUCCESS ) return false; m_waveFormat.wFormatTag = WAVE_FORMAT_PCM; m_waveFormat.nChannels = 2; m_waveFormat.nSamplesPerSec = 44100; m_waveFormat.wBitsPerSample = 16; m_waveFormat.cbSize = 0; m_waveFormat.nBlockAlign = (m_waveFormat.wBitsPerSample * m_waveFormat.nChannels) / 8; m_waveFormat.nAvgBytesPerSec = m_waveFormat.nSamplesPerSec * m_waveFormat.nBlockAlign; try { m_audio_out = AudioOutputStream::createAudioStream(); m_audio_out->openAudioStream( &m_waveFormat ); } catch ( std::exception& ex ) { log( ex ); m_spotify_error = ex.what(); disconnect(); return false; } m_track_timer.startThread(); return startThread(); }
JNIEXPORT int JNICALL Java_jahspotify_impl_JahSpotifyImpl_initialize ( JNIEnv *env, jobject obj, jstring username, jstring password ) { sp_session *sp; sp_error err; uint8_t *nativePassword = NULL; uint8_t *nativeUsername = NULL; int next_timeout = 0; if ( !username || !password ) { fprintf ( stderr, "Username or password not specified\n" ); return 1; } /* Create session */ spconfig.application_key_size = g_appkey_size; err = sp_session_create ( &spconfig, &sp ); if ( SP_ERROR_OK != err ) { fprintf ( stderr, "Unable to create session: %s\n",sp_error_message ( err ) ); return 1; } fprintf ( stderr, "Session created %x\n",(int)sp); nativeUsername = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, username, NULL ); nativePassword = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, password, NULL ); g_sess = sp; pthread_mutex_init ( &g_notify_mutex, NULL ); pthread_cond_init ( &g_notify_cond, NULL ); sp_playlistcontainer_add_callbacks ( sp_session_playlistcontainer ( g_sess ),&pc_callbacks,NULL ); fprintf ( stderr, "Initiating login: %s\n",nativeUsername ); sp_session_login ( sp, nativeUsername, nativePassword ); pthread_mutex_lock ( &g_notify_mutex ); for ( ;; ) { if ( next_timeout == 0 ) { while ( !g_notify_do && !g_playback_done ) pthread_cond_wait ( &g_notify_cond, &g_notify_mutex ); } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime ( CLOCK_REALTIME, &ts ); #else struct timeval tv; gettimeofday ( &tv, NULL ); TIMEVAL_TO_TIMESPEC ( &tv, &ts ); #endif 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 = 0; pthread_mutex_unlock ( &g_notify_mutex ); if ( g_playback_done ) { track_ended(); g_playback_done = 0; } sp_connectionstate conn_state = sp_session_connectionstate(sp); switch (conn_state) { case SP_CONNECTION_STATE_UNDEFINED: case SP_CONNECTION_STATE_LOGGED_OUT: case SP_CONNECTION_STATE_LOGGED_IN: break; case SP_CONNECTION_STATE_DISCONNECTED: fprintf ( stderr, "Disconnected!\n"); break; } do { sp_session_process_events ( sp, &next_timeout ); } while ( next_timeout == 0 ); pthread_mutex_lock ( &g_notify_mutex ); } // FIXME: Release the username/password allocated? return 0; }
int main(int argc, char **argv) { sp_session *sp; sp_error err; int next_timeout = 0; const char *username = "******"; const char *password = "******"; int opt; while ((opt = getopt(argc, argv, "g:u:")) != EOF) { switch (opt) { case 'g': g_guid = optarg; break; case 'u': g_user = optarg; break; } } if (!g_guid || !g_user) { usage(basename(argv[0])); exit(1); } spconfig.application_key_size = g_appkey_size; err = sp_session_create(&spconfig, &sp); if (SP_ERROR_OK != err) { exit(1); } g_sess = sp; pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); sp_session_login(sp, username, password); for (;;) { if (next_timeout == 0) { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &ts); #else struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); #endif ts.tv_sec += next_timeout / 1000; ts.tv_nsec += (next_timeout % 1000) * 1000000; pthread_cond_timedwait(&g_notify_cond, &g_notify_mutex, &ts); } pthread_mutex_unlock(&g_notify_mutex); do { sp_session_process_events(sp, &next_timeout); } while (next_timeout == 0); pthread_mutex_lock(&g_notify_mutex); } return 0; }
/********************** *** Init functions *** **********************/ void session_init() { sp_error error; gchar* cache_path; g_debug("Creating session..."); /* Cache path */ cache_path = g_build_filename(g_get_user_cache_dir(), g_get_prgname(), NULL); /* libspotify session config */ sp_session_config config = { .api_version = SPOTIFY_API_VERSION, .cache_location = cache_path, .settings_location = cache_path, .application_key = g_appkey, .application_key_size = g_appkey_size, .user_agent = "spop " SPOP_VERSION, .callbacks = &g_sp_session_callbacks, .userdata = NULL, .compress_playlists = FALSE, .dont_save_metadata_for_playlists = FALSE, .initially_unload_playlists = FALSE, NULL, }; error = sp_session_create(&config, &g_session); if (error != SP_ERROR_OK) g_error("Failed to create session: %s", sp_error_message(error)); /* Set bitrate */ if (config_get_bool_opt("high_bitrate", TRUE)) { g_debug("Setting preferred bitrate to high."); sp_session_preferred_bitrate(g_session, SP_BITRATE_320k); } else { g_debug("Setting preferred bitrate to low."); sp_session_preferred_bitrate(g_session, SP_BITRATE_160k); } if (config_get_bool_opt("offline_high_bitrate", TRUE)) { g_debug("Setting preferred offline bitrate to high."); sp_session_preferred_offline_bitrate(g_session, SP_BITRATE_320k, FALSE); } else { g_debug("Setting preferred offline bitrate to low."); sp_session_preferred_offline_bitrate(g_session, SP_BITRATE_160k, FALSE); } size_t cache_size = config_get_int_opt("cache_size", 0); g_debug("Setting cache size to %zu.", cache_size); sp_session_set_cache_size(g_session, cache_size); g_debug("Session created."); } void session_login(const char* username, const char* password) { g_debug("Logging in..."); if (!g_session) g_error("Session is not ready."); sp_session_login(g_session, username, password, TRUE, NULL); }
int main(int argc, char **argv) { init_session_config(); init_session_callbacks(); init_playlist_callbacks(); init_playlist_container_callbacks(); sp_session *sp; sp_error err; int next_timeout = 0; const char *username = NULL; const char *password = NULL; int opt; while ((opt = getopt(argc, argv, "u:p:l:d")) != EOF) { switch (opt) { case 'u': username = optarg; break; case 'p': password = optarg; break; case 'l': g_listname = optarg; break; case 'd': g_remove_tracks = 1; break; default: exit(1); } } if (!username || !password || !g_listname) { usage(argv[0]); exit(1); } audio_open(); err = sp_session_create(&spconfig, &sp); if (SP_ERROR_OK != err) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); exit(1); } g_sess = sp; g_notify_mutex = SDL_CreateMutex(); g_notify_cond = SDL_CreateCond(); sp_playlistcontainer_add_callbacks( sp_session_playlistcontainer(g_sess), &pc_callbacks, NULL); sp_session_login(sp, username, password); SDL_mutexP(g_notify_mutex); for (;;) { if (next_timeout == 0) { while(!g_notify_do && !g_playback_done) SDL_CondWait(g_notify_cond, g_notify_mutex); } else { SDL_CondWaitTimeout(g_notify_cond, g_notify_mutex, next_timeout); } g_notify_do = 0; SDL_mutexV(g_notify_mutex); if (g_playback_done) { track_ended(); g_playback_done = 0; } do { sp_session_process_events(sp, &next_timeout); } while (next_timeout == 0); SDL_mutexP(g_notify_mutex); } return 0; }
int main(int argc, char **argv) { // Open syslog openlog("spotify-api-server", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); // Initialize program state struct state *state = malloc(sizeof(struct state)); // Initialize libev w/ pthreads evthread_use_pthreads(); state->event_base = event_base_new(); state->async = event_new(state->event_base, -1, 0, &process_events, state); state->timer = evtimer_new(state->event_base, &process_events, state); state->sigint = evsignal_new(state->event_base, SIGINT, &sigint_handler, state); // Initialize APR apr_status_t rv = apr_initialize(); if (rv != APR_SUCCESS) { syslog(LOG_CRIT, "Unable to initialize APR"); return EXIT_FAILURE; } apr_pool_create(&state->pool, NULL); // Initialize libspotify sp_session_callbacks session_callbacks = { .logged_in = &logged_in, .logged_out = &logged_out, .notify_main_thread = ¬ify_main_thread }; sp_session_config session_config = { .api_version = SPOTIFY_API_VERSION, .application_key = g_appkey, .application_key_size = g_appkey_size, .cache_location = ".cache", .callbacks = &session_callbacks, .compress_playlists = false, .dont_save_metadata_for_playlists = false, .settings_location = ".settings", .user_agent = "sphttpd", .userdata = state, }; sp_session *session; sp_error session_create_error = sp_session_create(&session_config, &session); if (session_create_error != SP_ERROR_OK) { syslog(LOG_CRIT, "Error creating Spotify session: %s", sp_error_message(session_create_error)); return EXIT_FAILURE; } // Log in to Spotify sp_session_login(session, username, password, false); event_base_dispatch(state->event_base); event_free(state->async); event_free(state->timer); if (state->http != NULL) evhttp_free(state->http); event_base_free(state->event_base); free(state); return exit_status; }
int main(int argc, char **argv) { sp_session *sp; sp_error err; int next_timeout = 0; const char *username = NULL; const char *password = NULL; const char *serialdevice = NULL; int opt; mtrace(); while ((opt = getopt(argc, argv, "u:p:s:")) != EOF) { switch (opt) { case 'u': username = optarg; break; case 'p': password = optarg; break; case 's': serialdevice = optarg; break; default: exit(1); } } if (!username || !password) { usage(basename(argv[0])); exit(1); } srand(time(NULL)); audio_fifo_reset(&g_musicfifo); audio_fifo_reset(&g_gaplessfifo); audio_fifo_reset(&g_staticfifo1); audio_fifo_reset(&g_staticfifo2); audio_fifo_reset(&g_audiofifo); printf("music fifo: %X\n", &g_musicfifo); printf("gapless fifo: %X\n", &g_gaplessfifo); printf("static1 fifo: %X\n", &g_staticfifo1); printf("static2 fifo: %X\n", &g_staticfifo2); printf("audio fifo: %X\n", &g_audiofifo); hardware_start(serialdevice); hardware_banner("welcome.", 200); hardware_set_callback(_hardware_event); g_static1 = static_init(BROWN_NOISE, "static1.raw"); g_static2 = static_init(PINK_NOISE, "static2.raw"); g_static3 = static_init(WHITE_NOISE, "static3.raw"); g_tuner = tuner_init(); tuner_addchannel(g_tuner, 130 + rand()%100, "Channel 1", "spotify:user:possan:playlist:4g17smZvFZqg4dN74XMBYH"); tuner_addchannel(g_tuner, 410 + rand()%100, "Channel 2", "spotify:user:possan:playlist:2BBVnBjG4Cynww1mnjfV0v"); tuner_addchannel(g_tuner, 700 + rand()%100, "Channel 3", "spotify:user:possan:playlist:72weZVptgKfYFyzafxBdO5"); tuner_goto(g_tuner, rand() % tuner_numchannels(g_tuner)); tuner_tune_by(g_tuner, -70 + rand()%150); printf("Start loop...\n"); spconfig.application_key_size = g_appkey_size; audio_init(&g_audiofifo); // audio_init(&g_gaplessfifo); err = sp_session_create(&spconfig, &sp); if (SP_ERROR_OK != err) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); exit(1); } g_sess = sp; pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); sp_session_login(sp, username, password, 0, NULL); pthread_mutex_lock(&g_notify_mutex); static pthread_t id; pthread_create(&id, NULL, inputloop, NULL); static pthread_t id2; pthread_create(&id2, NULL, gaplessloop, NULL); static pthread_t id3; pthread_create(&id3, NULL, static1loop, NULL); static pthread_t id4; pthread_create(&id4, NULL, static2loop, NULL); static pthread_t id5; pthread_create(&id5, NULL, static3loop, NULL); for (;;) { // printf("In loop\n"); if (next_timeout == 0) { while(!g_notify_do) { pthread_cond_wait(&g_notify_cond, &g_notify_mutex); } } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &ts); #else struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); #endif 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 = 0; pthread_mutex_unlock(&g_notify_mutex); if (g_playback_done) { track_ended(1); g_playback_done = 0; } do { sp_session_process_events(sp, &next_timeout); } while (next_timeout == 0); pthread_mutex_lock(&g_notify_mutex); } return 0; }
PyObject * session_connect(PyObject *self, PyObject *args) { sp_session_config config; PyObject *client; sp_session *session; sp_error error; char *username, *password; char *cache_location, *settings_location, *user_agent; if (!PyArg_ParseTuple(args, "O", &client)) return NULL; PyEval_InitThreads(); memset(&config, 0, sizeof(config)); config.api_version = SPOTIFY_API_VERSION; config.userdata = (void *)client; config.callbacks = &g_callbacks; cache_location = PySpotify_GetConfigString(client, "cache_location"); if (!cache_location) return NULL; config.cache_location = cache_location; #ifdef DEBUG fprintf(stderr, "[DEBUG]-session- Cache location is '%s'\n", cache_location); #endif settings_location = PySpotify_GetConfigString(client, "settings_location"); config.settings_location = settings_location; #ifdef DEBUG fprintf(stderr, "[DEBUG]-session- Settings location is '%s'\n", settings_location); #endif PyObject *application_key = PyObject_GetAttr(client, PyBytes_FromString("application_key")); if (!application_key) { PyErr_SetString(SpotifyError, "application_key not set"); return NULL; } else if (!PyBytes_Check(application_key)) { PyErr_SetString(SpotifyError, "application_key must be a byte string"); return NULL; } char *s_appkey; Py_ssize_t l_appkey; PyBytes_AsStringAndSize(application_key, &s_appkey, &l_appkey); config.application_key_size = l_appkey; config.application_key = PyMem_Malloc(l_appkey); memcpy((char *)config.application_key, s_appkey, l_appkey); user_agent = PySpotify_GetConfigString(client, "user_agent"); if (!user_agent) return NULL; if (strlen(user_agent) > 255) { PyErr_SetString(SpotifyError, "user agent must be 255 characters max"); } config.user_agent = user_agent; #ifdef DEBUG fprintf(stderr, "[DEBUG]-session- User agent set to '%s'\n", user_agent); #endif username = PySpotify_GetConfigString(client, "username"); if (!username) return NULL; password = PySpotify_GetConfigString(client, "password"); if (!password) return NULL; Py_BEGIN_ALLOW_THREADS; #ifdef DEBUG fprintf(stderr, "[DEBUG]-session- creating session...\n"); #endif error = sp_session_create(&config, &session); Py_END_ALLOW_THREADS; if (error != SP_ERROR_OK) { PyErr_SetString(SpotifyError, sp_error_message(error)); return NULL; } session_constructed = 1; #ifdef DEBUG fprintf(stderr, "[DEBUG]-session- login as %s in progress...\n", username); #endif Py_BEGIN_ALLOW_THREADS; sp_session_login(session, username, password); Py_END_ALLOW_THREADS; g_session = session; Session *psession = (Session *) PyObject_CallObject((PyObject *)&SessionType, NULL); psession->_session = session; return (PyObject *)psession; }
int main(int argc, char **argv) { sp_session *sp; sp_error err; int next_timeout = 0; const char *username = NULL; const char *password = NULL; int opt; while ((opt = getopt(argc, argv, "u:p:l:d")) != EOF) { switch (opt) { case 'u': username = optarg; break; case 'p': password = optarg; break; case 'l': g_listname = optarg; break; case 'd': g_remove_tracks = 1; break; default: exit(1); } } if (!username || !password || !g_listname) { usage(basename(argv[0])); exit(1); } audio_init(&g_audiofifo); /* Create session */ spconfig.application_key_size = g_appkey_size; err = sp_session_create(&spconfig, &sp); if (SP_ERROR_OK != err) { fprintf(stderr, "Unable to create session: %s\n", sp_error_message(err)); exit(1); } g_sess = sp; pthread_mutex_init(&g_notify_mutex, NULL); pthread_cond_init(&g_notify_cond, NULL); sp_session_login(sp, username, password, 0, NULL); pthread_mutex_lock(&g_notify_mutex); for (;;) { if (next_timeout == 0) { while(!g_notify_do) pthread_cond_wait(&g_notify_cond, &g_notify_mutex); } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &ts); #else struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); #endif 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 = 0; pthread_mutex_unlock(&g_notify_mutex); if (g_playback_done) { track_ended(); g_playback_done = 0; } do { sp_session_process_events(sp, &next_timeout); } while (next_timeout == 0); pthread_mutex_lock(&g_notify_mutex); } return 0; }
PHP_METHOD(Spotify, __construct) { zval *object = getThis(); zval *z_key, *z_user, *z_pass; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzz", &z_key, &z_user, &z_pass) == FAILURE) { return; } sp_session_config config; sp_error error; sp_session *session; FILE *fp; long key_size; char *key_filename; spotify_object *obj = (spotify_object*)zend_object_store_get_object(object TSRMLS_CC); memset(&config, 0, sizeof(config)); config.api_version = SPOTIFY_API_VERSION; config.cache_location = "tmp"; config.settings_location = "tmp"; config.user_agent = "libspotify-php"; key_filename = Z_STRVAL_P(z_key); fp = fopen(key_filename, "rb"); if (!fp) { zend_throw_exception((zend_class_entry*)zend_exception_get_default(), "Unable to open spotify key file", 0 TSRMLS_CC); return; } fseek(fp, 0L, SEEK_END); key_size = ftell(fp); fseek(fp, 0L, SEEK_SET); if (key_size > 4096) { fclose(fp); zend_throw_exception((zend_class_entry*)zend_exception_get_default(), "Key file is way too large to be a key file", 0 TSRMLS_CC); return; } obj->key_data = (char*)emalloc(sizeof(char) * key_size); if (fread(obj->key_data, 1, key_size, fp) != key_size) { fclose(fp); zend_throw_exception((zend_class_entry*)zend_exception_get_default(), "Failed reading key file", 0 TSRMLS_CC); return; } fclose(fp); config.application_key = obj->key_data; config.application_key_size = key_size; config.callbacks = &callbacks; config.userdata = obj; error = sp_session_create(&config, &session); if (SP_ERROR_OK != error) { zend_throw_exception((zend_class_entry*)zend_exception_get_default(), sp_error_message(error), 0 TSRMLS_CC); return; } sp_session_login(session, Z_STRVAL_P(z_user), Z_STRVAL_P(z_pass), false); obj->session = session; obj->timeout = 0; obj->playlistcontainer = NULL; do { sp_session_process_events(obj->session, &obj->timeout); } while (obj->timeout == 0 || !obj->is_logged_in); }
int main(int argc, char** argv) { for (;;) { int option_index = 0; int c = getopt_long(argc, argv, "hl:u:p:r", NULL, &option_index); if (c == -1) { break ; } switch (c) { case 'h': usage(); break; case 'l': playlist_name = strdup(optarg); break; case 'u': user_name = strdup(optarg); break; case 'p': password = strdup(optarg); break; case 'r': reset = true; break; }; } // setup our spotify config sp_session_config config; memset(&config, 0, sizeof(config)); config.api_version = SPOTIFY_API_VERSION; config.cache_location = "/tmp/spiffify"; config.settings_location = "/tmp/spiffify"; config.application_key = g_appkey; config.application_key_size = g_appkey_size; /* mkdir(config.cache_location, 0); */ /* mkdir(config.settings_location, 0); */ config.user_agent = "spiffify"; sp_session_callbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); callbacks.logged_in = &logged_in; /* callbacks.logged_out = logged_out; */ callbacks.connection_error = &connection_error; callbacks.notify_main_thread = ¬ify_main_thread; config.callbacks = &callbacks; // setup waits pthread_mutex_init(&g_mutex, NULL); pthread_cond_init(&g_cond, NULL); sp_error error = sp_session_create(&config, &session); if (SP_ERROR_OK != error) { fprintf(stderr, "Could not create session: %s\n", sp_error_message(error)); abort(); } error = sp_session_login(session, user_name, password, 0, NULL); if (SP_ERROR_OK != error) { fprintf(stderr, "Could not initiate login: %s\n", sp_error_message(error)); abort(); } pthread_mutex_lock(&g_mutex); int next_timeout=0; int load_completed=0; int messaged_load_waiting=0; for(;;) { if (next_timeout == 0) { while(!g_notify_do) { pthread_cond_wait(&g_cond, &g_mutex); } } else { struct timespec ts; #if _POSIX_TIMERS > 0 clock_gettime(CLOCK_REALTIME, &ts); #else struct timeval tv; gettimeofday(&tv, NULL); TIMEVAL_TO_TIMESPEC(&tv, &ts); #endif pthread_cond_timedwait(&g_cond, &g_mutex, &ts); } g_notify_do = 0; pthread_mutex_unlock(&g_mutex); do { sp_session_process_events(session, &next_timeout); if (load_completed == 0 && validate_complete_load()) { if (did_spiffify == 0 ) { spiffify(); did_spiffify = 1; } sp_session_process_events(session, &next_timeout); // when the container_loaded event comes back (don't ask) we can be sure that our stuff made it to the server and we can exit there. if (can_exit==1) { goto done; } } else { if (messaged_load_waiting==0) { printf("Load not completed.. waiting\n"); messaged_load_waiting = 1; } } } while (next_timeout == 0); pthread_mutex_lock(&g_mutex); } done: error = sp_session_logout(session); if (SP_ERROR_OK != error) { fprintf(stderr, "Could not logout: %s\n", sp_error_message(error)); exit(1); } error = sp_session_release(session); if (SP_ERROR_OK != error) { fprintf(stderr, "Could not destroy session: %s\n", sp_error_message(error)); exit(1); } };
int main(int argc, char **argv) { int listen_fd; sp_session *session; static sp_session_config config; static sp_session_callbacks callbacks = { .logged_in = &sess_callback_logged_in, .logged_out = &sess_callback_logged_out, .metadata_updated = &sess_callback_metadata_updated, .connection_error = NULL, .message_to_user = &sess_callback_message_to_user, .notify_main_thread = &sess_callback_notify, .music_delivery = &player_callback_frame_delivery, .play_token_lost = &player_callback_playtoken_lost, .log_message = &sess_callback_log_message, .end_of_track = &player_callback_end_of_track, .streaming_error = NULL, .userinfo_updated = NULL, .start_playback = &player_callback_start_playback, .stop_playback = &player_callback_stop_playback, .get_audio_buffer_stats = &player_callback_get_audio_buffer_stats, // libspotify 10 .offline_status_updated = &sess_callback_offline_status_updated, .offline_error = &sess_callback_offline_error, // libspotify 11 .credentials_blob_updated = sess_callback_credentials_blob_updated, // libspotify 12 .connectionstate_updated = &sess_callback_connectionstate_updated, .scrobble_error = NULL, .private_session_mode_changed = NULL, }; thread_main = pthread_self(); /* Setup logging to stderr */ openlog(LIBSPOTIFY_USERAGENT, LOG_PERROR, LOG_USER); /** * Filter logging with one of these * setlogmask(LOG_UPTO(LOG_WARNING)); setlogmask(LOG_UPTO(LOG_NOTICE)); setlogmask(LOG_UPTO(LOG_DEBUG)); */ setlogmask(LOG_UPTO(LOG_INFO)); config.api_version = SPOTIFY_API_VERSION; config.cache_location = LIBSPOTIFY_CACHE_DIR; config.settings_location = LIBSPOTIFY_CACHE_DIR; config.application_key = g_appkey; config.application_key_size = sizeof(g_appkey); config.user_agent = LIBSPOTIFY_USERAGENT; config.callbacks = &callbacks; config.userdata = app_create(); config.compress_playlists = 1; config.dont_save_metadata_for_playlists = 0; config.initially_unload_playlists = 0; config.device_id = NULL; syslog(LOG_DEBUG, "MAIN: Initializing libspotify"); if(sp_session_create(&config, &session) != SP_ERROR_OK) { syslog(LOG_ERR, "MAIN: Unable to initialize libspotify"); app_release(); return -1; } app_set_session(session); if(argc == 4) { sp_link *link = sp_link_create_from_string(argv[3]); app_set_link(link); } /* This program will be run on mobile internet connections */ sp_session_set_connection_type(session, SP_CONNECTION_TYPE_MOBILE_ROAMING); sp_session_set_connection_rules(session, SP_CONNECTION_RULE_NETWORK|SP_CONNECTION_RULE_NETWORK_IF_ROAMING|SP_CONNECTION_RULE_ALLOW_SYNC_OVER_MOBILE); sp_session_preferred_offline_bitrate(session, SP_BITRATE_160k, 0); if(argc < 2) { char username[256]; if(sp_session_remembered_user(session, username, sizeof(username)) > 0) syslog(LOG_DEBUG, "MAIN: Attempting to login using stored credentials for user '%s'", username); if(sp_session_relogin(session) == SP_ERROR_NO_CREDENTIALS) { syslog(LOG_ERR, "MAIN: No credentials stored. Please run: %s <username> <password>", argv[0]); app_release(); return -1; } } else { syslog(LOG_DEBUG, "MAIN: Attempting to login using command line credentials"); sp_session_login(session, argv[1], argc == 3? argv[2]: NULL, 1, get_auth_blob()); } if((listen_fd = net_create(CTRL_TCP_PORT)) < 0) { syslog(LOG_ERR, "MAIN: Failed to initialize external network"); app_release(); return -1; } mainloop(session, listen_fd); syslog(LOG_INFO, "MAIN: Outside main event loop, good bye!"); net_release(listen_fd); app_release(); return 0; }