dynamically show videos added to a folder

edited June 2015 in Library Questions

hej –

i know how to play/loop an existing video. but what if i have a folder in which videos will be copied (from an external source – in my case a raspberry pi that uploads captured video clips) dynamically?

can i add videos to my canvas on runtime? there is a function to list folder contents – but i don't know HOW TO dynamically add video sources to a running project.

is there any help? or a definitive "NO" …? thanks anyways!

– stephan

Answers

  • edited May 2015

    What you need is some kind of sentinel function, which is responsible to scan some folder from time to time and see whether some new file(s) arrived.

    I did something like that in this very old forum thread:
    http://forum.processing.org/one/topic/listing-last-10-modified-files-in-directory

    But it's very complex and was meant to do more stuff than that. :-&

    For maximum performance, best approach is having the folderSentinel() function running under another Thread. For that we'll use thread(""):
    https://processing.org/reference/thread_.html

    Another nice touch is to include a FilenameFilter:
    http://docs.oracle.com/javase/8/docs/api/java/io/FilenameFilter.html

    Then we can control for example which file types it's gonna be accepted by File's list() method:
    http://docs.oracle.com/javase/8/docs/api/java/io/File.html#list-java.io.FilenameFilter-

    All videos go into List<Movie> videos container.
    While new arrivals go into List<Movie> newVids temporarily.

    Every time folderSentinel() detects there are more File objects after a list() than there are Movie objects, it tries to find which 1(s) among the former are new.

    For that it compares (via equals() inside a double for () loop) each String from the former against each Movie's filename field from the latter.

    If at the end of the loop it doesn't get a match, a new Movie is instantiated using that String path. And it's temporarily add() into newVids.

    Once the double loop has completely finished, whatever newVids had collected goes into videos via addAll() method. And newVids gets clear().

  • edited May 2015

    And here's the whole example. Any doubts about it just ask here again: :D

    /**
     * Folder Sentinel (v1.21)
     * by GoToLoop (2015/May/10)
     *
     * forum.processing.org/two/discussion/10738/
     * dynamically-show-videos-added-to-a-folder
     */
    
    import java.io.FilenameFilter;
    
    static final FilenameFilter VIDEO_FILTER = new FilenameFilter() {
      final String[] EXTS = {
        "mp4", "webm", "mov"
      };
    
      boolean accept(File f, String name) {
        name = name.toLowerCase();
        for (String s : EXTS)  if (name.endsWith(s))  return true;
        return false;
      }
    };
    
    static final int SLEEP = 30 * 1000; // 30 seconds or half minute
    
    import java.util.List;
    import processing.video.Movie;
    
    final List<Movie> videos = new ArrayList<Movie>();
    
    File dir;
    Movie mv;
    int idx = -1;
    
    void setup() {
      size(1280, 800, JAVA2D);
    
      noSmooth();
      noLoop();
      frameRate(40);
    
      dir = dataFile("");
      thread("folderSentinel");
    
      while (videos.isEmpty())  delay(50);
    }
    
    void draw() {
      checkLatestVideo();
      set(width - mv.width >> 1, height - mv.height >> 1, mv);
    }
    
    void checkLatestVideo() {
      if (idx < videos.size() - 1) {
        if (mv != null)  mv.pause();
        (mv = videos.get(idx = videos.size() - 1)).loop();
        background(0);
        while (mv.width == 0)  delay(10);
      }
    }
    
    void movieEvent(Movie m) {
      m.read();
      redraw = true;
    }
    
    @ Override void exit() {
      for (Movie v : videos)  v.stop();
      super.exit();
    }
    
    void folderSentinel() {
      while (dir == null | !dir.isDirectory())  delay(50);
    
      final List<Movie> movies  = videos;
      final List<Movie> newVids = new ArrayList<Movie>();
    
      final File folder = dir;
      final String path = folder + "/";
    
      for (;; delay(SLEEP)) {
        println("Re-checking \"" + folder + "\" for new files...");
        String[] paths = folder.list(VIDEO_FILTER);
    
        if (paths.length <= movies.size()) {
          println("Nothing new has arrived since last scan.\n");
          continue;
        }
    
        for (String p : paths) {
          p = path + p;
          boolean isNew = true;
    
          for (Movie m : movies)  if (p.equals(m.filename)) {
            isNew = false;
            break;
          }
    
          if (isNew) {
            Movie m = new Movie(this, p);
            if (m != null)  newVids.add(m);
          }
        }
    
        movies.addAll(newVids);
    
        println();
        println(newVids.size(), "new video(s) arrived just now:");
        for (Movie m : newVids)  println(m.filename);
    
        println("\nTotal available videos now:", movies.size());
        for (Movie m : movies)   println(m.filename);
        println();
    
        newVids.clear();
      }
    }
    
  • wow! thank you! i would have never thought about an answer with the complete code needed for my case.

    do you think it might be possible to show multiple videos at once? spreaded all over the canvas (randomly) with the same size? i would then need to clear them all at a specific time … and then go on with the next couple of movies.

  • Awesome, how can I cycle through the videos within the folder?

Sign In or Register to comment.