static struct input_stream * input_despotify_open(const char *url, G_GNUC_UNUSED GError **error_r) { struct input_despotify *ctx; struct despotify_session *session; struct ds_link *ds_link; struct ds_track *track; if (!g_str_has_prefix(url, "spt://")) return NULL; session = mpd_despotify_get_session(); if (!session) return NULL; ds_link = despotify_link_from_uri(url + 6); if (!ds_link) { g_debug("Can't find %s\n", url); return NULL; } if (ds_link->type != LINK_TYPE_TRACK) { despotify_free_link(ds_link); return NULL; } ctx = g_new(struct input_despotify, 1); memset(ctx, 0, sizeof(*ctx)); track = despotify_link_get_track(session, ds_link); despotify_free_link(ds_link); if (!track) { g_free(ctx); return NULL; } input_stream_init(&ctx->base, &input_plugin_despotify, url); ctx->session = session; ctx->track = track; ctx->tag = mpd_despotify_tag_from_track(track); ctx->eof = false; /* Despotify outputs pcm data */ ctx->base.mime = g_strdup("audio/x-mpd-cdda-pcm"); ctx->base.ready = true; if (!mpd_despotify_register_callback(callback, ctx)) { despotify_free_link(ds_link); return NULL; } if (despotify_play(ctx->session, ctx->track, false) == false) { despotify_free_track(ctx->track); g_free(ctx); return NULL; } return &ctx->base; }
static VALUE rb_ds_session_play_playlist (VALUE self, VALUE playlist) { SESSION_METHOD_HEADER rb_ds_playlist *pl; VALUE2PLAYLIST(playlist, pl); return BOOL2VALUE(despotify_play(session->real, pl->real->tracks, true)); }
static VALUE rb_ds_session_play (VALUE self, VALUE track) { SESSION_METHOD_HEADER rb_ds_track *t; VALUE2TRACK(track, t); return BOOL2VALUE(despotify_play(session->real, t->real, false)); }
// Start playback. void sess_play(struct ds_track *t) { if (g_session.state != SESS_ONLINE) { log_append("Not connected"); return; } if (despotify_play(g_session.dsfy, t, true)) { g_session.playing = true; g_session.paused = false; log_append("Playing %s", t->title); thread_play(); } else log_append("Playback failed"); }
/* * Handle list item clicking * At the moment the clicked line is just played back. */ void on_changed(GtkWidget *widget, AppData * appdata) { GtkTreeIter iter; GtkTreeModel *model; char *artist; char *title; struct track *track; if (gtk_tree_selection_get_selected( GTK_TREE_SELECTION(widget), &model, &iter)) { gtk_tree_model_get(model, &iter, LIST_ARTIST, &artist, LIST_TITLE, &title, LIST_TRACK_POINTER, &track, -1); gtk_label_set_text(GTK_LABEL(appdata->label), artist); /* play this item. The list it belongs to will be the playlist */ despotify_play(appdata->ds, track, true); g_free(artist); g_free(title); } }
void command_loop(struct despotify_session* ds) { bool loop = true; char buf[80]; struct playlist* rootlist = NULL; struct playlist* searchlist = NULL; struct search_result *search = NULL; struct album_browse* playalbum = NULL; print_help(); do { wprintf(L"\n> "); fflush(stdout); bzero(buf, sizeof buf); fgets(buf, sizeof buf -1, stdin); buf[strlen(buf) - 1] = 0; /* remove newline */ /* list */ if (!strncmp(buf, "list", 4)) { int num = atoi(buf + 5); if (num) { struct playlist* p = get_playlist(rootlist, num); if (p) { print_tracks(p->tracks); lastlist = p; } } else { if (!rootlist) rootlist = despotify_get_stored_playlists(ds); print_list_of_lists(rootlist); } } /* rename */ else if (!strncmp(buf, "rename", 6)) { int num = 0; char *name = 0; if (strlen(buf) > 9) { num = atoi(buf + 7); name = strchr(buf + 7, ' ') + 1; } if (num && name && name[0]) { struct playlist* p = get_playlist(rootlist, num); if (p) { if (despotify_rename_playlist(ds, p, name)) wprintf(L"Renamed playlist %d to \"%s\".\n", num, name); else wprintf(L"Rename failed: %s\n", despotify_get_error(ds)); } } else wprintf(L"Usage: rename [num] [string]\n"); } /* collab */ else if (!strncmp(buf, "collab", 6)) { int num = 0; if (strlen(buf) > 7) num = atoi(buf + 7); if (num) { struct playlist* p = get_playlist(rootlist, num); if (p) { if (despotify_set_playlist_collaboration(ds, p, !p->is_collaborative)) wprintf(L"Changed playlist %d collaboration to %s.\n", num, p->is_collaborative ? "ON" : "OFF"); else wprintf(L"Setting playlist collaboration state failed: %s\n", despotify_get_error(ds)); } } else wprintf(L"Usage: collab [num]\n"); } /* search */ else if (!strncmp(buf, "search", 6)) { if (buf[7]) { if (search) despotify_free_search(search); despotify_stop(ds); /* since we replace the list */ search = despotify_search(ds, buf + 7, MAX_SEARCH_RESULTS); if (!search) { wprintf(L"Search failed: %s\n", despotify_get_error(ds)); continue; } searchlist = search->playlist; } else if (searchlist && (searchlist->num_tracks < search->total_tracks)) if (!despotify_search_more(ds, search, searchlist->num_tracks, MAX_SEARCH_RESULTS)) { wprintf(L"Search failed: %s\n", despotify_get_error(ds)); continue; } if (searchlist) { print_search(search); lastlist = searchlist; } else wprintf(L"No previous search\n"); } /* artist */ else if (!strncmp(buf, "artist", 6)) { int num = atoi(buf + 7); if (!num) { wprintf(L"usage: artist [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; for (struct artist* aptr = t->artist; aptr; aptr = aptr->next) { struct artist_browse* a = despotify_get_artist(ds, aptr->id); print_artist(a); despotify_free_artist_browse(a); } } /* album */ else if (!strncmp(buf, "album", 5)) { int num = atoi(buf + 6); if (!num) { wprintf(L"usage: album [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; if (t) { struct album_browse* a = despotify_get_album(ds, t->album_id); if (a) { print_album(a); despotify_free_album_browse(a); } else wprintf(L"Got no album for id %s\n", t->album_id); } } /* playalbum */ else if (!strncmp(buf, "playalbum", 9)) { int num = atoi(buf + 10); if (!num) { wprintf(L"usage: playalbum [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested track */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; if (t) { if (playalbum) despotify_free_album_browse(playalbum); despotify_stop(ds); playalbum = despotify_get_album(ds, t->album_id); if (playalbum) despotify_play(ds, playalbum->tracks, true); else wprintf(L"Got no album for id %s\n", t->album_id); } } /* uri */ else if (!strncmp(buf, "uri", 3)) { char *uri = buf + 4; if(strlen(uri) == 0) { wprintf(L"usage: info <uri>\n"); continue; } struct link* link = despotify_link_from_uri(uri); struct album_browse* al; struct artist_browse* ar; struct playlist* pls; struct search_result* s; struct track* t; switch(link->type) { case LINK_TYPE_ALBUM: al = despotify_link_get_album(ds, link); if(al) { print_album(al); despotify_free_album_browse(al); } break; case LINK_TYPE_ARTIST: ar = despotify_link_get_artist(ds, link); if(ar) { print_artist(ar); despotify_free_artist_browse(ar); } break; case LINK_TYPE_PLAYLIST: pls = despotify_link_get_playlist(ds, link); if(pls) { print_playlist(pls); despotify_free_playlist(pls); } break; case LINK_TYPE_SEARCH: s = despotify_link_get_search(ds, link); if(s) { print_search(s); despotify_free_search(s); } break; case LINK_TYPE_TRACK: t = despotify_link_get_track(ds, link); if(t) { print_track_full(t); despotify_free_track(t); } break; default: wprintf(L"%s is a invalid Spotify URI\n", uri); } despotify_free_link(link); } /* portrait */ else if (!strncmp(buf, "portrait", 8)) { int num = atoi(buf + 9); if (!num) { wprintf(L"usage: portrait [num]\n"); continue; } if (!lastlist) { wprintf(L"No playlist\n"); continue; } /* find the requested artist */ struct track* t = lastlist->tracks; for (int i=1; i<num; i++) t = t->next; struct artist_browse* a = despotify_get_artist(ds, t->artist->id); if (a && a->portrait_id[0]) { int len; void* portrait = despotify_get_image(ds, a->portrait_id, &len); if (portrait && len) { wprintf(L"Writing %d bytes into portrait.jpg\n", len); FILE* f = fopen("portrait.jpg", "w"); if (f) { fwrite(portrait, len, 1, f); fclose(f); } free(portrait); } } else wprintf(L"Artist %s has no portrait.\n", a->name); despotify_free_artist_browse(a); } /* play */ else if (!strncmp(buf, "play", 4)) { if (!lastlist) { wprintf(L"No list to play from. Use 'list' or 'search' to select a list.\n"); continue; } /* skip to track <num> */ listoffset = atoi(buf + 5); struct track* t = lastlist->tracks; for (int i=1; i<listoffset && t; i++) t = t->next; if (t) despotify_play(ds, t, true); else wprintf(L"Invalid track number %d\n", listoffset); } /* stop */ else if (!strncmp(buf, "stop", 4)) { despotify_stop(ds); } /* pause */ else if (!strncmp(buf, "pause", 5)) { despotify_pause(ds); } /* resume */ else if (!strncmp(buf, "resume", 5)) { despotify_resume(ds); } /* info */ else if (!strncmp(buf, "info", 4)) { print_info(ds); } /* help */ else if (!strncmp(buf, "help", 4)) { print_help(); } /* quit */ else if (!strncmp(buf, "quit", 4)) { loop = false; } } while(loop); if (rootlist) despotify_free_playlist(rootlist); if (search) despotify_free_search(search); if (playalbum) despotify_free_album_browse(playalbum); }
int main(int argc, char** argv) { setlocale(LC_ALL, ""); if (argc < 3) { wrapper_wprintf(L"Usage: %s <username> <password> [remote control port]\n", argv[0]); return 1; } DSFYDEBUG("$Id$\n"); if (!despotify_init()) { wrapper_wprintf(L"despotify_init() failed\n"); return 1; } struct despotify_session* ds = despotify_init_client(callback, NULL, true, true); if (!ds) { wrapper_wprintf(L"despotify_init_client() failed\n"); return 1; } pthread_create(&thread, NULL, &thread_loop, ds); if(argc == 4 && wrapper_listen(atoi(argv[3]))) { wrapper_wprintf(L"wrapper_listen() failed to listen on local port %s\n", argv[3]); return 1; } if (!despotify_authenticate(ds, argv[1], argv[2])) { printf( "Authentication failed: %s\n", despotify_get_error(ds)); despotify_exit(ds); return 1; } audio_device = audio_init(); #if 0 { struct ds_track* t = despotify_get_track(ds, "d1b264bb6bcd46be852ceba8ac5e6582"); despotify_play(ds, t, false); thread_play(); while(1) { sleep(1); } } #else print_info(ds); command_loop(ds); #endif thread_exit(); audio_exit(audio_device); despotify_exit(ds); if (!despotify_cleanup()) { wrapper_wprintf(L"despotify_cleanup() failed\n"); return 1; } return 0; }