implement basic autoplay
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Jan 2022 19:58:11 +0000 (20:58 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 16 Jan 2022 19:58:11 +0000 (20:58 +0100)
application/player.c
application/utils.c
application/utils.h

index 4d0ef22..37c1b98 100644 (file)
@@ -39,6 +39,7 @@
 #include <pthread.h>
 
 #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);
+        }
     }
 }
 
index 35b0ab5..7d123e3 100644 (file)
 
 #include "utils.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <errno.h>
+
 #include <ucx/string.h>
 
 
@@ -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<nfiles;i++) {
+            if(!strcmp(files[i], current_file_name)) {
+                if(i + 1 < nfiles) {
+                    result = util_concat_path(current_folder, files[i+1]);
+                    break;
+                }
+            }
+        }
+    }
+    
+    closedir(dir);
+    for(int i=0;i<nfiles;i++) {
+        free(files[i]);
+    }
+    free(files);
+    free(current_folder);
+    
+    return result;
+}
index 813fe65..ea79563 100644 (file)
@@ -32,6 +32,12 @@ extern "C" {
 
 char* util_concat_path(const char *url_base, const char *p);
 
+char* util_resource_name(char *url);
+
+char* util_parent_path(const char *path);
+
+char* util_find_next_file(char *current_file);
+
 
 #ifdef __cplusplus
 }