static int event_player(G_GNUC_UNUSED const struct mpd_connection *conn, const struct mpd_song *song, const struct mpd_status *status) { enum mpd_state state; g_assert(status != NULL); state = mpd_status_get_state(status); if (state == MPD_STATE_PAUSE) { song_paused(); return MPDCRON_EVENT_SUCCESS; } else if (state != MPD_STATE_PLAY) song_stopped(); if (was_paused) { if (song != NULL && mpd_song_get_id(song) == last_id) song_continued(); was_paused = false; } /* Submit the previous song */ if (prev != NULL && (song == NULL || mpd_song_get_id(prev) != mpd_song_get_id(song))) song_ended(prev); if (song != NULL) { if (mpd_song_get_id(song) != last_id) { /* New song. */ song_started(song); last_id = mpd_song_get_id(song); } else { /* still playing the previous song */ song_playing(song, mpd_status_get_elapsed_time(status)); } } if (prev != NULL) { mpd_song_free(prev); prev = NULL; } if (song != NULL) { if ((prev = mpd_song_dup(song)) == NULL) { g_critical("mpd_song_dup failed: out of memory"); return MPDCRON_EVENT_UNLOAD; } } return MPDCRON_EVENT_SUCCESS; }
static void song_changed(const struct mpd_song *song) { g_assert(song != NULL); if (mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) == NULL || mpd_song_get_tag(song, MPD_TAG_TITLE, 0) == NULL) { g_message("New song detected with tags missing (%s)", mpd_song_get_uri(song)); g_timer_start(timer); return; } g_timer_start(timer); g_debug("New song detected (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); as_now_playing(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song)); }
static void song_ended(const struct mpd_song *song) { bool long_enough; int elapsed, song_duration, percent_played; GError *error; g_assert(song != NULL); elapsed = g_timer_elapsed(timer, NULL); song_duration = mpd_song_get_duration(song); long_enough = played_long_enough(elapsed, song_duration); percent_played = elapsed * 100 / song_duration; g_debug("Saving old song (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); error = NULL; if (!db_process(song, long_enough, percent_played, &error)) { g_warning("Saving old song failed: %s", error->message); g_error_free(error); } else if (error != NULL) { g_warning("Skipped saving old song: %s", error->message); g_error_free(error); } }
static void song_changed(const struct mpd_song *song) { g_assert(song != NULL); g_timer_start(timer); g_debug("New song detected (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); }
static void song_ended(const struct mpd_song *song) { int elapsed; g_assert(song != NULL); elapsed = g_timer_elapsed(timer, NULL); if (mpd_song_get_tag(song, MPD_TAG_ARTIST, 0) == NULL || mpd_song_get_tag(song, MPD_TAG_TITLE, 0) == NULL) { g_message("Song (%s) has missing tags, skipping", mpd_song_get_uri(song)); return; } else if (!played_long_enough(elapsed, mpd_song_get_duration(song))) { g_message("Song (%s - %s), id: %u, pos: %u not played long enough, skipping", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); return; } g_debug("Submitting old song (%s - %s), id: %u, pos: %u", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); /* FIXME: libmpdclient doesn't have any way to fetch the musicbrainz id. */ as_songchange(mpd_song_get_uri(song), mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song) > 0 ? mpd_song_get_duration(song) : g_timer_elapsed(timer, NULL), NULL); }
static int fetch_items(MENU_SEARCH *menu,char *str,CLIENT_OBJECT *cli,DB_OBJECT *db) { if (!(str && strlen(str))) return 1; /* send query */ if (!mpd_search_db_songs(cli->conn,false)) clear_or_exit_on_error(cli->conn); if (!mpd_search_add_tag_constraint(cli->conn,MPD_OPERATOR_DEFAULT,MPD_TAG_TITLE,str)) clear_or_exit_on_error(cli->conn); if (!mpd_search_commit(cli->conn)) clear_or_exit_on_error(cli->conn); /* process response */ int block = 1024; menu->items = (MENU_SEARCH_ITEM*)calloc(block,sizeof(MENU_SEARCH_ITEM)); struct mpd_song *song; int i = 0; while ((song = mpd_recv_song(cli->conn))) { /* realloc if memory not enough */ if (i >= block) { block *= 2; menu->items = (MENU_SEARCH_ITEM*)realloc(menu->items,block*sizeof(MENU_SEARCH_ITEM)); } unsigned id = mpd_song_get_id(song); const char *uri = mpd_song_get_uri(song); const char *title = mpd_song_get_tag(song,MPD_TAG_TITLE,0); menu->items[i].id = id; menu->items[i].title = (char *)malloc((strlen(title)+1)*sizeof(char)); strcpy(menu->items[i].title,title); menu->items[i++].node = get_node_by_uri(db,uri); mpd_song_free(song); } if (mpd_connection_get_error(cli->conn) == MPD_ERROR_SUCCESS) mpd_response_finish(cli->conn); else clear_or_exit_on_error(cli->conn); menu->num = i; return 0; }
static void song_changed(const struct mpd_song *song) { g_message("new song detected (%s - %s), id: %u, pos: %u\n", mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_id(song), mpd_song_get_pos(song)); g_timer_start(timer); as_now_playing(mpd_song_get_tag(song, MPD_TAG_ARTIST, 0), mpd_song_get_tag(song, MPD_TAG_TITLE, 0), mpd_song_get_tag(song, MPD_TAG_ALBUM, 0), mpd_song_get_tag(song, MPD_TAG_TRACK, 0), mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0), mpd_song_get_duration(song)); }
static void commit_seek(struct mpdclient *c) { struct mpd_connection *connection; if (seek_id < 0) return; connection = mpdclient_get_connection(c); if (connection == NULL) { seek_id = -1; return; } if (c->song != NULL && (unsigned)seek_id == mpd_song_get_id(c->song)) if (!mpd_run_seek_id(connection, seek_id, seek_target_time)) mpdclient_handle_error(c); seek_id = -1; }
int mpd_put_queue(char *buffer, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; if (!mpd_send_list_queue_range_meta(mpd.conn, offset, offset+MAX_ELEMENTS_PER_PAGE)) RETURN_ERROR_AND_RECOVER("mpd_send_list_queue_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"queue\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG) { song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"id\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_id(song)); cur += json_emit_raw_str(cur, end - cur, ",\"pos\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_pos(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"artist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_artist(song)); cur += json_emit_raw_str(cur, end - cur, ",\"album\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_album(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); } mpd_entity_free(entity); } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
static int find_songname_id(struct mpd_connection *conn, const char *s) { int res = -1; mpd_search_queue_songs(conn, false); const char *pattern = s; //charset_to_utf8(s); mpd_search_add_any_tag_constraint(conn, MPD_OPERATOR_DEFAULT, pattern); mpd_search_commit(conn); struct mpd_song *song = mpd_recv_song(conn); if (song != NULL) { res = mpd_song_get_id(song); mpd_song_free(song); } my_finishCommand(conn); return res; }
int main(int argc, char *argv[]) { int opts; const char *short_opts = "t:r:b:a:p:s:h"; struct option long_opts[] = { { "title", required_argument, 0, 't' }, { "artist", required_argument, 0, 'r' }, { "album", required_argument, 0, 'b' }, { "addr", required_argument, 0, 'a' }, { "port", required_argument, 0, 'p' }, { "secret", required_argument, 0, 's' }, { "help", no_argument, 0, 'h' }, { 0, 0, 0, 0 } }; unsigned int id = 0; struct mpd_song *song = NULL; struct mpd_connection *mpd = NULL; char *mpd_addr = getenv("MPD_HOST"); int mpd_port = getenv("MPD_PORT") ? atoi(getenv("MPD_PORT")) : 0; char *mpd_pass = NULL; char *title = NULL; char *artist = NULL; char *album = NULL; if (argc == 1) { help(); return -1; } while ((opts = getopt_long(argc, argv, short_opts, long_opts, 0)) != -1) { switch (opts) { case 't': { title = optarg; break; } case 'r': { artist = optarg; break; } case 'b': { album = optarg; break; } case 'a': { mpd_addr = optarg; break; } case 'p': { mpd_port = atoi(optarg); break; } case 's': { mpd_pass = optarg; break; } default : case 'h': { help(); return -1; } } } mpd = mpd_connection_new(mpd_addr, mpd_port, 30000); CHECK_MPD_CONN(mpd); if (mpd_pass != NULL) { mpd_run_password(mpd, mpd_pass); CHECK_MPD_CONN(mpd); } mpd_search_queue_songs(mpd, false); if (title) { mpd_search_add_tag_constraint( mpd, MPD_OPERATOR_DEFAULT, MPD_TAG_TITLE, title ); } if (artist) { mpd_search_add_tag_constraint( mpd, MPD_OPERATOR_DEFAULT, MPD_TAG_ARTIST, artist ); } if (album) { mpd_search_add_tag_constraint( mpd, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album ); } mpd_search_commit(mpd); song = mpd_recv_song(mpd); mpd_response_finish(mpd); if (song) { id = mpd_song_get_id(song); mpd_song_free(song); mpd_run_play_id(mpd, id); CHECK_MPD_CONN(mpd); } mpd_connection_free(mpd); return 0; }
static void env_export_song(struct mpd_song *song) { const char *tag; char *envstr; time_t t; char date[DEFAULT_DATE_FORMAT_SIZE] = { 0 }; g_setenv("MPD_SONG_URI", mpd_song_get_uri(song), 1); t = mpd_song_get_last_modified(song); strftime(date, DEFAULT_DATE_FORMAT_SIZE, DEFAULT_DATE_FORMAT, localtime(&t)); g_setenv("MPD_SONG_LAST_MODIFIED", date, 1); envstr = g_strdup_printf("%u", mpd_song_get_duration(song)); g_setenv("MPD_SONG_DURATION", envstr, 1); g_free(envstr); envstr = g_strdup_printf("%u", mpd_song_get_pos(song)); g_setenv("MPD_SONG_POS", envstr, 1); g_free(envstr); envstr = g_strdup_printf("%u", mpd_song_get_id(song)); g_setenv("MPD_SONG_ID", envstr, 1); g_free(envstr); /* Export tags. FIXME: For now we just export the first tag value to * the environment. */ if ((tag = mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)) != NULL) g_setenv("MPD_SONG_TAG_ARTIST", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0)) != NULL) g_setenv("MPD_SONG_TAG_ALBUM", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_ALBUM_ARTIST, 0)) != NULL) g_setenv("MPD_SONG_TAG_ALBUM_ARTIST", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_TITLE, 0)) != NULL) g_setenv("MPD_SONG_TAG_TITLE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_TRACK, 0)) != NULL) g_setenv("MPD_SONG_TAG_TRACK", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_NAME, 0)) != NULL) g_setenv("MPD_SONG_TAG_NAME", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_GENRE, 0)) != NULL) g_setenv("MPD_SONG_TAG_GENRE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_DATE, 0)) != NULL) g_setenv("MPD_SONG_TAG_DATE", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_COMPOSER, 0)) != NULL) g_setenv("MPD_SONG_TAG_COMPOSER", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_PERFORMER, 0)) != NULL) g_setenv("MPD_SONG_TAG_PERFORMER", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_COMMENT, 0)) != NULL) g_setenv("MPD_SONG_TAG_COMMENT", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_DISC, 0)) != NULL) g_setenv("MPD_SONG_TAG_DISC", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ARTISTID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ARTISTID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ALBUMID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ALBUMID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_ALBUMARTISTID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_ALBUMARTISTID", tag, 1); if ((tag = mpd_song_get_tag(song, MPD_TAG_MUSICBRAINZ_TRACKID, 0)) != NULL) g_setenv("MPD_SONG_TAG_MUSICBRAINZ_TRACKID", tag, 1); }
/** * Update: determine MPD's current song and enqueue submissions. */ static gboolean lmc_update(G_GNUC_UNUSED gpointer data) { struct mpd_song *prev; enum mpd_state state; unsigned elapsed = 0; prev = current_song; state = lmc_current(¤t_song, &elapsed); if (state == MPD_STATE_PAUSE) { if (!was_paused) song_paused(); was_paused = true; if (idle_supported) { lmc_schedule_idle(); update_source_id = 0; return false; } return true; } else if (state != MPD_STATE_PLAY) { current_song = NULL; last_id = -1; was_paused = false; } else if (mpd_song_get_tag(current_song, MPD_TAG_ARTIST, 0) == NULL || mpd_song_get_tag(current_song, MPD_TAG_TITLE, 0) == NULL) { if (mpd_song_get_id(current_song) != last_id) { g_message("new song detected with tags missing (%s)\n", mpd_song_get_uri(current_song)); last_id = mpd_song_get_id(current_song); } mpd_song_free(current_song); current_song = NULL; } if (was_paused) { if (current_song != NULL && mpd_song_get_id(current_song) == last_id) song_continued(); was_paused = false; } /* submit the previous song */ if (prev != NULL && (current_song == NULL || mpd_song_get_id(prev) != mpd_song_get_id(current_song))) { song_ended(prev, love); love = false; } if (current_song != NULL) { if (mpd_song_get_id(current_song) != last_id) { /* new song. */ song_started(current_song); last_id = mpd_song_get_id(current_song); } else { /* still playing the previous song */ song_playing(current_song, elapsed); } } if (prev != NULL) mpd_song_free(prev); if (g_mpd == NULL) { lmc_schedule_reconnect(); update_source_id = 0; return false; } if (idle_supported) { lmc_schedule_idle(); update_source_id = 0; return false; } return true; }
unsigned Song::getID() const { assert(m_song); return mpd_song_get_id(m_song.get()); }