Random videos displaying in different masks

edited September 2015 in Library Questions

Hey guys! I'm just beginning with Processing, so this is probably something just easy that I still don't understand. Okay now the project: I am trying to make this player that randomize some videos to display them in three different mask (together they form a entire screen) with three different keyboard keys... The masks and, theoretically the random aspect are done, but I really can't figure out how to activate the masks with the keys without using the same array output (without using the same random picked video in all three masks)...And it really sounds complicated, but if someone could help me I would be eternally grateful. (Windows 7/ Processing 2.2.1)

    import processing.video.*;
    import ddf.minim.*;

    //Audio
    AudioPlayer player;
    Minim minim;//audio context

    //
    PImage mask1;
    PImage mask2;
    PImage mask3;

    //Array-random
    int maxMovies= 4;
    int rand = int(random(maxMovies)); 

    Movie[] myMovies=new Movie[maxMovies];
    ArrayList<Movie> moviesPlaying = new ArrayList<Movie>();


    void setup() {
      size (640, 480, P3D);
      frameRate(30);

      //sound
      minim = new Minim(this);
      player = minim.loadFile("cocoon.mp3", 2048);
      player.play();

      //masks
      mask1 = loadImage("center.jpg");
      mask2 = loadImage("left.jpg");
      mask3 = loadImage("right.jpg");

      for (int i = 0; i < myMovies.length; i ++ ) {
        myMovies[i] = new Movie(this, i+".mov");
      }
    }

    void keyPressed() {

      if (key=='a') {
        rand = int(random(maxMovies));

        moviesPlaying.add(myMovies[rand]);
        moviesPlaying.get(moviesPlaying.size()-1).loop();
      }
    }

    void draw() {
      background(0);

      for (int i = 0; i< moviesPlaying.size (); i++ ) {    
        Movie m = moviesPlaying.get(i);

        if (m.available())
          m.read();
        m.mask(mask1);
        image(m, 0, 0);
      }
    }

    void stop()
    {
      player.close();
      minim.stop();
      super.stop();
    }

