From: Olaf Wintermann Date: Sun, 16 Jan 2022 19:58:11 +0000 (+0100) Subject: implement basic autoplay X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=2d586cf54532edd59659ef37323c992cdacca7ec;p=uwplayer.git implement basic autoplay --- diff --git a/application/player.c b/application/player.c index 4d0ef22..37c1b98 100644 --- a/application/player.c +++ b/application/player.c @@ -39,6 +39,7 @@ #include #include "json.h" +#include "utils.h" #include "settings.h" extern char **environ; @@ -560,11 +561,27 @@ static void json_print(JSONValue *value, char *name, int indent) { } } +static Boolean open_next_file(XtPointer data) { + char *file = data; + MainWindow *win = GetMainWindow(); + if(win->file) { + free(file); + } + win->file = file; + PlayerOpenFile(win); + return 0; +} + void PlayerEOF(Player *p) { MainWindow *win = GetMainWindow(); if(win->repeatTrack) { char *cmd = "{ \"command\": [\"set_property\", \"playback-time\", 0] }\n"; write(p->ipc, cmd, strlen(cmd)); + } else if(win->autoplayFolder) { + char *next_file = util_find_next_file(win->file); + if(next_file) { + AppExecProc(open_next_file, next_file); + } } } diff --git a/application/utils.c b/application/utils.c index 35b0ab5..7d123e3 100644 --- a/application/utils.c +++ b/application/utils.c @@ -22,6 +22,14 @@ #include "utils.h" +#include +#include +#include +#include +#include +#include +#include + #include @@ -54,3 +62,105 @@ char* util_concat_path(const char *url_base, const char *p) { return url.ptr; } + +char* util_resource_name(char *url) { + sstr_t urlstr = sstr(url); + if(urlstr.ptr[urlstr.length-1] == '/') { + urlstr.length--; + } + sstr_t resname = sstrrchr(urlstr, '/'); + if(resname.length > 1) { + return resname.ptr+1; + } else { + return url; + } +} + +char* util_parent_path(const char *path) { + char *name = util_resource_name((char*)path); + size_t namelen = strlen(name); + size_t pathlen = strlen(path); + size_t parentlen = pathlen - namelen; + char *parent = malloc(parentlen + 1); + memcpy(parent, path, parentlen); + parent[parentlen] = '\0'; + return parent; +} + +#define FIND_NEXT_MAX_FILES 2000 + +typedef int (*cmpfnc)(const void *, const void *); + +char* util_find_next_file(char *current_file) { + char *current_folder = util_parent_path(current_file); + char *current_file_name = util_resource_name(current_file); + DIR *dir = opendir(current_folder); + if(!dir) { + fprintf(stderr, "Error: Cannot open directory '%s': %s\n", current_folder, strerror(errno)); + free(current_folder); + return NULL; + } + + size_t nfiles = 0; + size_t falloc = 64; + char **files = calloc(falloc, sizeof(char*)); + + int abort = 0; + struct dirent *ent; + while((ent = readdir(dir))) { + if(ent->d_name[0] == '.') { + // skip '.', '..' and dot-files + continue; + } + + // stat + char *abs_path = util_concat_path(current_folder, ent->d_name); + struct stat s; + int r = stat(abs_path, &s); + free(abs_path); + if(r) { + continue; + } + + // we only want regular files + if(!S_ISREG(s.st_mode)) { + continue; + } + + // add file + if(nfiles >= falloc) { + falloc *= 2; + if(falloc > FIND_NEXT_MAX_FILES) { + abort = 1; + break; + } + files = realloc(files, falloc * sizeof(char*)); + } + files[nfiles] = strdup(ent->d_name); + + nfiles++; + } + + char *result = NULL; + if(!abort) { + qsort(files, nfiles, sizeof(char*), (cmpfnc)strcmp); + // search array for current file and return the successor + for(int i=0;i