Second video won't play after first video

So I have a basic understanding of how Processing and coding works and this project is partially based on another person’s work.

The problem I’m having is that after the first video is finished playing I can’t play a second video. This may be because my code is not working as intended for I want the “player” to be able to either press ‘F’ to play ending 1 or after a certain amount of time has passed after the first video has ended and ending 1 haven’t been played, the ending 2 plays automatically.

What should I change or add to the code to get it to work?

import processing.video.*;
int timer;

Movie [] mov = new Movie [3];

Boolean playMovie0 = true;
Boolean playMovie1 = false;
Boolean playMovie2 = false;

void setup (){

  mov [0] = new Movie (this, "movie 1.mp4");
  mov [1] = new Movie (this, "ending 1.mp4");
  mov [2] = new Movie (this, "ending 2.mp4");

  mov[0].play();
}

void draw (){
  if (playMovie0 == true){
    image(mov[0], 0, 0, width, height);

    if (mov[0].time() >= mov[0].duration()){
      mov[0].stop();
      playMovie0 =false;
    }
    if (keyPressed) {
    if (key == 'f' || key == 'F' && (mov[0].time() >= mov[0].duration()) && (playMovie2 = false)) {
        playMovie1 = true;
        mov[1].play();
        image(mov[1], 0, 0, width, height);
      } else if ((mov[0].time() >= mov[0].duration()) && (millis() - timer >= 10000) && (playMovie1 = false)){
        playMovie2 = true;
        mov[2].play();
        image(mov[2], 0, 0, width, height);
      }
    }
  }
}

void movieEvent (Movie m){
  m.read();
}

Hi! I see the problem - you need to be aware that draw is a loop that starts from the top every frame, and it won’t continue from where it left. So once playMovie0 is set to false, the entire block will be skipped and nothing will happen.

But in general I would suggest to rework on the whole structure and starting from something even simpler. For example, can you make them play sequentially like one after the other?

3 Likes

In addition to what @micuat said, maybe use movie.isPlaying() rather than checking the time - that may be buggy in some situations.

And as an aside, you almost certainly want to use boolean rather than Boolean - that can lead to interesting bugs occasionally - you don’t need a Boolean object here.

So I reworked and redid practically the whole code and took your advice into consideration and created a code that succeeded in doing what I wanted.

Thank you for your advice

import processing.video.*;

Movie theMov; 

int timer;
int Q;
int W;
int A;
int B;

boolean Vid1 = true;
boolean Vid2 = false;
boolean Vid3 = false;

Movie Video1; 
Movie Video2; 
Movie Video3;

void setup(){
  size(1280,720);
  Video1 = new Movie (this, "movie 1.mp4");
  Video2 = new Movie (this, "ending 1.mp4");
  Video3 = new Movie (this, "ending 2.mp4");
  Video1.play();
}

void draw(){
 image(Video1, 0, 0, width, height);
 if (Video1.time() >= 10.4) { // use println(Video1.time()); to see the first video's duration and replace in this case 10.4 with the duration number your video has
      Video1.stop();
      Vid1 =false;
      println(5);
      Q=1;
 } if ((Q==1) && (W==1) && (B<1)){
     Vid2 = true;
     Video2.play();
     image(Video2, 0, 0, width, height);
     A=1;
   } else if ((Q==1) && (millis() - timer >= 20000) && (A<1)){ //Change the number at the timer accordingly to the duration of the beginning video plus the amount of "wait time" you want before this set of code to trigger
     Vid3 = true;
     Video3.play();
     image(Video3, 0, 0, width, height);
     B=1;
 }
}

void keyPressed() {
  if ((key == 'f' || key == 'F') && (Q==1)) {
    W = 1 ;
    println(1);
  }
}

void movieEvent(Movie m) { 
  m.read();
}

glad that you figured it out!

however I see some room for improvement. it might help drawing a diagram to understand the transition

in this case I would keep all the states as one variable - not a boolean but enum would be good to keep track on what is happening. Perhaps something like this:

enum State {
  INIT,VIDEO1_PLAYING,VIDEO1_ENDED
};

State state = State.INIT;

void setup() {
}

void draw() {
  // if([video1 is ended])
  //   state = State.VIDEO01_ENDED;
  
  switch(state) {
    case INIT:
    state = State.VIDEO1_PLAYING;
    // play video
    break;

    case VIDEO1_PLAYING:
    // draw it
    break;

    case VIDEO1_ENDED:
    // do what you need next
    break;
  }
}
1 Like

I agree, my code isn’t the most optimal. But in this project, I’ll stick to the boolean method as I, unfortunately, don’t have much more time to work on the code. If I had more time or were to redo the project, I would differently follow your suggestion and try to gain an adequate understanding of how enum works and work with that function instead of boolean.

Again I thank you for your help and suggestions and will keep then in mind in future projects.

1 Like