예제 #1
0
void TopWidget::onTrackBarChanged()
{
	if(parent->trackView->status != TrackView::Status::Stop)
	{
		int pos = trackBar->getValue() * parent->trackView->playtrack.length / 100;
		mpd_run_seek_id(mpd, parent->trackView->playtrack.queueid, pos);
		parent->trackView->trackpos = trackBar->getValue();
	}
}
예제 #2
0
파일: command.cpp 프로젝트: reynhout/pms
/*
 * Seeks in the stream
 */
bool
Control::seek(int offset)
{
	EXIT_IDLE;

	pms->log(MSG_DEBUG, 0, "Seeking by %d seconds\n", offset);

	/* FIXME: perhaps this check should be performed at an earlier stage? */
	if (!song()) {
		return false;
	}

	offset = st->time_elapsed + offset;

	return mpd_run_seek_id(conn->h(), song()->id, offset);
}
예제 #3
0
파일: command.c 프로젝트: daaang/mpc
int
cmd_cdprev(gcc_unused int argc, gcc_unused char **argv,
	   struct mpd_connection *conn)
{
	struct mpd_status *status = getStatus(conn);

	/* go to previous track if mpd is playing first 3 seconds of
	   current track otherwise seek to beginning of current
	   track */
	if (mpd_status_get_elapsed_time(status) < 3) {
		cmd_prev(0, NULL, conn);
	} else {
		if (!mpd_run_seek_id(conn, mpd_status_get_song_id(status), 0))
			printErrorAndExit(conn);
	}

