Example #1
0
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;
}
Example #2
0
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));
}
Example #3
0
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);
	}
}
Example #4
0
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));
}
Example #5
0
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);
}
Example #6
0
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;
}
Example #7
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));
}
Example #8
0
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;
}
Example #9
0
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;
}
Example #10
0
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;
}
Example #11
0
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;
}
Example #12
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);
}
Example #13
0
/**
 * 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(&current_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;
}
Example #14
0
unsigned Song::getID() const
{
	assert(m_song);
	return mpd_song_get_id(m_song.get());
}