// Loads track if metadata exists, otherwise load the metadata static void load_track_or_metadata(sp_session *session, sp_track *track, const char *uri) { if (track != NULL) { if (s_is_playing) sp_session_player_play(session, false); sp_session_player_unload(session); sp_track_release(track); } track = sp_link_as_track(sp_link_create_from_string(uri)); set_track(track); sp_track_add_ref(track); s_player_position = 0; s_current_uri = uri; // either the track is already cached and can be used or we need to wait for the metadata callback if (sp_track_is_loaded(track)) { load_and_play_track(session, track); } else s_is_waiting_for_metadata = true; }
/********************* * Tracks management * *********************/ GArray* tracks_get_playlist(sp_playlist* pl) { GArray* tracks; sp_track* tr; int i, n; if (!sp_playlist_is_loaded(pl)) return NULL; n = sp_playlist_num_tracks(pl); tracks = g_array_sized_new(FALSE, FALSE, sizeof(sp_track*), n); if (!tracks) g_error("Can't allocate array of %d tracks.", n); for (i=0; i < n; i++) { tr = sp_playlist_track(pl, i); sp_track_add_ref(tr); g_array_append_val(tracks, tr); } return tracks; }
void queue_add_track(gboolean notif, sp_track* track) { sp_track_add_ref(track); if (!sp_track_is_loaded(track)) { sp_track_release(track); g_debug("Track not loaded."); return; } if (!track_available(track)) { sp_track_release(track); g_debug("Track is not available."); return; } g_debug("Adding track %p to queue.", track); g_queue_push_tail(&g_queue, track); if (g_shuffle) queue_setup_shuffle(); g_shuffle_first = g_current_track; if (notif) queue_notify(); }
/************************ *** Queue management *** ************************/ void queue_set_track(gboolean notif, sp_track* track) { sp_track_add_ref(track); if (!sp_track_is_loaded(track)) { sp_track_release(track); g_debug("Track not loaded."); return; } if (!track_available(track)) { sp_track_release(track); g_debug("Track is not available."); return; } g_debug("Setting track %p as queue.", track); queue_clear(FALSE); g_queue_push_tail(&g_queue, track); if (g_shuffle) queue_setup_shuffle(); g_shuffle_first = -1; if (notif) queue_notify(); }
static gboolean rbspotifysrc_start (GstBaseSrc *bsrc) { RBSpotifySrc *src = RBSPOTIFYSRC (bsrc); // sp_error err; sp_link* link; audio_fifo_t *af = &g_audio_fifo; // sp_track* track; // int timeout; fprintf(stderr, "Playing %s\n", src->uri); link = sp_link_create_from_string(src->uri); if (!link) { fprintf(stderr, "Couldn't open file"); return FALSE; } src->track = sp_link_as_track(link); if (!src->track) { fprintf(stderr, "Couldn't turn link to track %s", src->uri); return FALSE; } sp_track_add_ref(src->track); sp_link_release(link); src->tloaded = FALSE; src->played = 0; src->curoffset = 0; audio_fifo_flush(af); return TRUE; }
void track_get_data(sp_track* track, gchar** name, gchar** artist, gchar** album, gchar** link, guint* duration, int* popularity) { sp_artist** art = NULL; sp_album* alb = NULL; sp_link* lnk; int i; int nb_art = 0; const char* s; sp_track_add_ref(track); if (!sp_track_is_loaded(track)) { sp_track_release(track); return; } /* Begin loading everything */ if (name) { *name = g_strdup(sp_track_name(track)); } if (artist) { nb_art = sp_track_num_artists(track); art = (sp_artist**) malloc(nb_art * sizeof(sp_artist*)); if (!art) g_error("Can't allocate memory."); for (i=0; i < nb_art; i++) { art[i] = sp_track_artist(track, i); sp_artist_add_ref(art[i]); } } if (album) { alb = sp_track_album(track); sp_album_add_ref(alb); } if (link) { GString* tmp; lnk = sp_link_create_from_track(track, 0); if (!lnk) g_error("Can't get URI from track."); tmp = g_string_sized_new(1024); if (sp_link_as_string(lnk, tmp->str, 1024) < 0) g_error("Can't render URI from link."); *link = tmp->str; g_string_free(tmp, FALSE); sp_link_release(lnk); } if (duration) { *duration = sp_track_duration(track); } if (popularity) { *popularity = sp_track_popularity(track); } /* Now create destination strings */ if (artist) { GString* tmp = g_string_new(""); for (i=0; i < nb_art; i++) { if (sp_artist_is_loaded(art[i])) s = sp_artist_name(art[i]); else s = "[artist not loaded]"; if (i != 0) g_string_append(tmp, ", "); g_string_append(tmp, s); sp_artist_release(art[i]); } *artist = tmp->str; g_string_free(tmp, FALSE); } if (album) { if (sp_album_is_loaded(alb)) *album = g_strdup(sp_album_name(alb)); else *album = g_strdup("[album not loaded]"); sp_album_release(alb); } sp_track_release(track); }
bool Track::Load( sp_track* track ) { m_pTrack = track; sp_track_add_ref( m_pTrack ); return true; }
void Track::setSpotifyTrack(sp_track *spTrack) { m_spTrack = spTrack; sp_track_add_ref(m_spTrack); }
jobject createJAlbumInstance(JNIEnv *env, sp_album *album) { jclass albumJClass; jobject albumInstance; albumJClass = (*env)->FindClass(env, "jahspotify/media/Album"); if (albumJClass == NULL) { fprintf(stderr,"jahspotify::createJAlbumInstance: could not load jahnotify.media.Album\n"); return NULL; } albumInstance = (*env)->AllocObject(env,albumJClass); if (!albumInstance) { fprintf(stderr,"jahspotify::createJAlbumInstance: could not create instance of jahspotify.media.Album\n"); return NULL; } sp_albumbrowse *albumBrowse = sp_albumbrowse_create(g_sess,album,albumBrowseCompleteCallback,NULL); if (albumBrowse) { sp_albumbrowse_add_ref(albumBrowse); int count = 0; while (!sp_albumbrowse_is_loaded(albumBrowse) && count < 5) { fprintf(stderr,"jahspotify::createJAlbumInstance: waiting for album browse load to complete\n"); sleep(1); count++; } if (count == 5) { sp_albumbrowse_release(albumBrowse); return NULL; } // By now it looks like the album will also be loaded sp_link *albumLink = sp_link_create_from_album(album); if (albumLink) { sp_link_add_ref(albumLink); jobject albumJLink = createJLinkInstance(env, albumLink); setObjectObjectField(env,albumInstance,"id","Ljahspotify/media/Link;",albumJLink); setObjectStringField(env,albumInstance,"name",sp_album_name(album)); setObjectIntField(env,albumInstance,"year",sp_album_year(album)); sp_albumtype albumType = sp_album_type(album); jclass albumTypeJClass = (*env)->FindClass(env, "jahspotify/media/AlbumType"); jmethodID jMethod = (*env)->GetStaticMethodID(env,albumTypeJClass,"fromOrdinal","(I)Ljahspotify/media/AlbumType;"); jobject albumTypeEnum = (jobjectArray)(*env)->CallStaticObjectMethod(env, albumTypeJClass, jMethod,(int)albumType); setObjectObjectField(env,albumInstance,"type","Ljahspotify/media/AlbumType;",albumTypeEnum); sp_link *albumCoverLink = sp_link_create_from_album_cover(album); if (albumCoverLink) { sp_link_add_ref(albumCoverLink); jobject albumCoverJLink = createJLinkInstance(env, albumCoverLink); setObjectObjectField(env,albumInstance,"cover","Ljahspotify/media/Link;",albumCoverJLink); sp_image *albumCoverImage = sp_image_create_from_link(g_sess,albumCoverLink); if (albumCoverImage) { sp_image_add_ref(albumCoverImage); sp_image_add_load_callback(albumCoverImage,imageLoadedCallback,NULL); } sp_link_release(albumCoverLink); } sp_artist *artist = sp_album_artist(album); if (artist) { sp_artist_add_ref(artist); sp_link *artistLink = sp_link_create_from_artist(artist); if (artistLink) { sp_link_add_ref(artistLink); jobject artistJLink = createJLinkInstance(env,artistLink); setObjectObjectField(env,albumInstance,"artist","Ljahspotify/media/Link;",artistJLink); sp_link_release(artistLink); } sp_artist_release(artist); } sp_link_release(albumLink); } int numTracks = sp_albumbrowse_num_tracks(albumBrowse); if (numTracks > 0) { // Add each track to the album - also pass in the disk as need be jmethodID addTrackJMethodID = (*env)->GetMethodID(env,albumJClass,"addTrack","(ILjahspotify/media/Link;)V"); int i = 0; for (i = 0; i < numTracks; i++) { sp_track *track = sp_albumbrowse_track(albumBrowse,i); if (track) { sp_track_add_ref(track); sp_link *trackLink = sp_link_create_from_track(track,0); if (trackLink) { sp_link_add_ref(trackLink); jobject trackJLink = createJLinkInstance(env,trackLink); (*env)->CallVoidMethod(env, albumInstance, addTrackJMethodID,sp_track_disc(track),trackJLink); sp_link_release(trackLink); } } } } int numCopyrights = sp_albumbrowse_num_copyrights(albumBrowse); if (numCopyrights > 0) { // Add copyrights to album jmethodID addCopyrightMethodID = (*env)->GetMethodID(env,albumJClass,"addCopyright","(Ljava/lang/String;)V"); int i = 0; for (i = 0; i < numCopyrights; i++) { const char *copyright = sp_albumbrowse_copyright(albumBrowse,i); if (copyright) { jstring str = (*env)->NewStringUTF(env, copyright); (*env)->CallVoidMethod(env, albumInstance, addCopyrightMethodID,str); } } } const char *review = sp_albumbrowse_review(albumBrowse); if (review) { setObjectStringField(env,albumInstance,"review",review); } sp_albumbrowse_release(albumBrowse); } return albumInstance; }
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; }
jobject createJPlaylist(JNIEnv *env, sp_playlist *playlist) { jclass jClass; jobject playlistInstance; jmethodID jMethod; jClass = (*env)->FindClass(env, "jahspotify/media/Playlist"); if (jClass == NULL) { fprintf(stderr,"jahspotify::createJPlaylist: could not load jahnotify.media.Playlist\n"); return NULL; } playlistInstance = (*env)->AllocObject(env,jClass); if (!playlistInstance) { fprintf(stderr,"jahspotify::createJPlaylist: could not create instance of jahspotify.media.Playlistt\n"); return NULL; } sp_link *playlistLink = sp_link_create_from_playlist(playlist); if (playlistLink) { jobject playlistJLink = createJLinkInstance(env,playlistLink); setObjectObjectField(env,playlistInstance,"id","Ljahspotify/media/Link;",playlistJLink); sp_link_release(playlistLink); } setObjectStringField(env,playlistInstance,"name",sp_playlist_name(playlist)); sp_user *owner = sp_playlist_owner(playlist); if (owner) { setObjectStringField(env,playlistInstance,"author",sp_user_display_name(owner)); sp_user_release(owner); } // Lookup the method now - saves us looking it up for each iteration of the loop jMethod = (*env)->GetMethodID(env,jClass,"addTrack","(Ljahspotify/media/Link;)V"); if (jMethod == NULL) { fprintf(stderr,"jahspotify::createJPlaylist: could not load method addTrack(track) on class Playlist\n"); return NULL; } int numTracks = sp_playlist_num_tracks(playlist); int trackCounter = 0; for (trackCounter = 0 ; trackCounter < numTracks; trackCounter++) { sp_track *track = sp_playlist_track(playlist,trackCounter); if (track) { sp_track_add_ref(track); sp_link *trackLink = sp_link_create_from_track(track, 0); if (trackLink) { sp_link_add_ref(trackLink); jobject trackJLink = createJLinkInstance(env,trackLink); // Add it to the playlist (*env)->CallVoidMethod(env,playlistInstance,jMethod,trackJLink); sp_link_release(trackLink); } sp_track_release(track); } } return playlistInstance; }
static int osfy_artistbrowse_load_from_xml(sp_session *session, sp_artistbrowse *arb, ezxml_t root) { unsigned char id[20]; int disc_number, i; sp_track *track; sp_album *album; ezxml_t node, album_node, loop_node, track_node; /* Load artist from XML if not yet loaded */ if(sp_artist_is_loaded(arb->artist) == 0) osfy_artist_load_artist_from_xml(session, arb->artist, root); assert(sp_artist_is_loaded(arb->artist)); /* Load portraits */ for(loop_node = ezxml_get(root, "bios", 0, "bio", 0, "portraits", 0, "portrait", -1); loop_node; loop_node = loop_node->next) { if((node = ezxml_get(loop_node, "id", -1)) == NULL) continue; arb->portraits = realloc(arb->portraits, sizeof(unsigned char *) * (1 + arb->num_portraits)); arb->portraits[arb->num_portraits] = malloc(20); hex_ascii_to_bytes(node->txt, arb->portraits[arb->num_portraits], 20); arb->num_portraits++; } /* Load biography */ if((node = ezxml_get(root, "bios", 0, "bio", 0, "text", -1)) != NULL) arb->biography = strdup(node->txt); else arb->biography = strdup(""); /* Load similar artists */ for(loop_node = ezxml_get(root, "similar-artists", 0, "artist", -1); loop_node; loop_node = loop_node->next) { if((node = ezxml_get(loop_node, "id", -1)) == NULL) continue; arb->similar_artists = realloc(arb->similar_artists, sizeof(sp_artist *) * (1 + arb->num_similar_artists)); hex_ascii_to_bytes(node->txt, id, 16); arb->similar_artists[arb->num_similar_artists] = osfy_artist_add(session, id); sp_artist_add_ref(arb->similar_artists[arb->num_similar_artists]); if(sp_artist_is_loaded(arb->similar_artists[arb->num_similar_artists]) == 0) { DSFYDEBUG("Loading similar artist from artistbrowse XML\n"); osfy_artist_load_artist_from_xml(session, arb->similar_artists[arb->num_similar_artists], loop_node); } assert(sp_artist_is_loaded(arb->similar_artists[arb->num_similar_artists])); arb->num_similar_artists++; } /* Loop over each album listed */ for(album_node = ezxml_get(root, "albums", 0, "album", -1); album_node; album_node = album_node->next) { /* Extract album ID and add it */ if((node = ezxml_get(album_node, "id", -1)) == NULL) continue; hex_ascii_to_bytes(node->txt, id, 16); album = sp_album_add(session, id); /* Load album if necessary */ if(sp_album_is_loaded(album) == 0) osfy_album_load_from_album_xml(session, album, album_node); assert(sp_album_is_loaded(album)); /* Add album to artistbrowse's list of albums */ arb->albums = realloc(arb->albums, sizeof(sp_album *) * (1 + arb->num_albums)); arb->albums[arb->num_albums] = album; sp_album_add_ref(arb->albums[arb->num_albums]); arb->num_albums++; /* Loop over each disc in the album and add tracks */ for(loop_node = ezxml_get(album_node, "discs", 0, "disc", -1); loop_node; loop_node = loop_node->next) { /* Cache disc number */ if((node = ezxml_get(loop_node, "disc-number", -1)) == NULL) { DSFYDEBUG("BUG: Found no 'disc-numner' under discs -> disc\n"); continue; } disc_number = atoi(node->txt); /* Loop over each track and add it to the artistbrowse tracks list */ for(track_node = ezxml_get(loop_node, "track", -1), i = 1; track_node; track_node = track_node->next, i++) { /* Extract track ID and add it */ if((node = ezxml_get(track_node, "id", -1)) == NULL) continue; hex_ascii_to_bytes(node->txt, id, 16); track = osfy_track_add(session, id); /* Add album to track */ if(track->album) sp_album_release(track->album); track->album = album; sp_album_add_ref(track->album); /* Set disc number */ track->disc = disc_number; /* Set track index on disc */ if(track->index == 0) track->index = i; /* Load track details from XML if not already loaded */ if(sp_track_is_loaded(track) == 0) osfy_track_load_from_xml(session, track, track_node); assert(sp_track_is_loaded(track)); /* Mark track as available if the album is available and the album has a non-zero duration (i.e, associated files) */ if(!track->is_available && track->duration) { DSFYDEBUG("Track '%s' marked as not available but has files, force-marking track as %savailable\n", node->txt, !album->is_available? "not ": ""); track->is_available = album->is_available; } /* Add track to artistbrowse and increase the track's ref count */ arb->tracks = realloc(arb->tracks, sizeof(sp_track *) * (1 + arb->num_tracks)); arb->tracks[arb->num_tracks] = track; sp_track_add_ref(arb->tracks[arb->num_tracks]); arb->num_tracks++; } } /* for each disc in album */ } /* for each album */ return 0; }
static void restore_state(session_callback_type type, gpointer data, gpointer user_data) { JsonParser* jp = NULL; JsonReader* jr = NULL; const gchar* sqs; saved_state* s = NULL; GError* err = NULL; /* Is it the callback we're interested in? */ if (type != SPOP_SESSION_LOGGED_IN) return; /* First disable the callback so it's not called again */ session_remove_callback(restore_state, NULL); g_debug("savestate: reading saved state..."); s = g_new0(saved_state, 1); /* Read and parse state file */ jp = json_parser_new(); if (!json_parser_load_from_file(jp, g_state_file_path, &err)) { g_warning("savestate: error while reading state file: %s", err->message); goto restorestate_error; } jr = json_reader_new(json_parser_get_root(jp)); /* Read basic state */ if (!json_reader_read_member(jr, "status")) goto restorestate_jr_error; sqs = json_reader_get_string_value(jr); json_reader_end_member(jr); if (strcmp(sqs, "stopped")) s->qs = STOPPED; else if (strcmp(sqs, "playing")) s->qs = PLAYING; else if (strcmp(sqs, "paused")) s->qs = PAUSED; else { g_warning("savestate: bad value for queue status: %s", sqs); goto restorestate_error; } if (!json_reader_read_member(jr, "repeat")) goto restorestate_jr_error; s->repeat = json_reader_get_boolean_value(jr); json_reader_end_member(jr); if (!json_reader_read_member(jr, "shuffle")) goto restorestate_jr_error; s->shuffle = json_reader_get_boolean_value(jr); json_reader_end_member(jr); if (!json_reader_read_member(jr, "current_track")) goto restorestate_jr_error; s->cur_track = json_reader_get_int_value(jr); json_reader_end_member(jr); /* Now read tracks URIs */ if (!json_reader_read_member(jr, "tracks")) goto restorestate_jr_error; if (!json_reader_is_array(jr)) { g_warning("savestate: error while parsing JSON: tracks is not an array"); goto restorestate_error; } gint tracks = json_reader_count_elements(jr); if (s->cur_track >= tracks) { g_warning("savestate: incoherent state file: cur_track >= tracks"); goto restorestate_error; } s->tracks = g_array_sized_new(FALSE, FALSE, sizeof(sp_track*), tracks); if (!s->tracks) g_error("Can't allocate array of %d tracks.", tracks); size_t i; gboolean can_restore_now = TRUE; for (i=0; i < tracks; i++) { json_reader_read_element(jr, i); const gchar* uri = json_reader_get_string_value(jr); json_reader_end_element(jr); sp_link* lnk = sp_link_create_from_string(uri); sp_linktype lt = sp_link_type(lnk); if (lt != SP_LINKTYPE_TRACK) { g_warning("savestate: invalid link type for track %zu: %d", i, lt); sp_link_release(lnk); goto restorestate_error; } sp_track* tr = sp_link_as_track(lnk); sp_track_add_ref(tr); sp_link_release(lnk); g_array_append_val(s->tracks, tr); if (!sp_track_is_loaded(tr)) can_restore_now = FALSE; } /* If possible, restore now, else wait for all tracks to be loaded */ if (can_restore_now) really_restore_state(s); else { g_timeout_add(100, (GSourceFunc) really_restore_state, s); g_debug("savestate: waiting for all tracks to be loaded before restoring saved state..."); } /* Add a notification callback */ if (!interface_notify_add_callback(savestate_notification_callback, NULL)) g_error("Could not add savestate callback."); goto restorestate_clean; restorestate_jr_error: err = (GError*) json_reader_get_error(jr); g_warning("savestate: error while parsing JSON: %s", err->message); restorestate_error: if (s) { if (s->tracks) g_array_free(s->tracks, TRUE); g_free(s); } restorestate_clean: if (jp) g_object_unref(jp); if (jr) g_object_unref(jr); }
/* 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; }