	return 1;
}
예제 #4
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;
}
예제 #5
0
파일: mpd_client.c 프로젝트: rain0r/ympd
int callback_mpd(struct mg_connection *c)
{
    enum mpd_cmd_ids cmd_id = get_cmd_id(c->content);
    size_t n = 0;
    unsigned int uint_buf, uint_buf_2;
    int int_buf;
    char *p_charbuf = NULL, *token;

    if(cmd_id == -1)
        return MG_TRUE;

    if(mpd.conn_state != MPD_CONNECTED && cmd_id != MPD_API_SET_MPDHOST &&
        cmd_id != MPD_API_GET_MPDHOST && cmd_id != MPD_API_SET_MPDPASS &&
        cmd_id != MPD_API_GET_DIRBLEAPITOKEN)
        return MG_TRUE;

    switch(cmd_id)
    {
        case MPD_API_UPDATE_DB:
            mpd_run_update(mpd.conn, NULL);
            break;
        case MPD_API_SET_PAUSE:
            mpd_run_toggle_pause(mpd.conn);
            break;
        case MPD_API_SET_PREV:
            mpd_run_previous(mpd.conn);
            break;
        case MPD_API_SET_NEXT:
            mpd_run_next(mpd.conn);
            break;
        case MPD_API_SET_PLAY:
            mpd_run_play(mpd.conn);
            break;
        case MPD_API_SET_STOP:
            mpd_run_stop(mpd.conn);
            break;
        case MPD_API_RM_ALL:
            mpd_run_clear(mpd.conn);
            break;
        case MPD_API_RM_TRACK:
            if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
                mpd_run_delete_id(mpd.conn, uint_buf);
            break;
        case MPD_API_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_PLAY_TRACK,%u", &uint_buf))
                mpd_run_play_id(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_RANDOM:
            if(sscanf(c->content, "MPD_API_TOGGLE_RANDOM,%u", &uint_buf))
                mpd_run_random(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_REPEAT:
            if(sscanf(c->content, "MPD_API_TOGGLE_REPEAT,%u", &uint_buf))
                mpd_run_repeat(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CONSUME:
            if(sscanf(c->content, "MPD_API_TOGGLE_CONSUME,%u", &uint_buf))
                mpd_run_consume(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_SINGLE:
            if(sscanf(c->content, "MPD_API_TOGGLE_SINGLE,%u", &uint_buf))
                mpd_run_single(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CROSSFADE:
            if(sscanf(c->content, "MPD_API_TOGGLE_CROSSFADE,%u", &uint_buf))
                mpd_run_crossfade(mpd.conn, uint_buf);
            break;
        case MPD_API_GET_OUTPUTS:
            mpd.buf_size = mpd_put_outputs(mpd.buf, 1);
            c->callback_param = NULL;
            mpd_notify_callback(c, MG_POLL);
            break;
        case MPD_API_TOGGLE_OUTPUT:
            if (sscanf(c->content, "MPD_API_TOGGLE_OUTPUT,%u,%u", &uint_buf, &uint_buf_2)) {
                if (uint_buf_2)
                    mpd_run_enable_output(mpd.conn, uint_buf);
                else
                    mpd_run_disable_output(mpd.conn, uint_buf);
            }
            break;
        case MPD_API_SET_VOLUME:
            if(sscanf(c->content, "MPD_API_SET_VOLUME,%ud", &uint_buf) && uint_buf <= 100)
                mpd_run_set_volume(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_SEEK:
            if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
                mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
            break;
        case MPD_API_GET_QUEUE:
            if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf))
                n = mpd_put_queue(mpd.buf, uint_buf);
            break;
        case MPD_API_GET_BROWSE:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_BROWSE"))
                goto out_browse;

            uint_buf = strtoul(strtok(NULL, ","), NULL, 10);
            if((token = strtok(NULL, ",")) == NULL)
                goto out_browse;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            n = mpd_put_browse(mpd.buf, get_arg2(p_charbuf), uint_buf);
out_browse:
			free(p_charbuf);
            break;
        case MPD_API_ADD_TRACK:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_TRACK"))
                goto out_add_track;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_add_track;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_add(mpd.conn, get_arg1(p_charbuf));
out_add_track:
            free(p_charbuf);
            break;
        case MPD_API_ADD_PLAY_TRACK:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAY_TRACK"))
                goto out_play_track;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_play_track;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            int_buf = mpd_run_add_id(mpd.conn, get_arg1(p_charbuf));
            if(int_buf != -1)
                mpd_run_play_id(mpd.conn, int_buf);
out_play_track:
            free(p_charbuf);
            break;
        case MPD_API_ADD_PLAYLIST:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAYLIST"))
                goto out_playlist;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_playlist;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_load(mpd.conn, get_arg1(p_charbuf));
out_playlist:
            free(p_charbuf);
            break;
        case MPD_API_SAVE_QUEUE:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SAVE_QUEUE"))
                goto out_save_queue;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_save_queue;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            mpd_run_save(mpd.conn, get_arg1(p_charbuf));
out_save_queue:
            free(p_charbuf);
            break;
        case MPD_API_SEARCH:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH"))
				goto out_search;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_search;

			free(p_charbuf);
            p_charbuf = strdup(c->content);
            n = mpd_search(mpd.buf, get_arg1(p_charbuf));
out_search:
            free(p_charbuf);
            break;
#ifdef WITH_MPD_HOST_CHANGE
        /* Commands allowed when disconnected from MPD server */
        case MPD_API_SET_MPDHOST:
            int_buf = 0;
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDHOST"))
                goto out_host_change;

            if((int_buf = strtol(strtok(NULL, ","), NULL, 10)) <= 0)
                goto out_host_change;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_host_change;

            strncpy(mpd.host, token, sizeof(mpd.host));
            mpd.port = int_buf;
            mpd.conn_state = MPD_RECONNECT;
            free(p_charbuf);
            return MG_TRUE;
out_host_change:
            free(p_charbuf);
            break;
        case MPD_API_GET_MPDHOST:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdhost\", \"data\": "
                "{\"host\" : \"%s\", \"port\": \"%d\", \"passwort_set\": %s}"
                "}", mpd.host, mpd.port, mpd.password ? "true" : "false");
            break;
        case MPD_API_GET_DIRBLEAPITOKEN:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"dirbleapitoken\", \""
                "data\": \"%s\"}", dirble_api_token);
            break;
        case MPD_API_SET_MPDPASS:
            p_charbuf = strdup(c->content);
            if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDPASS"))
                goto out_set_pass;

            if((token = strtok(NULL, ",")) == NULL)
                goto out_set_pass;

            if(mpd.password)
                free(mpd.password);

            mpd.password = strdup(token);
            mpd.conn_state = MPD_RECONNECT;
            free(p_charbuf);
            return MG_TRUE;
out_set_pass:
            free(p_charbuf);
            break;
#endif
    }

    if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS)
    {
        n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", 
            mpd_connection_get_error_message(mpd.conn));

        /* Try to recover error */
        if (!mpd_connection_clear_error(mpd.conn))
            mpd.conn_state = MPD_FAILURE;
    }

    if(n > 0)
        mg_websocket_write(c, 1, mpd.buf, n);

    return MG_TRUE;
}
예제 #6
0
파일: mpd_client.c 프로젝트: HyShai/ympd
int callback_mpd(struct mg_connection *c)
{
    enum mpd_cmd_ids cmd_id = get_cmd_id(c->content);
    size_t n = 0;
    unsigned int uint_buf, uint_buf_2;
    int int_buf;
    char *p_charbuf = NULL;

    if(cmd_id == -1)
        return MG_CLIENT_CONTINUE;

    if(mpd.conn_state != MPD_CONNECTED && cmd_id != MPD_API_SET_MPDHOST &&
        cmd_id != MPD_API_GET_MPDHOST && cmd_id != MPD_API_SET_MPDPASS)
        return MG_CLIENT_CONTINUE;

    mpd_connection_set_timeout(mpd.conn, 10000);
    switch(cmd_id)
    {
        case MPD_API_UPDATE_DB:
            mpd_run_update(mpd.conn, NULL);
            break;
        case MPD_API_SET_PAUSE:
            mpd_run_toggle_pause(mpd.conn);
            break;
        case MPD_API_SET_PREV:
            mpd_run_previous(mpd.conn);
            break;
        case MPD_API_SET_NEXT:
            mpd_run_next(mpd.conn);
            break;
        case MPD_API_SET_PLAY:
            mpd_run_play(mpd.conn);
            break;
        case MPD_API_SET_STOP:
            mpd_run_stop(mpd.conn);
            break;
        case MPD_API_RM_ALL:
            mpd_run_clear(mpd.conn);
            break;
        case MPD_API_RM_TRACK:
            if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf))
                mpd_run_delete_id(mpd.conn, uint_buf);
            break;
        case MPD_API_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_PLAY_TRACK,%u", &uint_buf))
                mpd_run_play_id(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_RANDOM:
            if(sscanf(c->content, "MPD_API_TOGGLE_RANDOM,%u", &uint_buf))
                mpd_run_random(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_REPEAT:
            if(sscanf(c->content, "MPD_API_TOGGLE_REPEAT,%u", &uint_buf))
                mpd_run_repeat(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_CONSUME:
            if(sscanf(c->content, "MPD_API_TOGGLE_CONSUME,%u", &uint_buf))
                mpd_run_consume(mpd.conn, uint_buf);
            break;
        case MPD_API_TOGGLE_SINGLE:
            if(sscanf(c->content, "MPD_API_TOGGLE_SINGLE,%u", &uint_buf))
                mpd_run_single(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_VOLUME:
            if(sscanf(c->content, "MPD_API_SET_VOLUME,%ud", &uint_buf) && uint_buf <= 100)
                mpd_run_set_volume(mpd.conn, uint_buf);
            break;
        case MPD_API_SET_SEEK:
            if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2))
                mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2);
            break;
        case MPD_API_GET_QUEUE:
            if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf))
                n = mpd_put_queue(mpd.buf, uint_buf);
            break;
        case MPD_API_GET_BROWSE:
            if(sscanf(c->content, "MPD_API_GET_BROWSE,%u,%m[^\t\n]", &uint_buf, &p_charbuf) && p_charbuf != NULL)
            {
                n = mpd_put_browse(mpd.buf, p_charbuf, uint_buf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_TRACK:
            if(sscanf(c->content, "MPD_API_ADD_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                mpd_run_add(mpd.conn, p_charbuf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_PLAY_TRACK:
            if(sscanf(c->content, "MPD_API_ADD_PLAY_TRACK,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                int_buf = mpd_run_add_id(mpd.conn, p_charbuf);
                if(int_buf != -1)
                    mpd_run_play_id(mpd.conn, int_buf);
                free(p_charbuf);
            }
            break;
        case MPD_API_ADD_PLAYLIST:
            if(sscanf(c->content, "MPD_API_ADD_PLAYLIST,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                mpd_run_load(mpd.conn, p_charbuf);
                free(p_charbuf);
            }
            break;
        case MPD_API_SEARCH:
            if(sscanf(c->content, "MPD_API_SEARCH,%m[^\t\n]", &p_charbuf) && p_charbuf != NULL)
            {
                n = mpd_search(mpd.buf, p_charbuf);
                free(p_charbuf);
            }
            break;
#ifdef WITH_MPD_HOST_CHANGE
        /* Commands allowed when disconnected from MPD server */
        case MPD_API_SET_MPDHOST:
            int_buf = 0;
            if(sscanf(c->content, "MPD_API_SET_MPDHOST,%d,%m[^\t\n ]", &int_buf, &p_charbuf) && 
                p_charbuf != NULL && int_buf > 0)
            {
                strncpy(mpd.host, p_charbuf, sizeof(mpd.host));
                free(p_charbuf);
                mpd.port = int_buf;
                mpd.conn_state = MPD_RECONNECT;
                return MG_CLIENT_CONTINUE;
            }
            break;
        case MPD_API_GET_MPDHOST:
            n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdhost\", \"data\": "
                "{\"host\" : \"%s\", \"port\": \"%d\", \"passwort_set\": %s}"
                "}", mpd.host, mpd.port, mpd.password ? "true" : "false");
            break;
        case MPD_API_SET_MPDPASS:
            if(sscanf(c->content, "MPD_API_SET_MPDPASS,%m[^\t\n ]", &p_charbuf))
            {
                if(mpd.password)
                    free(mpd.password);

                mpd.password = p_charbuf;
                mpd.conn_state = MPD_RECONNECT;
                return MG_CLIENT_CONTINUE;
            }
            break;
#endif
    }

    if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS)
    {
        n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", 
            mpd_connection_get_error_message(mpd.conn));

        /* Try to recover error */
        if (!mpd_connection_clear_error(mpd.conn))
            mpd.conn_state = MPD_FAILURE;
    }

    if(n > 0)
        mg_websocket_write(c, 1, mpd.buf, n);

    return MG_CLIENT_CONTINUE;
}
예제 #7
0
파일: command.c 프로젝트: daaang/mpc
int
cmd_seek(gcc_unused int argc, gcc_unused char **argv,
	 struct mpd_connection *conn)
{
	struct mpd_status *status;
	char * arg = argv[0];

	int seekchange;
	int total_secs;
	int rel = 0;

	status = getStatus(conn);

	if (mpd_status_get_state(status) == MPD_STATE_STOP)
		DIE("not currently playing\n");

	/* Detect +/- if exists point to the next char */
	if (*arg == '+')
		rel = 1;
	else if (*arg == '-')
		rel = -1;

	if (rel != 0)
		++arg;

	/* If seeking by percent */
	if (arg[strlen(arg) - 1] == '%') {
		/* Remove the % */
		arg[strlen(arg) - 1] = '\0';

		/* percent seek, strtod is needed for percent with decimals */
		char *test;
		double perc = strtod(arg,&test);
		if (*test != '\0' || (rel == 0 && (perc < 0 || perc > 100)) ||
		    (rel && perc > abs(100)))
			DIE("\"%s\" is not an number between 0 and 100\n", arg);

		seekchange = perc * mpd_status_get_total_time(status) / 100 + 0.5;

	} else { /* If seeking by absolute seek time */

		if (strchr(arg, ':') != NULL) {
			int hr = 0;
			int min = 0;
			int sec = 0;

			/* Take the seconds off the end of arg */
			char *sec_ptr = strrchr(arg, ':');

			/* Remove ':' and move the pointer one byte up */
			*sec_ptr = '\0';
			++sec_ptr;

			/* If hour is in the argument, else just point to the arg */
			char *min_ptr = strrchr(arg, ':');
			if (min_ptr != NULL) {

				/* Remove ':' and move the pointer one byte up */
				*min_ptr = '\0';
				++min_ptr;

				/* If the argument still exists, it's the hour  */
				if (arg != NULL) {
					char *hr_ptr = arg;
					char *test;
					hr = strtol(hr_ptr, &test, 10);

					if (*test != '\0' ||
					    (rel == 0 && hr < 0))
						DIE("\"%s\" is not a positive number\n", sec_ptr);
				}
			} else {
				min_ptr = arg;
			}

			/* Change the pointers to a integer  */
			char *test;
			sec = strtol(sec_ptr, &test, 10);

			if (*test != '\0' || (rel == 0 && sec < 0))
				DIE("\"%s\" is not a positive number\n", sec_ptr);

			min = strtol( min_ptr, &test, 10 );

			if( *test != '\0' || (rel == 0 && min < 0 ))
				DIE("\"%s\" is not a positive number\n", min_ptr);

			/* If mins exist, check secs. If hrs exist, check mins  */
			if (min && strlen(sec_ptr) != 2)
				DIE("\"%s\" is not two digits\n", sec_ptr);
			else if (hr && strlen(min_ptr) != 2)
				DIE("\"%s\" is not two digits\n", min_ptr);

			/* Finally, make sure they're not above 60 if higher unit exists */
			if (min && sec > 60)
				DIE("\"%s\" is greater than 60\n", sec_ptr);
			else if (hr && min > 60 )
				DIE("\"%s\" is greater than 60\n", min_ptr);

			total_secs = (hr * 3600) + (min * 60) + sec;

		} else {

			/* absolute seek (in seconds) */
			char *test;
			total_secs = strtol(arg, &test, 10); /* get the # of seconds */

			if (*test != '\0' || (rel == 0 && total_secs < 0))
				DIE("\"%s\" is not a positive number\n", arg);
		}

		seekchange = total_secs;
	}

	/* This detects +/- and is necessary due to the parsing of HH:MM:SS numbers*/
	int seekto;
	if (rel == 1)
		seekto = mpd_status_get_elapsed_time(status) + seekchange;
	else if (rel == -1)
		seekto = mpd_status_get_elapsed_time(status) - seekchange;
	else
		seekto = seekchange;

	if (seekto > (int)mpd_status_get_total_time(status))
		DIE("Seek amount would seek past the end of the song\n");

	if (!mpd_run_seek_id(conn, mpd_status_get_song_id(status), seekto))
		printErrorAndExit(conn);

	mpd_status_free(status);
	return 1;
}