Help getting all videos in random sequence to fully play

Hi! I am trying to use Processing to make a random video generator, so that every time the program runs, a random video is picked from three different arrays (sort of like a random Choose Your Own Adventure). I have successfully solved this without using arrays, but the addition of arrays has resulted in some glitches. A friend helped me add the seq variable and the timer, but the program only plays two clips at a time, and often cuts off the first video before it has finished. Are there any suggestions as to how to get one video in each of the three arrays to play one after another? Thanks for the help, I only dabble in Processing so I’m limited in my knowledge. Have looked at a lot of other topics, but haven’t found one that’s trying to do the same thing.

import processing.video.*;
 
Movie [] begin = new Movie[3];
Movie [] middle = new Movie[3];
Movie [] end = new Movie[3];
float movieLength;
int timer;
int seq = 0;
int r1, r2, r3;

void setup(){
  size(1280, 720);
  frameRate(30);
  begin[0] = new Movie (this, "begin/A Few Good Men.mov");
  begin[1] = new Movie(this, "begin/Beetlejuice.mov");
  begin[2] = new Movie(this, "begin/Catch me if you can.mov");
  
  middle [0] = new Movie(this, "middle/Inside Out.mov");
  middle [1] = new Movie(this, "middle/Incredibles 2.mov");
  middle [2] = new Movie(this, "middle/Ghostbusters.mov");
  
  end [0] = new Movie(this, "end/Love And Other Drugs.mov");
  end [1] = new Movie(this, "end/The Jackal.mov");
  end [2] = new Movie(this, "end/Manhattan.mov");

  timer = second();
  background(0);
  r1 = int(random(0,2));
  r2 = int(random(0,2));
  r3 = int(random(0,2));
}

void draw(){
    if(seq == 0){
    int m = second() - timer;
    image(begin[r1], 0, 0, 1280, 720);
    begin[r1].play();
    int duration = int(begin[r1].duration());
    if(m >= duration){
      begin[r1].stop();
      print("stopped");
      seq = 1;
      timer = second();
    }
  }
  
  else if (seq == 1){
    int m = second() - timer;
    image(middle[r2], 0, 0, 1280, 720);
    middle[r2].play();
    int duration = int(middle[r2].duration());
    if (m >= duration){
      middle[r2].stop();
      print("stopped");
      timer = second();
      seq = 2;
    }
  }
  else if (seq == 2){
    int m = second() - timer;
    image(end[r3], 0, 0, 1280, 720);
    end[r3].play();
    int duration = int(end[r3].duration());
    if (m >= duration){
      end[r3].stop();
      print("stopped");
      timer = second();
      seq = 0;
    }
  }
}
   
  void movieEvent(Movie m) {
  m.read();
}

Well, if I get it right, you want to build a program that randomly runs one of three videos in a “begin> middle> end” loop sequence, each containing three videos? If so, then perhaps you should consider using a two-dimensional array instead of three individual arrays. It would look something like this:

Movie[][] video = new Movie[3][3];

Given that a two-dimensional array is nothing more than an array of arrays, you might consider that in each “row” of the array you would have a video in each “column”. In this case, there would be 3 videos in each “line”.This way, you can imagine each line containing videos of different categories: row 0 - begin; row 1 - middle; row 2 - end.

Something that could make your life easier and make your code tidier and shorter would be to rename your videos in an orderly way (e.g. by number) and call them all in a for loop.

You could even use an array of Strings to categorize your videos:

String[] movieType = {"begin_", "middle_", "end_"};

inside setup():

  for (int i = 0; i < video.length; i++) {
    for (int j = 0; j < video[i].length; j++) {
      video[i][j] = new Movie(this, movieType[i]+j+".mp4");
    }
  }

You don’t need to have a timer variable, since the Movie class already has a method that returns the current display time of the video: .time(). See Processing’s Movie reference

This is because you have set your random values to an integer between 0 and 2. This will return as possible results: 0 and 1. Using int (…) or (int) … to convert random values does not include the maximum value int defined. Thats why you could only play one of two diferent videos. To fix this you should define it as int rand = int(random(3)) or int rand = round(random(2)) `. See round()

Here’s what i think it should work for you :wink:

import processing.video.*;

String[] movieType = {"begin_", "middle_", "end_"};
int seq, rand;

Movie[][] video = new Movie[3][3];

void setup() {
  size(1280, 720, P2D);
  frameRate(30);

  for (int i = 0; i < video.length; i++) {
    for (int j = 0; j < video[i].length; j++) {
      video[i][j] = new Movie(this, movieType[i]+j+".mp4");
    }
  }
  rand = int(random(3));
  println(movieType[seq]+rand);
  }

void draw() {
  if (video[seq][rand].time() > floor(video[seq][rand].duration())) {
    video[seq][rand].stop();
    seq++;
    rand = int(random(3));
    if (seq > movieType.length-1) seq = 0;
    println(movieType[seq]+rand);
  }

  image(video[seq][rand], 0, 0, width, height);
  video[seq][rand].play();
}
void movieEvent(Movie m) {
  m.read();
}
1 Like

These links could be relevant to your original question:

manipulate consecutive videos - Processing 2.x and 3.x Forum

How to switch between multiple movies?/Play movie after a movie? - Processing 2.x and 3.x Forum

Almost 2/3 down the following link GotoLoop has a hack that you could use to detect when the movie ends playing: Video 1.0.1 - Read a frame from a paused video? - Processing 2.x and 3.x Forum

Kf

2 Likes