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(); } }
/* * 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); }
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; }
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 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; }
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; }
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; }