From 43a35f141b9b5a8d3db3ae35114db0ac1f6dafc9 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Sat, 30 Jan 2021 16:55:17 +0100 Subject: [PATCH] MPD: Add the seek, seekid, seekcur commands in lektord NOTE: Still need to add the module function "set_position(int)" in the sdl2 player module. --- README.md | 6 ++--- inc/lektor/commands.h | 4 +++ inc/lektor/database.h | 3 ++- src/base/commands.c | 53 ++++++++++++++++++++++++++++++++++++++++ src/database/queue.c | 24 ++++++++++++++++-- src/module/module_sdl2.c | 1 + src/net/listen.c | 7 ++++++ 7 files changed, 92 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 71c5cb9a..0e19ed3a 100644 --- a/README.md +++ b/README.md @@ -204,9 +204,9 @@ For the compatibility column, the possible values are the following: | `play [songpos]` | `play [songpos]` | + | if no `songpos` passed, defaults to `0` | | `playid [songid]` | `playid {songid}` | + | get the first found `songid` in the queue | | `previous` | `previous` | + | | -| `seek {songpos} {time}` | | | not implemented | -| `seekid {songid} {time}` | | | not implemented | -| `seekcur {time}` | `seekcur {time}` | | not implemented | +| `seek {songpos} {time}` | `seek {songpos} {time}` | + | | +| `seekid {songid} {time}` | `seekid {songid} {time}` | + | seek to the first found id, sqlite dependent | +| `seekcur {time}` | `seekcur {time}` | + | | | `stop` | `stop` | + | | | `add {uri}` | `add {uri}` | + | | | `addid {id} [pos]` | `addid {id...}` | ~ | can add multiple songs, but no position support | diff --git a/inc/lektor/commands.h b/inc/lektor/commands.h index bae6beeb..0eb603cb 100644 --- a/inc/lektor/commands.h +++ b/inc/lektor/commands.h @@ -27,6 +27,10 @@ bool command_play (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); bool command_playid (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); bool command_stop (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); +bool command_seek (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); +bool command_seekid (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); +bool command_seekcur (struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]); + bool command_set_pos(struct lkt_state *srv, int index); /* FIXME: Not used in net/listen.c */ /* The queue */ diff --git a/inc/lektor/database.h b/inc/lektor/database.h index e57b4aba..61bea9e2 100644 --- a/inc/lektor/database.h +++ b/inc/lektor/database.h @@ -46,7 +46,8 @@ bool database_queue_set_paused (volatile sqlite3 *db, bool paused); bool database_queue_set_current_index(volatile sqlite3 *db, int idx); bool database_queue_get_current_file (volatile sqlite3 *db, char filepath[PATH_MAX]); -bool database_get_kara_path(volatile sqlite3 *db, int id, char filepath[PATH_MAX]); +bool database_get_kara_path (volatile sqlite3 *db, int id, char filepath[PATH_MAX]); +bool database_get_kara_position(volatile sqlite3 *db, int id, int *pos); /* Update the database. */ bool database_update (volatile sqlite3 *db, const char *kara_dir, int check_timestamp); diff --git a/src/base/commands.c b/src/base/commands.c index ca8b9208..049afeb3 100644 --- a/src/base/commands.c +++ b/src/base/commands.c @@ -694,6 +694,59 @@ command_set_pos(struct lkt_state *srv, int index) return ! MOD_CALL(srv->window_mod, "load", filepath); } +bool +command_seek(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) +{ + int pos, seconds, err_flag; + char *endptr; + RETURN_UNLESS(args && args[0] && args[1], "Invalid arguments", false); + + STRTOL(pos, args[0], endptr, err_flag); + RETURN_IF(err_flag, "Failed to get a number!", false); + + STRTOL(seconds, args[1], endptr, err_flag); + RETURN_IF(err_flag, "Failed to get a number!", false); + + RETURN_UNLESS(command_set_pos(srv, pos), "Failed to get to the right file", false); + srv->mpd_idle_events |= MPD_IDLE_PLAYER; + return ! MOD_CALL(srv->window_mod, "set_position", seconds); +} + +bool +command_seekid(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) +{ + int id, seconds, err_flag, position; + char *endptr; + RETURN_UNLESS(args && args[0] && args[1], "Invalid arguments", false); + + STRTOL(id, args[0], endptr, err_flag); + RETURN_IF(err_flag, "Failed to get a number!", false); + + STRTOL(seconds, args[1], endptr, err_flag); + RETURN_IF(err_flag, "Failed to get a number!", false); + + RETURN_UNLESS(database_get_kara_position(srv->db, id, &position), + "Can't find kara in queue", false); + + srv->mpd_idle_events |= MPD_IDLE_PLAYER; + RETURN_UNLESS(command_set_pos(srv, position), "Failed to set position to right kara", false); + return ! MOD_CALL(srv->window_mod, "set_position", seconds); +} + +bool +command_seekcur(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) +{ + int seconds, err_flag; + char *endptr; + RETURN_UNLESS(args && args[0], "Invalid arguments", false); + + STRTOL(seconds, args[0], endptr, err_flag); + RETURN_IF(err_flag, "Failed to get a number!", false); + + srv->mpd_idle_events |= MPD_IDLE_PLAYER; + return ! MOD_CALL(srv->window_mod, "set_position", seconds); +} + bool command_plt_add(struct lkt_state *srv, char *args[LKT_MESSAGE_ARGS_MAX]) { diff --git a/src/database/queue.c b/src/database/queue.c index 6ef69d50..635c3644 100644 --- a/src/database/queue.c +++ b/src/database/queue.c @@ -85,8 +85,7 @@ error: } bool -database_queue_current_kara(volatile sqlite3 *db, struct kara_metadata *res, - int *id) +database_queue_current_kara(volatile sqlite3 *db, struct kara_metadata *res, int *id) { static const char *SQL_STMT = "SELECT song_name, source_name, category, language, author_name, " @@ -668,6 +667,27 @@ error: return false; } +bool +database_get_kara_position(volatile sqlite3 *db, int id, int *pos) +{ + sqlite3_stmt *stmt = NULL; + static const char *SQL = + "WITH content AS (" + " SELECT kara.id AS id, position" + " FROM queue" + " JOIN kara ON kara_id = kara.id" + " GROUP BY position ORDER BY position ASC, priority DESC)" + "SELECT id, position FROM content WHERE id = ?;"; + RETURN_UNLESS(db && pos, "Invalid argument", false); + SQLITE_PREPARE(db, stmt, SQL, error); + SQLITE_BIND_INT(db, stmt, 1, id, error); + SQLITE_STEP_ROW(db, stmt, error); + *pos = sqlite3_column_int(stmt, 0); + return true; +error: + return false; +} + bool database_queue_shuffle(volatile sqlite3 *db) { diff --git a/src/module/module_sdl2.c b/src/module/module_sdl2.c index f1169076..67418b9a 100644 --- a/src/module/module_sdl2.c +++ b/src/module/module_sdl2.c @@ -235,6 +235,7 @@ REG_ADD_NAMED("load", mod_load_file) REG_ADD_NAMED("set_volume", mod_set_volume) REG_ADD_NAMED("get_duration", mod_get_duration) REG_ADD_NAMED("get_elapsed", mod_get_elapsed) +/* Add "set_position" */ REG_END() #if ! defined (LKT_STATIC_MODULE) REG_EXPORT(sdl2_reg) diff --git a/src/net/listen.c b/src/net/listen.c index cffd0fe0..bd2b9811 100644 --- a/src/net/listen.c +++ b/src/net/listen.c @@ -204,6 +204,13 @@ handle_simple_command(struct lkt_state *srv, size_t c, struct lkt_command cmd) else if (STR_MATCH(cmd.name, "shuffle")) err = ! command_shuffle(srv, NULL); + else if (STR_MATCH(cmd.name, "seek")) + err = ! command_seek(srv, cmd.args); + else if (STR_MATCH(cmd.name, "seekid")) + err = ! command_seekid(srv, cmd.args); + else if (STR_MATCH(cmd.name, "seekcur")) + err = ! command_seekcur(srv, cmd.args); + else if (STR_MATCH(cmd.name, "playlist") || STR_MATCH(cmd.name, "playlistinfo")) err = ! command_queue_list(srv, c, cmd.args); else if (STR_MATCH(cmd.name, "playlistfind") || STR_MATCH(cmd.name, "playlistsearch")) -- GitLab