// Start playback. void sess_play(sp_track *t) { if (g_session.state != SESS_ONLINE) { log_append("Not connected"); return; } if (!t || !sp_track_is_available(t) || !sp_track_is_loaded(t)) { log_append("Track not available"); return; } sess_stop(); g_session.current_track = t; log_append("Playing \"%s\"...", sp_track_name(t)); sp_error err = sp_session_player_load(g_session.spotify, t); if (err != SP_ERROR_OK) panic("sp_session_player_load() failed: %s", sp_error_message(err)); err = sp_session_player_play(g_session.spotify, true); if (err != SP_ERROR_OK) panic("sp_session_player_play() failed: %s", sp_error_message(err)); g_session.playing = true; // Redraw track info and progress. ui_dirty(UI_TRACKINFO); ui_dirty(UI_TRACKPROGRESS); ui_update_post(0); }
static void sess_cb_search_complete_cb(sp_search *res, void *data) { (void)data; log_append("Search result: %d/%d", sp_search_num_tracks(res), sp_search_total_tracks(res)); ui_dirty(UI_SIDEBAR); ui_dirty(UI_TRACKLIST); ui_update_post(0); }
static void sess_cb_logged_in(sp_session *sess, sp_error err) { if (err == SP_ERROR_OK) { g_session.state = SESS_ONLINE; log_append("Logged in as \"%s\"", sp_user_display_name(sp_session_user(sess))); ui_dirty(UI_FOOTER); ui_show(UI_SET_BROWSER); } else { g_session.state = SESS_ERROR; log_append(sp_error_message(err)); ui_dirty(UI_FOOTER); ui_show(UI_SET_LOG); } }
void sess_connect() { assert(g_session.username && g_session.password); sess_disconnect(); if (!(g_session.dsfy = despotify_init_client(sess_callback, NULL, true, true))) panic("despotify_init_client(...) failed"); play_state = PAUSE; pthread_create(&thread, NULL, &thread_loop, g_session.dsfy); // Login with credentials set by sess_username/sess_password. if (!despotify_authenticate(g_session.dsfy, g_session.username, g_session.password)) { g_session.state = SESS_ERROR; log_append(despotify_get_error(g_session.dsfy)); despotify_exit(g_session.dsfy); // Switch to log view. ui_show(UI_SET_LOG); } else { g_session.state = SESS_ONLINE; log_append("Logged in as %s@%s:%d (%s)", g_session.dsfy->user_info->username, g_session.dsfy->user_info->server_host, g_session.dsfy->user_info->server_port, g_session.dsfy->user_info->country); // Switch to browser view. ui_show(UI_SET_BROWSER); } // Redraw status info. ui_dirty(UI_FOOTER); }
static void sess_cb_logged_out(sp_session *sess) { (void)sess; g_session.state = SESS_OFFLINE; log_append("Logged out"); ui_dirty(UI_FOOTER); ui_update_post(0); if (g_session.exiting) sess_cleanup(); }
void sess_disconnect() { if (thread) thread_exit(); if (g_session.state == SESS_ONLINE) { sess_stop(); despotify_exit(g_session.dsfy); log_append("Disconnected"); // Return to splash screen. ui_show(UI_SET_SPLASH); } g_session.state = SESS_OFFLINE; // Redraw status info. ui_dirty(UI_FOOTER); }
// Stop playback. void sess_stop() { if (g_session.state != SESS_ONLINE || !g_session.current_track || !sp_track_is_loaded(g_session.current_track)) return; sp_session_player_unload(g_session.spotify); g_session.current_track = NULL; g_session.playing = false; g_session.paused = false; audio_clear_position(); log_append("Stopped"); // Redraw track info. ui_dirty(UI_TRACKINFO); ui_update_post(0); }
// Toggle playback pause. void sess_pause() { if (g_session.state != SESS_ONLINE || !g_session.playing || !g_session.current_track || !sp_track_is_loaded(g_session.current_track)) return; g_session.paused = !g_session.paused; sp_error err = sp_session_player_play(g_session.spotify, !g_session.paused); if (err != SP_ERROR_OK) panic("sp_session_player_play() failed: %s", sp_error_message(err)); if (g_session.paused) { log_append("Paused"); } else { // Continue updating track progress. ui_dirty(UI_TRACKPROGRESS); log_append("Resuming"); } }
void sess_disconnect() { if (g_session.state == SESS_ONLINE) { sess_stop(); sp_error err = sp_session_logout(g_session.spotify); if (err != SP_ERROR_OK) panic("sp_session_logout() failed: %s", sp_error_message(err)); log_append("Disconnecting..."); g_session.state = SESS_DISCONNECTING; // Return to splash screen. ui_show(UI_SET_SPLASH); } // Redraw status info. ui_dirty(UI_FOOTER); ui_update_post(0); }
void sess_init(struct event_base *evbase) { g_session.evbase = evbase; g_session.spot_ev = evtimer_new(evbase, sess_event_cb, &g_session); g_session.stop_ev = evtimer_new(evbase, sess_stop_cb, &g_session); g_session.exiting = false; g_session.current_track = NULL; sp_session_config config = { .api_version = SPOTIFY_API_VERSION, .cache_location = "tmp", .settings_location = "tmp", .application_key = g_appkey, .application_key_size = g_appkey_size, .user_agent = POLSPOT_USER_AGENT, .callbacks = &g_callbacks, .userdata = &g_session }; sp_error err = sp_session_init(&config, &g_session.spotify); if (err != SP_ERROR_OK) panic("sp_session_init() failed: %s", sp_error_message(err)); } void sess_cleanup() { // If user is logged in then initiate logout. This will change the session // state to SESS_DISCONNECTING. Another call to this function will thus exit // the main loop without waiting for the logout process to finish, allowing // users to avoid waiting for timeouts by issuing the quit commant twice. if (g_session.state == SESS_ONLINE) { sess_disconnect(); g_session.exiting = true; } else { free(g_session.username); g_session.username = 0; free(g_session.password); g_session.password = 0; // Free search results. for (sess_search_t *s = g_session.search; s;) { sp_search_release(s->res); sess_search_t *p = s; s = s->next; free(p); } g_session.current_track = NULL; event_free(g_session.spot_ev); // Exit main event loop. event_base_loopbreak(g_session.evbase); } } void sess_connect() { assert(g_session.username && g_session.password); sess_disconnect(); // Login with credentials set by sess_username/sess_password. sp_error err = sp_session_login(g_session.spotify, g_session.username, g_session.password); if (err != SP_ERROR_OK) panic("sp_session_login() failed: %s", sp_error_message(err)); log_append("Connecting..."); // Redraw status info. g_session.state = SESS_CONNECTING; ui_dirty(UI_FOOTER); ui_update_post(0); }