Answers

  • edited January 2016

    I can't grasp exactly what you're trying to achieve, sorry.
    For now I did the example below just to test waters out.
    Check it out for yourself whether it gets close to what you wish:

    // forum.Processing.org/two/discussion/12609/
    // random-videos-displaying-in-different-masks
    
    // 2015-Sep-21
    
    import ddf.minim.Minim;
    import processing.video.Movie;
    import java.util.Map;
    
    static final String FILM_EXT = ".mov", PIC_EXT = ".jpg", MASK_FILES[] = {
      "center", "left", "right"
    };
    
    static final int MOVIES = MASK_FILES.length;
    final Map<Movie, MaskedFrame> movies = new HashMap<Movie, MaskedFrame>(MOVIES, 1);
    
    void setup() {
      size(640, 480, JAVA2D);
      smooth(4);
      frameRate(30);
      imageMode(CORNER);
    
      new Minim(this).loadFile("cocoon.mp3", 2048).loop();
    
      for (int i = 0; i != MOVIES; ++i) {
        MaskedFrame mf = new MaskedFrame();
        (mf.mask = loadImage(MASK_FILES[i] + PIC_EXT)).resize(width, height);
    
        Movie movie = new Movie(this, i + FILM_EXT);
        movies.put(movie, mf);
        movie.loop();
      }
    
      for (boolean stillNull = true; stillNull; delay(100))
        for (MaskedFrame mf: movies.values())  if (stillNull = mf.frame == null) break;
    }
    
    void draw() {
      for (MaskedFrame mf: movies.values()) mf.script();
    }
    
    void movieEvent(Movie movie) {
      movie.read();
      MaskedFrame mf = movies.get(movie);
    
      if (mf.frame != null) mf.updateFrame(movie);
      else                  mf.frame = movie.get();
    }
    
    class MaskedFrame {
      PImage frame, mask;
    
      synchronized void script() {
        maskFrame();
        displayFrame();
      }
    
      void maskFrame() {
        if (frame.width == mask.width & frame.height == mask.height) frame.mask(mask);
      }
    
      void displayFrame() {
        image(frame, 0, 0);
      }
    
      void displayFrame(int x, int y) {
        image(frame, x, y);
      }
    
      synchronized void updateFrame(PImage img) {
        img.loadPixels();
        arrayCopy(img.pixels, frame.pixels);
        frame.updatePixels();
      }
    }
    
  • Wow, thank you so much for your help @GotoLoop, and yeah I probably made it look more complicated than it is. Unfortunately this don't help me. I have three masks, so every time I press a keyboard button its randomically plays a video from my array (oh but I need it to be 3 different buttons). I am trying to rewrite the code with little success, so any help is really welcomed.

    videos_onmasks

  • I have three masks, so every time I press a keyboard button its randomically plays a video from my array...

    Again not well explained... At least I can't get it yet: 8-|

    • Are those videos supposed to be playing at the same time?
    • If so, are they displayed at same coordinates or are they split up?
    • Are those mask pics mapped to a particular video or are they applied randomly?
    • Are those buttons for play/pause or for mask activation?

    You see by now that lotsa information is missing.
    You need to lay out exactly what's your program is about to do. :-B

  • Sorry...I will try to explain it: 1.Yup, playing at same time. 2.Same coordinates, always centered. 3.The masks are constant, only the videos from an array that are applied in it randomly. 4.Okay, every time I press one button it activates a mask, and the video inside it. There is a video playing in the background, if you press "a", it activate a new layer over the video, for example.

    Thank you so much by your time, and sorry again T.T...

  • edited September 2015

    There are some contradictions here:

    • You say all of those videos are playing at the same time and being displayed at the same location.
    • But then you say "There is a video playing in the background, if you press "a", it activate a new layer over the video, ..."
    • Which video? It's all of them or just 1? Is a mask applied to 1 video or to all of them?
    • Still not very clear which of those 3 masks are applied to which video...

    And most importantly, what is exactly the bug from your sketch?
    Does it compile, or throws an exception or simply doesn't have the desired result? :-B
    Did my own version run there anyways? :-/

  • edited September 2015

    Thank you again. In my code the masks are working okay, the main problem is that I don't know how to pick a random movie from my array every time I press a different button and put it in a mask. It's works, but with just one key, if I try to add another key, well I don't know how to put another one... About the masks: 3 masks complete the entire screen, each mask pick a random video from my array every time a key is pressed. The video I talked about (in the bg) don't have a mask, is not even in the array. I just call to play so if anyone play any button the screen won't be black.

    My big problem is in this part:

    void keyPressed() {
    
      if (key=='a') {
        rand = int(random(maxMovies));
    
        moviesPlaying.add(myMovies[rand]);
        moviesPlaying.get(moviesPlaying.size()-1).loop();
      }
    }
    
    void draw() {
      background(0);
    
      for (int i = 0; i< moviesPlaying.size (); i++ ) {    
        Movie m = moviesPlaying.get(i);
    
        if (m.available())
          m.read();
        m.mask(mask1);
        image(m, 0, 0);
      }
    }
    

    How can I add more key (buttons) and make it activate the other masks like this?

  • edited September 2015
    • In my own version, each Movie is mapped to an instance of class MaskedFrame.
    • MaskedFrame got 2 PImage fields: frame & mask.
    • And logically, field mask is initialized w/ 1 of the loadImage() filters.
    • The way they're created, "center.jpg" is applied to "0.mov", "left.jpg" to "1.mov" & "right.jpg" to "2.mov".
    • So in my version, changing the filter used by a Movie is as easy as reassigning MaskedFrame's mask field to 1 of the loadImage() files.
    • Just create a PImage[] array in order to receive those 3 loadImage() files.
    • Then you can random() an index of it and assign it to 1 of the MaskedFrame's mask fields.
    • Each MaskedFrame object is bound to a Movie 1 of course.
  • edited September 2015

    Hey! @GoToLoop I am back. And I did it, well sorta of... My code works but only without the masks, when I activate the masks I got this error: "mask() can only be used with an image that's the same size" but the weird thing is that I made I code testing the masks and it works! Every time I put the array aspect of the code, its gimme this kind of error. It's bizarre. Oh, and sorry but I couldn't use your code 'cause I really can't understand most of it, so I just did it and learned a lot! Anyway thank you by your time :)

        import processing.video.*;
        import ddf.minim.*;
    
        //Audio
        AudioPlayer player;
        Minim minim;//audio context
    
        //Images
        PImage mask1;
        PImage mask2;
        PImage mask3;
    
        //MovieArray
        //String [] allMovies = {
        //  "0.mov", "1.mov", "2.mov"
        //Movie[] movie1;
        //int movee1 = int(random (allMovies.length));
    
        int maxMovies= 3;
        Movie[] myMovies=new Movie[maxMovies] ;
        int rand = int(random(maxMovies));
    
        Movie firstclipMovie;
    
        void setup() {
    
          size(1280, 720, P2D);
          frameRate(24);
    
          //sound
          minim = new Minim(this);
          player = minim.loadFile("cocoon.mp3", 2048);
          player.play();
    
          //Loadmasks
          mask1 = loadImage("center.jpg");
          mask2 = loadImage("left.jpg");
          mask3 = loadImage("right.jpg");
    
          for (int i = 0; i < myMovies.length; i ++ ) {
            myMovies[i] = new Movie(this, i+ ".mp4");
          }
        }
    
        //void movieEvent (Movie firstclipMovie) {
        //  firstclipMovie.read ();}
    
        void keyPressed() {
          rand = int(random(maxMovies));
        }
    
        void draw() {
          background(0);
          if (key=='a') {
    
            myMovies[rand].read();
            myMovies[rand].play();
            myMovies[rand].mask(mask1);
            image(myMovies[rand], 10, 10);
          }
    
          if (key=='s') {
    
            myMovies[rand].read();
            myMovies[rand].play();
            myMovies[rand].mask(mask2);
            image(myMovies[rand], 10, 10);
          }
    
          if (key=='d') {
    
            myMovies[rand].read();
            myMovies[rand].play();
            myMovies[rand].mask(mask3);
            image(myMovies[rand], 10, 10);
          }
        }
    
        void stop()
        {
          player.close();
          minim.stop();
          super.stop();
        }
    
Sign In or Register to comment.