Issue with video player

edited June 8 in Library Questions

Hello, I wrote this class dedicated to a video player. I want to read videos when I click on 3d spheres in my main tab. How should I proceed to choose my videos inside the videoList, (they have the same names than the spheres) with an index ? I click on a sphere, it plays the full screen video wich has the same name than the sphere, then the video stop, window closes and go back to interface with the spheres and so on... Do someone know how I should start? Thanks a lot in advance for your help ;)

class Movie {


  int currentMovieIndex;
  int STATE_PLAYING_SELECTED_MOVIE;
  int currentState = STATE_PLAYING_SELECTED_MOVIE, STATE_WAITING_FOR_CLICK;
  float movieEndDuration = 0.039719;
  String [] stateLabels = {"waiting for click", "playing selected movie"};

  String [] videoList= {"obscurité", "sombre"};
  Movie[] movies;

  Movie(movies, String[]videoList) {

    Movie[] movies = new Movie[videoList.length]; 
    for (int i=0; i < videoList.length; i++) {
      movies[i] = new Movie(this, videoList[i]+".mp4");
      movies[currentMovieIndex].play();
    }
  }


  void drawMovie() {
    background(0);
    image(movies[currentMovieIndex], 0, 0);
  }
  void playSelectedMovie() {
    currentState = STATE_PLAYING_SELECTED_MOVIE;
    movies[currentMovieIndex].play();
  }

  void movieEvent (Movie m) {

    if (currentState == STATE_PLAYING_SELECTED_MOVIE) {
      if ((m.time()+ movieEndDuration) < m.duration) {
        m.read();
        movies[currentMovieIndex].play();
      } else if ((m.time() +movieEndDuration)>= m.duration()) { 
        m.stop();
        currentState = STATE_WAITING_FOR_CLICK;
        println("movie at index " + currentMovieIndex + " finished playback, current state: " + stateLabels[currentState]);
      }
    }
  }
}
Tagged:

