browse.c

The browse.c example shows how you can use the album, artist, and browse functions. The example also include some rudimentary playlist browsing. It is part of the spshell program

#include "spshell.h"
#include "cmd.h"

static sp_track *track_browse;
static sp_playlist *playlist_browse;
static sp_playlist_callbacks pl_callbacks;

void print_track(sp_track *track)
{
    int duration = sp_track_duration(track);
    char url[256];
    sp_link *l;
    int i;

#if WIN32
    printf(" %s ", sp_track_is_starred(g_session,track) ? "*" : " ");
#else
    printf(" %s ", sp_track_is_starred(g_session,track) ? "★" : "☆");
#endif
    printf("Track %s [%d:%02d] has %d artist(s), %d%% popularity",
           sp_track_name(track),
           duration / 60000,
           (duration / 1000) % 60,
           sp_track_num_artists(track),
           sp_track_popularity(track));
    
    if(sp_track_disc(track)) 
        printf(", %d on disc %d",
               sp_track_index(track),
               sp_track_disc(track));
    printf("\n");

    for (i = 0; i < sp_track_num_artists(track); i++) {
        sp_artist *art = sp_track_artist(track, i);
        printf("\tArtist %d: %s\n", i + 1, sp_artist_name(art));
    }
    l = sp_link_create_from_track(track, 0);
    sp_link_as_string(l, url, sizeof(url));
    printf("\t\t%s\n", url);
    sp_link_release(l);
}

static void print_albumbrowse(sp_albumbrowse *browse)
{
    int i;

    printf("Album browse of \"%s\" (%d)\n", 
           sp_album_name(sp_albumbrowse_album(browse)), 
           sp_album_year(sp_albumbrowse_album(browse)));

    for (i = 0; i < sp_albumbrowse_num_copyrights(browse); ++i)
        printf("  Copyright: %s\n", sp_albumbrowse_copyright(browse, i));

    printf("  Tracks: %d\n", sp_albumbrowse_num_tracks(browse));
    printf("  Review: %.60s...\n", sp_albumbrowse_review(browse));
    puts("");

    for (i = 0; i < sp_albumbrowse_num_tracks(browse); ++i)
        print_track(sp_albumbrowse_track(browse, i));

    puts("");
}

static void print_artistbrowse(sp_artistbrowse *browse)
{
    int i;

    printf("Artist browse of \"%s\"\n", sp_artist_name(sp_artistbrowse_artist(browse)));

    for (i = 0; i < sp_artistbrowse_num_similar_artists(browse); ++i)
        printf("  Similar artist: %s\n", sp_artist_name(sp_artistbrowse_similar_artist(browse, i)));

    printf("  Portraits: %d\n", sp_artistbrowse_num_portraits(browse));
    printf("  Tracks   : %d\n", sp_artistbrowse_num_tracks(browse));
    printf("  Biography: %.60s...\n", sp_artistbrowse_biography(browse));
    puts("");

    for (i = 0; i < sp_artistbrowse_num_tracks(browse); ++i)
        print_track(sp_artistbrowse_track(browse, i));

    puts("");
}



static void SP_CALLCONV browse_album_callback(sp_albumbrowse *browse, void *userdata)
{
    if (sp_albumbrowse_error(browse) == SP_ERROR_OK)
        print_albumbrowse(browse);
    else
        fprintf(stderr, "Failed to browse album: %s\n",
                sp_error_message(sp_albumbrowse_error(browse)));

    sp_albumbrowse_release(browse);
    cmd_done();
}


static void SP_CALLCONV browse_artist_callback(sp_artistbrowse *browse, void *userdata)
{
    if (sp_artistbrowse_error(browse) == SP_ERROR_OK)
        print_artistbrowse(browse);
    else
        fprintf(stderr, "Failed to browse artist: %s\n",
                sp_error_message(sp_artistbrowse_error(browse)));

    sp_artistbrowse_release(browse);
    cmd_done();
}



