// 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); }
SP_LIBEXPORT(sp_error) sp_session_player_load(sp_session *session, sp_track *track) { void **container; if(session == NULL || track == NULL) { return SP_ERROR_INVALID_INDATA; } else if(!sp_track_is_loaded(track)) { return SP_ERROR_RESOURCE_NOT_LOADED; } else if(!sp_track_is_available(track)) { return SP_ERROR_TRACK_NOT_PLAYABLE; } /* Unload any previously loaded track */ player_push(session, PLAYER_UNLOAD, NULL, 0); /* The track will released in player.c when PLAYER_UNLOAD is called */ container = malloc(sizeof(sp_track *)); *container = track; sp_track_add_ref(track); player_push(session, PLAYER_LOAD, container, sizeof(sp_track *)); return SP_ERROR_OK; }
static PyObject * Track_is_available(Session * self, PyObject *args) { Track *track; if (!PyArg_ParseTuple(args, "O!", &TrackType, &track)) { return NULL; } return Py_BuildValue("i", sp_track_is_available(self->_session, track->_track)); }
JNIEXPORT int JNICALL Java_jahspotify_impl_JahSpotifyImpl_playTrack (JNIEnv *env, jobject obj, jstring uri) { uint8_t *nativeURI = NULL; fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Initiating play\n"); nativeURI = ( uint8_t * ) ( *env )->GetStringUTFChars ( env, uri, NULL ); fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: uri: %s\n", nativeURI); if (!g_audio_initialized) { audio_init(&g_audiofifo); g_audio_initialized = JNI_TRUE; } // For each track, read out the info and populate all of the info in the Track instance sp_link *link = sp_link_create_from_string(nativeURI); if (link) { sp_track *t = sp_link_as_track(link); if (!t) { fprintf(stderr,"No track from link\n"); return; } while (!sp_track_is_available(g_sess,t)) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Waiting for track ...\n"); sleep(1); } if (sp_track_error(t) != SP_ERROR_OK) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Error with track: %s\n",sp_error_message(sp_track_error(t))); return; } fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: name: %s duration: %d\n",sp_track_name(t),sp_track_duration(t)); if (g_currenttrack == t) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Same track!\n"); return; } // If there is one playing, unload that now if (g_currenttrack && t != g_currenttrack) { // audio_fifo_flush(&g_audiofifo); // Unload the current track now sp_session_player_unload(g_sess); sp_link *currentTrackLink = sp_link_create_from_track(g_currenttrack,0); char *currentTrackLinkStr = NULL; if (currentTrackLink) { currentTrackLinkStr = malloc ( sizeof ( char ) * ( 100 ) ); sp_link_as_string(currentTrackLink,currentTrackLinkStr,100); sp_link_release(currentTrackLink); } signalTrackEnded(currentTrackLinkStr, JNI_TRUE); if (currentTrackLinkStr) { free(currentTrackLinkStr); } sp_track_release(g_currenttrack); g_currenttrack = NULL; } else { // audio_fifo_flush(&g_audiofifo); // audio_close(); // audio_init(&g_audiofifo); } sp_track_add_ref(t); sp_error result = sp_session_player_load(g_sess, t); if (sp_track_error(t) != SP_ERROR_OK) { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Issue loading track: %s\n", sp_error_message((sp_track_error(t)))); } fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Track loaded: %s\n", (result == SP_ERROR_OK ? "yes" : "no")); // Update the global reference g_currenttrack = t; // Start playing the next track sp_session_player_play(g_sess, 1); fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Playing track\n"); sp_link_release(link); signalTrackStarted(nativeURI); return 0; } else { fprintf(stderr,"jahspotify::Java_jahspotify_impl_JahSpotifyImpl_play: Unable to load link at this point\n"); } return 1; }
/* only used to trigger sp_session_process_events when needed, * looks like about once a second */ static void* spotify_thread_func (void *data) { int timeout = -1; GTimeVal t; GstSpotSrc *spot = (GstSpotSrc *) data; if (!spotify_create_session (spot)) { GST_ERROR_OBJECT (spot, "Create_session error"); return FALSE; } while (spot->keep_spotify_thread) { sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); g_get_current_time (&t); g_time_val_add (&t, timeout * 1000); g_cond_timed_wait (spot->process_events_cond, spot->process_events_mutex, &t); spot->spotify_thread_initiated = TRUE; while (spot->spot_works) { struct spot_work *spot_work; sp_error ret = SP_ERROR_INVALID_INDATA; spot_work = (struct spot_work *)spot->spot_works->data; g_mutex_lock (spot_work->spot_mutex); switch (spot_work->cmd) { case SPOT_CMD_START: GST_DEBUG_OBJECT (spot, "Uri = %s", GST_SPOT_SRC_URI_LOCATION (spot)); if (!spotify_login (spot)) { /* error message from within function */ break; } sp_link *link = sp_link_create_from_string (GST_SPOT_SRC_URI_LOCATION (spot)); if (!link) { GST_ERROR_OBJECT (spot, "Incorrect track ID:%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } GST_SPOT_SRC_CURRENT_TRACK (spot) = sp_link_as_track (link); if (!GST_SPOT_SRC_CURRENT_TRACK (spot)) { GST_ERROR_OBJECT (spot, "Could get track from uri=%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } #if 0 /* FIXME: why does not this work? */ if (!sp_track_is_available (GST_SPOT_SRC_CURRENT_TRACK (spot))) { /* this probably happens for tracks avaiable in other countries or something */ GST_ERROR_OBJECT (spot, "Track is not available, uri=%s", GST_SPOT_SRC_URI_LOCATION (spot)); break; } #endif sp_track_add_ref (GST_SPOT_SRC_CURRENT_TRACK (spot)); sp_link_add_ref (link); sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); while (sp_track_is_loaded (GST_SPOT_SRC_CURRENT_TRACK (spot)) == 0) { sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); usleep (10000); } GST_DEBUG_OBJECT (spot, "Now playing \"%s\"", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot))); ret = sp_session_player_load (GST_SPOT_SRC_SPOTIFY_SESSION (spot), GST_SPOT_SRC_CURRENT_TRACK (spot)); if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed to load track '%s' uri=%s", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot)), (GST_SPOT_SRC_URI_LOCATION (spot))); break; } sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), TRUE); if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed to play track '%s' uri=%s", sp_track_name (GST_SPOT_SRC_CURRENT_TRACK (spot)), (GST_SPOT_SRC_URI_LOCATION (spot))); break; } break; case SPOT_CMD_PROCESS: sp_session_process_events (GST_SPOT_SRC_SPOTIFY_SESSION (spot), &timeout); break; case SPOT_CMD_PLAY: ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), TRUE); break; case SPOT_CMD_DURATION: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_track_duration (GST_SPOT_SRC_CURRENT_TRACK (spot)); } break; case SPOT_CMD_STOP: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_session_player_play (GST_SPOT_SRC_SPOTIFY_SESSION (spot), FALSE); if (ret != SP_ERROR_OK) { break; } ret = SP_ERROR_OK; sp_session_player_unload (GST_SPOT_SRC_SPOTIFY_SESSION (spot)); } break; case SPOT_CMD_SEEK: if (GST_SPOT_SRC_CURRENT_TRACK (spot)) { ret = sp_session_player_seek (GST_SPOT_SRC_SPOTIFY_SESSION (spot), spot_work->opt); } break; default: g_assert_not_reached (); break; } /* print all errors caught and propagate to calling thread */ if (ret != SP_ERROR_OK) { GST_ERROR_OBJECT (spot, "Failed with SPOT_CMD=%d, ret=%d, error=%s", spot_work->cmd, ret, sp_error_message (ret)); } spot_work->ret = ret; spot->spot_works = g_list_remove (spot->spot_works, spot->spot_works->data); g_mutex_unlock (spot_work->spot_mutex); g_cond_broadcast (spot_work->spot_cond); } } return NULL; }