Answers

  • edited June 9

    window closes

    Have you implemented this part? More details if possible...

    Important. The name of your class is Movie. However, Processing has a class called Movie and this is just conflicting. Change the name to something my MyMovieClass, for instance.


    There are a couple of considerations. Before going any further, it is very important to define exactly how movies are played. For this, you need to consider all possible scenarios in your program. Consider the following situation:

    The user clicks the sphere. The movie starts playing. Playing another movie is not possible but only after the movie stops playing.

    Second situation:
    A user clicks in a sphere. The movie starts playing. Then the user clicks on another sphere. The current movie stops playing and the other movie starts playing.

    This behavior is different and you should provide all these details upfront.

    Related to your line 32. keep in mind that you need to call the PApplet's movieEvent callback to be able to use this function, like this:

    void setup(){ ...}
    
    void draw(){...}
    
    void movieEvent(Movie m){
       myMovieObject.movieEvent(m);
    }
    

    Kf

  • This next post could be a starter: https://forum.processing.org/two/discussion/22640/can-anyone-help-me-find-what-s-wrong-with-my-code-for-a-video-player-based-off-sensor-reading#latest

    Check my code posted on May 18th. It has arduino code. You can remove any reference from arduino or serial since I implemented an alternative response using key events.

    You have a look at it and hopefully you can see what direction I would be taking next, or at least for you to consider.

    Kf

  • Dear kfrajer, thank you very much for your help. I checked out your code and implemented it into my class, I still have a problem with the constructor... I indicate Movie then the list to play... ?!

    To answer your question: yes if the user clicks the sphere. The movie starts playing. Playing another movie is not possible but only after the movie stops playing. And there will be an escape button if the user doesn't want to read completely the video and go back to the interface to click on a new sphere. I hope it's more clear?! I never used this library before and I am not fluent in Processing as you can notice Thanks a lot

    lm

    import processing.video.*;
    
    class MyMovieClass {
    
      int current=NO_MOVIE;
      String [] videoList= {"obscurité", "sombre"};
      Movie[] movies;
    
      MyMovieClass(Movie, String[]videoList) {
    
    
          for (int idx = 0; idx < videoList.length; i++) {
    movies[idx] = new Movie(this, videoList[idx]+".mp4");
    movies[idx].play();
          }
        }
    
      void drawMovie() {
        if (current != NO_MOVIE) {
          image(movies[current], 0, 0);
          movies[idx].play();
          return();
          if (millis() > targetTime) { 
            updateCurrentMovie(NO_MOVIE);
            println("Stopping" + current+ " : " + currentMovie);
            stopAll();
          }
        } else {
          // back to interface?!
        }
      }
    
      void playSelectedMovie() {
        current != NO_MOVIE;
        movies[current].play();
      }
    
      void movieEvent (Movie m) {
        m.read();
      }
    
      void stopAll() {
        for (Movie : m) {
          m.stop();
          m.jump(0);
        }
        targetTime =-1;
      }
      void playOne (int idx) {
        stopAll();
        movies[idx].play();
        delay(20);
        targetTime = 20+millis() + in(movies[idx].duration()*1000);
        println("Time schedule:" + millis()+"->"+targetTime+"msec");
      }
    }
    

    :-B

  • Dear kfrajer,

    if you ever have a bit of time today... Thanks a lot. best, l

  • You don't need line 14. In that block, you are initializing the movies. Line 14 play the movies.... but all at the same time? Conclusion: not need it!

    Also you have line 20 and 21, idx and current... you have two variables managing your movies? How do you manage your current variable? I am thinking it will be better to see all your code including setup and draw. I find for this type of problems it is better to be able to have a running example.

    For line 45, instead of using jump(0), I believe you can use .rewind()... this is not important atm but to keep in mind, like making a mental note: Check documentation.

    Kf

  • edited July 17

    Dear Kf, Thanks a lot for your answer.I post you the entire code, I haven't tried to link my selectSphere function with my my Movie Class yet since I wanted this class to be written properly before :)) Sorry the code is long! Thanks a lot for your help. Lm

    //import peasy.test.*;
    import peasy.org.apache.commons.math.*;
    import peasy.*;
    import peasy.org.apache.commons.math.geometry.*;
    import processing.opengl.*;
    import processing.pdf.*;
    
    
    PeasyCam camera;
    // nmbr of spheres
    Sphere [] sats;
    Sphere [] planets;
    Sphere sun;
    Sphere currentSphereCenter;
    boolean record;
    boolean pressed = false;
    boolean locked = false;
    float radiusSphere = 800;
    float radius;
    float range;
    float rangeCount = 600;
    PVector camPos;   
    float theta;
    float phi;
    boolean resetOnDoubleClick =true;
    color value;
    
    // VIDEO GLOBAL VARIABLES
    int NOMOVIE=-100;
    int current=NOMOVIE;
    String currentMovie;
    int targetTime =-1;
    MyMovieClass MovieCl1;
    
    String[] words = { 
      "suées nocturnes", "trop de luxes", "outrenoir", "clair de nuit", "lucioles", "voir le noir", "chiaroscuro"
    }; 
    String[][] satWords = { 
      {
        "nuit pétrole", "les ombres", "apprivoiser le noir", "nuit debout", "lumière !", "hantise"
      }
      , {
        "folles lucioles", "pleins phares", "extinction", "jour nocturne", "esthétique pollueuse"
      }
      , {
        "près des étoiles", "clairement obscur", "poussières", "petite planète", "pourquoi pourquoi ?"
      }
      , {
        "une vie à part", "phare away", "la nuit nuit", "dans le pétrin", "rangs serrés", "à dessein"
      }
      , {
        "dormir debout", "chronobio", "chez morphée", "face nocturne", "âmes soeurs"
      }
      , {
        "nuit du regard", "voir avec les doigts", "pas du soir"
      }
      , {
        "scène obscure", "on/off", "lumière sombre", "light by night"
      }
    }; 
    
    void setup() {
    
    
      size (1200, 800, P3D);
      hint(DISABLE_DEPTH_TEST);
    
      camera = new PeasyCam(this, 1500);
      range = rangeCount;
      value = color (int(random(150, 250)));
    
      PFont Moonfont = createFont ("RNIB MOON", (180));
    
      sun = new Sphere(0, 0, TWO_PI, PI/2, "Clair Obscur", Moonfont, null, 0, color(random(150, 220)));
      //textFont (Moonfont);
      //text("Clair Obscur", width/2, height/2);
      PFont [] fonts1 = new PFont [8];
      for (int j=0; j<8; j++) {
        println(j);
        fonts1 [j] = createFont("Helvetica 45 Light", (62));
        //println( "fonts :" + fonts[j].getSize());
      }
      PFont [] fonts2 = new PFont [8];
      for (int j=0; j<8; j++) {
        println(j);
        fonts2 [j] = createFont("Helvetica 45 Light", (30));
        //println( "fonts :" + fonts[j].getSize());
      }
      Sphere []planets = new Sphere [words.length];
      for (int i =0; i<planets.length; i++) {
        PFont f = fonts1[floor(random(fonts1.length))] ;
    
        planets[i] = new Sphere(radiusSphere, random(25, 40), random(0, TWO_PI), random(0, PI), words[i], f, sun, 1, color(random(200, 250)));
        // satWords = liste de liste des noms pr chaque satellite et [i] correspond à la planète
    
        Sphere [] sats = new Sphere [satWords[i].length];
        for (int k =0; k<satWords[i].length; k++) {
          PFont g = fonts2[floor(random(fonts2.length))] ;
    
          sats [k] = new Sphere(radiusSphere/4, random(10, 20), random(0, TWO_PI), random(0, PI), satWords[i][k], g, planets[i], 2, color(random(180, 200)));
        } 
        planets [i].addSatellites(sats);
      }
      //String[] fontList = PFont.list();
      // printArray(fontList);
    
      sun.addSatellites(planets);
      currentSphereCenter = sun;
      println(rangeCount); 
      frameRate(25);
    
      //VIDEO
      for (int i =0; i<planets.length; i++) {
        for (int k =0; k<satWords[i].length; k++) {
          MovieCl1= new MyMovieClass (satWords[i]);
        }
      }
      updateCurrentMovie(NOMOVIE);
    }
    
    
    void draw() {
      if (record) {
        beginRaw(PDF, "output.pdf");
      }
      background (0); 
    
      sun.display();
      sun.separate(planets);
    
    
    
      pushMatrix();
      translate (0, 0, 0);
      sphereWave();
      popMatrix();
    }
    void sphereWave() {
      float radious = radiusSphere;
      float noiseScale = 0.01;
      float timeScale = 0.03;
      stroke (75, 75, 75, 120);
      noFill();
      for (float y = -radious/3 * 2.0; y <= radious * 2.0 / 3; y += 12) {
        float r = radious * cos(asin(abs(y / radious)));
        beginShape();
        for (float radian = 0; radian < TWO_PI; radian += PI / 256) {
          float x = r * cos(radian);
          float z = r * sin(radian);
          float yy = y + map(noise(x * noiseScale, frameCount * timeScale, z * noiseScale), 0, 1, -radious / 3, radious / 3);
          if (yy > radious) {
            yy = radious;
          }
          float rr = radious * cos(asin(abs(yy / radious)));
          float xx = rr * cos(radian);
          float zz = rr * sin(radian);
          vertex(xx, yy, zz);
        }
        endShape(CLOSE);
      }
      if (record) {
        endRaw();
        record = false;
      }
    }
    
    
    void keyPressed() {
      if (key == 'r') {
        record = true;
      }
    }
    
    void mouseClicked () {
    
      Sphere clickedSphere = sun. planets[0];
      float lastd = 10000;
    
    
      for (Sphere s : sun.planets) {
        float x1 = screenX (s.x, s.y, s.z);
        float y1 = screenY (s.x, s.y, s.z);
        float d = dist(x1, y1, mouseX, mouseY);
        if ( d < lastd) {
          lastd = d;
          clickedSphere = s;
          camera.lookAt(s.x, s.y, s.z, d+300, 1500);
        }
      }
      for (Sphere s : sun.planets) {
        for (Sphere sat : s.planets) {
    
          float x1 = screenX (s.x+sat.x, s.y+sat.y, sat.z+s.z);
          float y1 = screenY (s.x+sat.x, s.y+sat.y, sat.z+s.z);
          float d = dist(x1, y1, mouseX, mouseY);
          if ( d < lastd) {
            lastd = d;
            clickedSphere = sat;
            camera.lookAt(s.x+sat.x, s.y+sat.y, s.z+sat.z, d+300, 1500);
          }
        }
      }
      if (lastd <= clickedSphere.radius*1.5) {
        selectSphere (clickedSphere);
      } else {
        backLevel();
        camera.lookAt(sun.x, sun.y, sun.z, 1400, 1500);
      }
    }
    
    
    void backLevel() {
      println("backLevel");
      if (currentSphereCenter != sun) {
        selectSphere (currentSphereCenter.sphereCenter);
      }
    }
    void selectSphere (Sphere s) {
      planets= sats;
      if (currentSphereCenter != sun) {
        currentSphereCenter.satDeSelect();
      }
      currentSphereCenter = s;
      s.satSelect();
    
      println ("planete la plus proche: "+ s.name);
    }
    
    // SELECT CURRENT VIDEO
    void updateCurrentMovie (int c) {
      current = c;
      currentMovie = current ==NOMOVIE?"No movie selected":"movie"+(current+1);
    }
    
    ///////////////////////////////////////////////////////////////////////////
    
    class Sphere {
      float theta;
      float phi;
      float vTheta;
      float vPhi;
      float  r, x, y, z;
      float radius;
      //float radiusSphere;
      String name;
      PFont font;
      int level;
      color strokeColor;
      Sphere[] planets;
      Sphere sphereCenter;
    
      boolean isSelected;
      boolean wasVisited;
    
      PVector location;
      PVector velocity;
      PVector acceleration;
      float phiStep;
      float thetaStep;
      PVector nameSize;
      float noiseScaleZ;
      float maxSpeed;
      float maxForce;
      //VideoPlayer vp;
    
      Sphere (float radiusSphere, float rad, float theta, float phi, String s, PFont f, Sphere sC, int l, color StrokeCol) {
        this.theta = theta ;
        this.phi = phi;
        this.r = radiusSphere;
        vTheta =0;
        vPhi =0;
        x = r * sin(phi) * cos(theta);
        y = r * sin(phi) * sin(theta);
        z = r * cos(phi);
        location = new PVector (x, y, z);
        velocity = new PVector( r * sin(phi) * cos(theta), r * sin(phi) * sin(theta), r * cos(phi));
        acceleration = new PVector(0, 0, 0);
    
        radius = rad;
        name = s;
        font = f;
        sphereCenter = sC;
        level = l;
        strokeColor = StrokeCol;
        phiStep = 8;
        thetaStep = 0.05;
        noiseScaleZ = 1;
        maxSpeed =2;
        maxForce = 0.03;
    
    
        isSelected = false;
        wasVisited = false;
    
        // calcule de la taille du texte
        textFont(f);
        float tw = textWidth(s); 
        float th = f.getSize();
        nameSize = new PVector(tw, th);
      }
    
      String printPos () {
        return "location.x:"+x+ " y:"+y+" z:"+z;
      }
    
      void move() {
        vTheta = noise (-0.0001, 0.0001);
        theta+=vTheta/150;
        if (theta < 0||theta > TWO_PI) {
          vTheta*= -1;
        }
        vPhi = noise (-0.0001, 0.0001);
        phi+=vPhi/150;
        if (phi < 0 ||phi > PI) {
          vPhi*= -1;
        }
        vPhi*=2;
        vTheta*=2;
    
        x = r * sin(phi) * cos(theta);
        y = r * sin(phi) * sin(theta) ;
        z = r * cos(phi);
        location = new PVector(x, y, z);
        velocity.add(acceleration);
        velocity.limit(maxSpeed);
        acceleration.mult(0);
    
    
        /**if (planets != null) {
         for (int i = 0; i < planets.length; i++) {
         planets[i].move();*/
      }
    
      // }
    
      void addSatellites (Sphere [] sats) {
        planets= sats;
        if (sats != null) {
          for (int i = 0; i < sats.length; i++) {
            sats[i].move();
            sats[i].separate(sats);
          }
        }
      }
    
      void display () {
    
        pushMatrix();
        translate(location.x, location.y, location.z);
    
        if (level > 0 ) {
          stroke(strokeColor);
          drawNoisySphere();
        } else {
        }
    
        // println("level"+level);
        if (planets != null) {
          if (level > 0 ) {
            //lignes qui pointent des planets vers le sun
            for (int k = 0; k < planets.length; k++) {
              float x3 = planets[k].location.x;
              float y3 = planets[k].location.y;
              float z3 = planets[k].location.z;
              strokeWeight(1);
              stroke(random (180, 225));  
              line (0, 0, 0, x3, y3, z3);
            }
          }
    
          // dessin des lignes entre sphères
    
          for (int i = 0; i < planets.length; i++) {
            float x1 = planets[i].location.x;
            float y1 = planets[i].location.y;
            float z1 = planets[i].location.z;
    
            int j =1;
            for (j+=i; j<planets.length; j++) {
              float x2 = planets[j].location.x;
              float y2 = planets[j].location.y;
              float z2 = planets[j].location.z;      
              float d= dist(x1, y1, z1, x2, y2, z2);
              if (d<=range) { 
                float a = constrain((range - d)*4, 0, 225);
                stroke(150, a); 
                if (level < 1) {
                  strokeWeight(1);
                } else {
                  strokeWeight(0.5);
                }   
                line(x1, y1, z1, x2, y2, z2);
              }
            }
            planets[i].separate(planets);
            planets[i].display();  
            planets[i].move();
          }
        }
        popMatrix();
        textFont(font);
        textAlign(CENTER);
        pushMatrix();
        noStroke();
        float[] rotations = camera.getRotations();
        translate(x, y - (radius+20), z);
        rotateX(rotations[0]);
        rotateY(rotations[1]);
        rotateZ(rotations[2]);
        noStroke();
        scale(0.5);
        rectMode(CENTER);
        if (level>0) {
          fill(0, 200);
          rect(0, 0, nameSize.x+20, nameSize.y);
          fill(255, 250);
          translate(nameSize.x/50, nameSize.y/3, -10);
          text(name, 0, 0, 0);
        } else {
          fill(0, 10);
          rect(0, 0, nameSize.x+20, nameSize.y);
          fill(255, 250);
          translate(nameSize.x/50, nameSize.y/3, -10);
          text(name, 0, 0, 0);
        }
        popMatrix();
      }
    
    
      void applyForce(PVector force) {
        acceleration.add(force);
      }
    
    
      void satSelect() {
        this.isSelected= true;
        if (level > 1) {
          strokeColor = color(255, 0, 0);
          phiStep = 7;
          thetaStep= 0.05;
          noiseScaleZ=0;
        }
      }
    
      void satDeSelect() {
        this.isSelected = false;
        this.wasVisited = true;
        if (level > 1) {
          strokeColor = color(0, 255, 0);
          phiStep = 5;
          thetaStep= 0.08;
          noiseScaleZ=0;
        }
      }
    
    
      void separate (Sphere[]planets) {
        float desiredDist = radius*6;
        PVector sum = new PVector();
        int count = 0;
        if (planets != null) {
          if (level > 0 ) {
            for (int i = 0; i <planets.length; i++) {
              int j=1;
              for (j+=i; j<planets.length; j++) {
                float d = PVector.dist(planets[i].location, planets[j].location);
                if ((d >0) && (d<desiredDist)) {
                  PVector diff = PVector.sub(planets[i].location, planets[j].location);
                  diff.normalize();
                  diff.div(d);
                  sum.add(diff);
                  count++;
                }
    
                if (count > 0) {
                  sum.div((float)count);
                }
                if (sum.mag() > 0) {
                  sum.setMag(maxSpeed);
                  PVector steer = PVector.sub(sum, velocity);
                  steer.limit(maxForce);
                  applyForce(steer);
                }
              }
            }
          }
        }
      }
    
      void drawNoisySphere() {
        float s = 0;
        float t = 0;
        float lastx = 0;
        float lasty = 0;
        float lastz = 0;
        float noiseScale = noise (random(10)*25);
        while (t < 180) {
          s += phiStep*(radius/150);
          t += thetaStep ;
    
          float radianS = radians(s);
          float radianT = radians(t);
          float thisx = (radius * cos(radianS) * sin(radianT))+ noiseScale; 
          float thisy = (radius * sin(radianS) * sin(radianT))+ noiseScale;
          float thisz = (radius * cos(radianT)) + ((noise(random(10))*25) * noiseScaleZ);
    
          if (lastx != 0) {
            line(thisx, thisy, thisz, lastx, lasty, lastz);
          }
          lastx = thisx;
          lasty = thisy;
          lastz = thisz;
        }
      }
    }
    
    ///////////////////////////////////////////////////////////////////////////
    
    import processing.serial.*;
    import processing.video.*;
    
    class MyMovieClass {
    
      String [] videoList= {"obscurité", "sombre"};
      int targetTime;
      Movie movies[];
    
      MyMovieClass(String [] v) {
        v = videoList ;
    
        Movie movies[]=new Movie[v.length]; 
        /**for (int idx =0; idx< videoList.length; idx++) {
          movies[idx] = new Movie (this, videoList[idx]+".mp4"); // SOMETHING IS WRONG HERE?!
        }*/
      }
    
      void drawMovie() {
    
        if (current != NOMOVIE) {
          image(movies[current], 0, 0);
    
          if (millis() > targetTime) { 
            updateCurrentMovie(NOMOVIE);
            println("Stopping" + current+ " : " + currentMovie);
            stopAll();
          }
        } else {
          // back to interface?!
        }
      }
    
      void playSelectedMovie() {
        current != NOMOVIE;
        movies[current].play();
      }
    
      void movieEvent (Movie m) {
        m.read();
      }
    
      void stopAll() {
        for (Movie m : movies) {
          m.stop();
          m.jump(0);
        }
        targetTime =-1;
      }
      void playOne (int idx) {
        stopAll();
        movies[idx].play();
        delay(20);
        targetTime = 20+millis() + int(movies[idx].duration()*1000);
        println("Time schedule:" + millis()+"->"+targetTime+"msec");
      }
    }
    
  • Dear Kf, I basically a problem with the constructor of my class MyMovieClass line 533, don't know how to solve that now... It's the 1rst time I use the video library !! Thanks for your attention and help. best, l

  • edited July 16

    Ok, I can see now what you mean with testing it before merging it with your project. Do you have a hook to connect the movie to the sphere already? Just curious... but not needed right now...

    Here next is a demo after I adopted the code from the previous post. I removed all the references to serial and any serial processing. Now this is how the demo works. This demo assumes you have three different movies. If you press from 1 to 3, inclusive, you activate a movie. No other movie can be played. However, if you press the button, it will stop playing the movie and it goes back to the idle stage where it can accept a numeric entry to play a movie. Notice that if you let a movie play until the end, it should go back to idle mode. However, letting the movie playing 'till the end might not work 100% correct. The issue is that it seems that the video finishes a second or two faster than sound or so it is my impression with my video samples.

    This demo should get you going to your next step.

    Kf

    //===========================================================================
    // IMPORTS:
    import processing.video.*;
    
    //===========================================================================
    // FINAL FIELDS:
    final int NOMOVIE=-100;
    final int MOVIE1=0;
    final int MOVIE2=1;
    final int MOVIE3=2;
    
    //===========================================================================
    // GLOBAL VARIABLES:
    
    int n=3;
    Movie mov[]=new Movie[n];
    
    Button bStop;
    
    String currentMovie;
    int current=NOMOVIE;  //INIT
    int targetTime=-1;  //For movie to finish playing
    
    //===========================================================================
    // PROCESSING DEFAULT FUNCTIONS:
    
    void setup() {
      size(1280, 720);
      background(0);
    
      // files inside processing folder for this programme
      mov[MOVIE1] = new Movie(this, "mer.mp4");
      mov[MOVIE2] = new Movie(this, "ven.mov");
      mov[MOVIE3] = new Movie(this, "ear.mp4");
    
      updateCurrentMovie(NOMOVIE);  //PROPER init!
    
      bStop = new Button("Stop",width*0.80,height*0.80,width*0.10,height*0.10);
    
    }
    
    void draw() {
    
      if (current!=NOMOVIE) {
        //if (mov[current].available())    ##### IMPORTANT: Don't do this... in Win10, it was blocking the video
        image(mov[current], 0, 0);
    
        //DETECT when a movie has stopped playing... counter time has expired 
        //so set current index to no movie.
        if (millis()>targetTime) {
          println("Stopping "+current+": "+currentMovie);
          updateCurrentMovie(NOMOVIE);
          stopAll();
        }
      } else {
        background(0);
      }
    
      bStop.Draw();
    }
    
     void keyReleased() {
    
      if (key>='1' && key<=('1'+n-1)) {   
    
        int[] sensors=new int[n];
        for (int i=0; i<n; i++)
          sensors[i]=0;
    
        sensors[key-'1']=1;
        processInputData(sensors);
      } else {
        println("Nothing to do");
      }
    }
    
    void mouseReleased(){
    
      if(bStop.MouseIsOver()==true){
        //NEXT forces the movie currently being played to stop
        targetTime=-1;
      }
    }
    
    
    void movieEvent(Movie m) {
      m.read();
    }
    
    
    
    //===========================================================================
    // OTHER FUNCTIONS:
    
    void stopAll() {
      for (Movie m : mov) {
        m.stop();
        m.jump(0);
      }
      targetTime=-1;
    }
    
    void playOne(int idx) {
      mov[idx].play();
      delay(20);
      targetTime=20+millis()+int(mov[idx].duration()*1000);    //Time in msecs: current mscs + delay + movie's duration 
      println("Time schedule: " + millis() +" -> "+targetTime+" msec");
    
      println("Now playing " + currentMovie);
    }
    
    void processInputData(int[] sensors) {
    
      //ONLY process serial data if no movie is being played
      if (current!=NOMOVIE) {
        println("Action blocked: A movie is still been played!");
        return;
      }
    
      if (sensors[MOVIE1] == 1) {
        updateCurrentMovie(MOVIE1);
      } else if (sensors[MOVIE2] == 1) {
        updateCurrentMovie(MOVIE2);
      } else if (sensors[MOVIE3] == 1) {
        updateCurrentMovie(MOVIE3);
      } else {
        updateCurrentMovie(NOMOVIE);
        println("Received data: Nothing to do (" + currentMovie+")");
      }
    
      if (current!=NOMOVIE)
        playOne(current);
    }
    
    void updateCurrentMovie(int c) {
      current=c;
      currentMovie = current==NOMOVIE?" No movie selected":"movie"+(current+1);
      surface.setTitle(currentMovie);
    }
    
    
    // =============================================================================
    class Button {
      String label;
      float x;      
      float y;    
      float w;    
      float h;    
    
      // constructor
      Button(String labelB, float xpos, float ypos, float widthB, float heightB) {
        label = labelB;
        x = xpos;
        y = ypos;
        w = widthB;
        h = heightB;
      }
    
      void Draw() {
        fill(218);
        stroke(141);
        rect(x, y, w, h, 10);
        textAlign(CENTER, CENTER);
        fill(0);
        text(label, x + (w / 2), y + (h / 2));
      }
    
      boolean MouseIsOver() {
        if (mouseX > x && mouseX < (x + w) && mouseY > y && mouseY < (y + h)) {
          return true;
        }
        return false;
      }
    }
    
  • edited June 13

    Dear Kf, Thank you very much for taking some time to help me :) I have implemented your code in my sketch, but I still need to find a way to play the videos when I press on a sphere. I'll try it later on today. If you have any idea I'd be glad to hear about it! I thought about comparing the names of the spheres to the names of the videos (they are the same) to check out if I play the right video...?

  • Dear Kf, I tried to implement your code, but is there a simpler way to compare my movies[idx] to my sphere number? In your code you update movies according to the sensors idx, but I have 28 videos to load/play ... If I click on my sphere and idx= sphere number then play movies[idx] ?! Hope it's clear?!!

  • Dear Kf,

    Here is the code I've written, but I still don't use a currentMovie and when The mouse is not over a button the image of the last video remain as the background. Should I put everything in a mouseReleased function?! Thank you very much in advance for your help!

    import processing.video.*;
    String [] videoList= {"obscurité", "sombre", "Romain"};
    Movie [] movies= new Movie[videoList.length];
    int idx; // index of the videos
    Button [] buttons = new Button [3];
    Button buttonStop; 
    Button currentButton;
    
    void setup() {
      size(1920, 1080);
      background(0);
    
    
      // Load the videos 
      for (int idx = 0; idx< videoList.length; idx++) {
        movies[idx] = new Movie (this, videoList[idx]+".mp4");
        movies[0].stop();
        currentButton = buttons[0];
      }
    
      buttons[0] = new Button("obscurité", width*0.40, height*0.80, width*0.10, height*0.10, color(255, 0, 0), 0);
      buttons[1] = new Button("sombre", width*0.20, height*0.80, width*0.10, height*0.10, color(0, 255, 0), 1);
      buttons[2] = new Button("Romain", width*0.60, height*0.80, width*0.10, height*0.10, color(0, 0, 255), 2);
      buttonStop = new Button("stop", width*0.80, height*0.80, width*.10, height*0.10, color(127, 0, 127),-1);
    }
    
    
    void draw() {
    
      for (int idx = 0; idx <buttons.length; idx++) {
        if (buttons[idx].mouseIsOver()==true) {
    
          if (buttons[idx].label.equals(videoList[idx]) ==  true) {
           delay(20);
           movies[idx].play();
           currentButton = buttons[idx];
    
          } else {
    
             movies[idx].stop();
            background(0);
    
          } 
          image(movies[idx], 0, 0, width, height);
          println("play video :"+ idx);
        } else if (buttonStop.mouseIsOver() == true) { 
    
          movies[idx].stop();
          background(0);
        }
    
        for (int i = 0; i <buttons.length; i++) {
          buttons[i].buttonShape();
          buttonStop.buttonShape();
        }
      }
    }
    void movieEvent(Movie m) {
      m.read();
    }
    
    class Button {
      String label;
      float x;
      float y;
      float w;
      float h;
      color c;
      int currentButton;
    
      Button(String labelB, float xpos, float ypos, float widthB, float heightB, color col, int currentB ) {
        label = labelB;
        x = xpos;
        y = ypos;
        w = widthB;
        h = heightB;
        c = col;
        currentButton = currentB;
      }    
    
      void buttonShape() {  
        noStroke();
        fill(c);
        rect(x, y, w, h,10);
        textAlign(CENTER, CENTER);
        fill(255);
        textSize(25);
        text(label, x+(w/2), y+(h/2));
      }
      boolean mouseIsOver() {
        if (mouseX > x && mouseX < (x+w) && mouseY > y && mouseY < (y+h)) {
          return true;
        }
        return false;
      }
    }
    
  • edited July 16 Answer ✓

    Some comments:

    The class Button has a member field called currentButton. What is the purpose of that field? You should name this variable based on its functionality. Maybe you meant buttonID?

    Now, you have also a currentButton. I will recommend not to use it as you are right now. Instead, keep a variable that remembers what movie is being played right now.

    This last generates a new question. What is the purpose of your stop button? I can see that you start playing the movie when the mouse is on top of the button. Should the movie stop playing when the mouse is not hovering on top of the button?

    The mouse is not over a button the image of the last video remain as the background

    Modified version below.

    ******* EDITED

    I think the stop button shouldamke sure all the movies call the stop function so they are all rewind and ready to start playing from the start.... it should be an easy implementation below if this is the desired behavior.

    Kf

    import processing.video.*;
    
    final String M1="movie1.mp4";
    final String M2="movie2.mov";
    final String M3="movie3.mp4";
    
    final int NOMOVIE=PApplet.MAX_INT;
    
    String [] videoList= {M1, M2, M3};
    Movie [] movies= new Movie[videoList.length];
    int idx; // index of the videos
    Button [] buttons = new Button [3];
    Button buttonStop; 
    
    int currentMovie=NOMOVIE;
    
    void setup() {
      size(1920, 1080);
      background(0);
    
    
      // Load the videos 
      for (int idx = 0; idx< videoList.length; idx++) {
        movies[idx] = new Movie (this, videoList[idx]);
        movies[0].stop();
      }
    
      buttons[0] = new Button(M1, width*0.40, height*0.80, width*0.10, height*0.10, color(255, 0, 0), 0);
      buttons[1] = new Button(M2, width*0.20, height*0.80, width*0.10, height*0.10, color(0, 255, 0), 1);
      buttons[2] = new Button(M3, width*0.60, height*0.80, width*0.10, height*0.10, color(0, 0, 255), 2);
      buttonStop = new Button("stop", width*0.80, height*0.80, width*.10, height*0.10, color(127, 0, 127), -1);
    }
    
    
    void draw() {
    
      background(0);
      currentMovie=NOMOVIE;
    
      for (int idx = 0; idx <buttons.length; idx++) {
    
        if (buttons[idx].mouseIsOver()==true) {
    
          if (idx!=currentMovie && currentMovie!=NOMOVIE) {
            // ** EITHER  [Different behavior]       
            movies[currentMovie].pause();   //OPTION 1: 
            //movies[currentMovie].stop();  //OPTION 2:
          }
          currentMovie=idx;
          movies[currentMovie].play();
        }
      }
    
      if (currentMovie!=NOMOVIE) {
        image(movies[currentMovie], 0, 0, width, height);
      } else {
        for (int idx = 0; idx <movies.length; idx++) {
          movies[idx].pause();
        }
      }
    
    
      if (buttonStop.mouseIsOver() == true) { 
    
        if (currentMovie!=NOMOVIE) {
          movies[currentMovie].stop();
          currentMovie=NOMOVIE;
        }
      }
    
      for (int i = 0; i <buttons.length; i++) {
        buttons[i].buttonShape();
        buttonStop.buttonShape();
      }
    }
    
    void movieEvent(Movie m) {
      m.read();
    }
    
    class Button {
      String label;
      float x;
      float y;
      float w;
      float h;
      color c;
      int id;
    
      Button(String labelB, float xpos, float ypos, float widthB, float heightB, color col, int anID ) {
        label = labelB;
        x = xpos;
        y = ypos;
        w = widthB;
        h = heightB;
        c = col;
        id = anID;
      }    
    
      void buttonShape() {  
        noStroke();
        fill(c);
        rect(x, y, w, h, 10);
        textAlign(CENTER, CENTER);
        fill(255);
        textSize(25);
        text(label, x+(w/2), y+(h/2));
      }
      boolean mouseIsOver() {
        if (mouseX > x && mouseX < (x+w) && mouseY > y && mouseY < (y+h)) {
          return true;
        }
        return false;
      }
    }
    
  • Dear Kfrajer, Thank you so much!! Your code works perfectly and does exactly what I wanted that is to say as you suggest : " the movie stop playing when the mouse is not hovering on top of the button" What didn't work with my code. I understand the purpose and advantage to comprae the idx with the currentMovie and not comparing the string labels of the buttons with the names of the movies.

    The only thing I don't understand and don't have a clue about is this line ?! : final int NOMOVIE=PApplet.MAX_INT; I it a practical way to use this vide oplayer later as a class inside a longer sketch?! Thanks again for your work and patience.

  • What didn't work with my code.

    I think one of the reason is that you had everything inside the for loop. Also, you addressed the action when you were on top of the button but you didn't address the action when the mouse was not on any button, or you will probably doing it in an ill-constructed else statement. I just rearrange what you had. I used the indes instead bc it is more clear to me.

    final int NOMOVIE=PApplet.MAX_INT is a way to define a reference value in my sketch. Every sketch in Processing extends from the PApplet class and in the process, your sketch inherits functionalities. This is the reason you can draw an ellipse or access mouse event actions, for example. PApplet also has access to some constants like the max number an integer variable can handle. You can access this info in different ways. For example, from the java.lang.Integer class:https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html

    However, I just stick to what Processing offers.

    Kf

  • Thank you very much Kfrajer for the explanations and the link to the doc, I really appreciate your help! Here is the videoPlayer implemented and ready to use inside my main sketch (using PApplet ;))):

    import processing.video.*;
    Video_Player players;
    
    void setup() {
      size(1920, 1080);
      background(0);
      players = new Video_Player(this);
    }
    void draw() {
    
    background(0);
    players.pressed(); 
    } 
    void movieEvent(Movie m) {
      m.read();
    }
    
    //////////////////////////////////////////////////////////////////////////
    
    class Video_Player {
    
      final String M1="obscurité.mp4";
      final String M2="sombre.mp4";
      final String M3="Romain.mp4";
    
      final int NOMOVIE=PApplet.MAX_INT;
    
      String [] videoList= {M1, M2, M3};
      Movie [] movies= new Movie[videoList.length];
      Movie  movie;
      int idx; // index of the videos
      Button [] buttons = new Button [3];
      Button buttonStop; 
    
      int currentMovie=NOMOVIE;
    
      Video_Player(PApplet app) {
    
        // Load the videos 
        for (int idx = 0; idx< videoList.length; idx++) {
          movies[idx] = new Movie (app, videoList[idx]);
          movies[0].stop();
        }
    
        buttons[0] = new Button(M1, width*0.40, height*0.80, width*0.10, height*0.10, color(255, 0, 0), 0);
        buttons[1] = new Button(M2, width*0.20, height*0.80, width*0.10, height*0.10, color(0, 255, 0), 1);
        buttons[2] = new Button(M3, width*0.60, height*0.80, width*0.10, height*0.10, color(0, 0, 255), 2);
        buttonStop = new Button("stop", width*0.80, height*0.80, width*.10, height*0.10, color(127, 0, 127), -1);
      }
      void pressed() {
    
        currentMovie=NOMOVIE;
    
        for (int idx = 0; idx <buttons.length; idx++) {
    
          if (buttons[idx].mouseIsOver()==true) {
    
            if (idx!=currentMovie && currentMovie!=NOMOVIE) {
              // ** EITHER  [Different behavior]       
              // movies[currentMovie].pause();   //OPTION 1: 
              movies[currentMovie].stop();  //OPTION 2:
            }
            currentMovie=idx;
            movies[currentMovie].play();
          }
        }
    
        if (currentMovie!=NOMOVIE) {
          image(movies[currentMovie], 0, 0, width, height);
        } else {
          for (int idx = 0; idx <movies.length; idx++) {
            movies[idx].pause();
          }
        }
    
    
        if (buttonStop.mouseIsOver() == true) { 
    
          if (currentMovie!=NOMOVIE) {
            movies[currentMovie].stop();
            currentMovie=NOMOVIE;
          }
        }
    
        for (int i = 0; i <buttons.length; i++) {
          buttons[i].buttonShape();
          buttonStop.buttonShape();
        }
      }
    }
    
    /////////////////////////////////////////////////////////////////////////// 
    
     class Button {
      String label;
      float x;
      float y;
      float w;
      float h;
      color c;
      int id;
    
     Button(String labelB, float xpos, float ypos, float widthB, float heightB, color col, int anID ) {
        label = labelB;
        x = xpos;
        y = ypos;
        w = widthB;
        h = heightB;
        c = col;
        id = anID;
      }    
    
      void buttonShape() {  
        noStroke();
        fill(c);
        rect(x, y, w, h, 10);
        textAlign(CENTER, CENTER);
        fill(255);
        textSize(25);
        text(label, x+(w/2), y+(h/2));
      }
      boolean mouseIsOver() {
        if (mouseX > x && mouseX < (x+w) && mouseY > y && mouseY < (y+h)) {
          return true;
        }
        return false;
      }
    }
    
  • I won't be able to run your code but until later today to see the difference, if any. The main sketch refers to selecting the spheres in 3D space? What have you implemented so far?

    Kf

  • Dear Kfrajer no problem, the code run properly Tomorrow I'll connect it with the main sketch that refers to spheres in 3D space... Today I tried to fix the problem of distance between the spheres. Most of the examples are the same bouncing balls in a square 3d space thatdoesn't correspond tomine, but still it's a good base to start with. See you then and thanks a lot for your feedback. best wishes, lm

  • Small change after revising my prev post. Lines 44 to 48 are not needed... they are indeed not effective. Removing those lines will not change the current program functionality. On a side note, the stop button does not have a clear function in your sample sketch. I suppose you are only interested in the functionality of playing movies only when hovering on a button as this can be applied to your spheres.

    Related to the main sketch with the noisy spheres, I notice that sometimes I get red or green spirals in some spheres. Should all the spheres react in the same way?

    Kf

Sign In or Register to comment.