static void track_browse_try(void)
{
    switch (sp_track_error(track_browse)) {
    case SP_ERROR_OK:
        print_track(track_browse);
        break;

    case SP_ERROR_IS_LOADING:
        return; // Still pending

    default:
        fprintf(stderr, "Unable to resolve track: %s\n", sp_error_message(sp_track_error(track_browse)));
        break;
    }
    
    metadata_updated_fn = NULL;
    cmd_done();
    sp_track_release(track_browse);
}



static void playlist_browse_try(void)
{
    int i, tracks;

    metadata_updated_fn = playlist_browse_try;
    if(!sp_playlist_is_loaded(playlist_browse)) {
        printf("\tPlaylist not loaded\n");
        return;
    }

    tracks = sp_playlist_num_tracks(playlist_browse);
    for(i = 0; i < tracks; i++) {
        sp_track *t = sp_playlist_track(playlist_browse, i);
        if (!sp_track_is_loaded(t))
            return;
    }

    printf("\tPlaylist and metadata loaded\n");

    for(i = 0; i < tracks; i++) {
        sp_track *t = sp_playlist_track(playlist_browse, i);
        
        printf(" %5d: ", i + 1);
        print_track(t);
    }
    sp_playlist_remove_callbacks(playlist_browse, &pl_callbacks, NULL);

    sp_playlist_release(playlist_browse);
    playlist_browse = NULL;
    metadata_updated_fn = NULL;
    cmd_done();
}

static void SP_CALLCONV pl_tracks_added(sp_playlist *pl, sp_track * const * tracks,
                int num_tracks, int position, void *userdata)
{
    printf("\t%d tracks added\n", num_tracks);
}

static void SP_CALLCONV pl_tracks_removed(sp_playlist *pl, const int *tracks,
                  int num_tracks, void *userdata)
{
    printf("\t%d tracks removed\n", num_tracks);
}

static void SP_CALLCONV pl_tracks_moved(sp_playlist *pl, const int *tracks,
                int num_tracks, int new_position, void *userdata)
{
    printf("\t%d tracks moved\n", num_tracks);
}

static void SP_CALLCONV pl_renamed(sp_playlist *pl, void *userdata)
{
    printf("\tList name: %s\n",  sp_playlist_name(pl));
}

static void SP_CALLCONV pl_state_change(sp_playlist *pl, void *userdata)
{
    playlist_browse_try();
}

static sp_playlist_callbacks pl_callbacks = {
    pl_tracks_added,
    pl_tracks_removed,
    pl_tracks_moved,
    pl_renamed,
    pl_state_change,
};


void browse_playlist(sp_playlist *pl)
{
    playlist_browse = pl;
    sp_playlist_add_callbacks(playlist_browse, &pl_callbacks, NULL);
    playlist_browse_try();
}

static void browse_usage(void)
{
    fprintf(stderr, "Usage: browse <spotify-uri>\n");
}


int cmd_browse(int argc, char **argv)
{
    sp_link *link;

    if (argc != 2) {
        browse_usage();
        return -1;
    }

    
    link = sp_link_create_from_string(argv[1]);
    
    if (!link) {
        fprintf(stderr, "Not a spotify link\n");
        return -1;
    }

    switch(sp_link_type(link)) {
    default:
        fprintf(stderr, "Can not handle link");
        sp_link_release(link);
        return -1;

    case SP_LINKTYPE_ALBUM:
        sp_albumbrowse_create(g_session, sp_link_as_album(link), browse_album_callback, NULL);
        break;

    case SP_LINKTYPE_ARTIST:
        sp_artistbrowse_create(g_session, sp_link_as_artist(link), SP_ARTISTBROWSE_FULL, browse_artist_callback, NULL);
        break;

    case SP_LINKTYPE_LOCALTRACK:
    case SP_LINKTYPE_TRACK:
        track_browse = sp_link_as_track(link);
        metadata_updated_fn = track_browse_try;
        sp_track_add_ref(track_browse);
        track_browse_try();
        break;

    case SP_LINKTYPE_PLAYLIST:
        browse_playlist(sp_playlist_create(g_session, link));
        break;
    }

    sp_link_release(link);
    return 0;
}

Generated on Wed Jun 13 2012 14:22:40.
Copyright © 2006–2012 Spotify Ltd