Search code examples
videoprocessingframe-rate

Framerate() doesn't seem to affect Movie - Processing


This must be something really stupid - so sorry if that's the case :) - but I really have been stuck on the simple issue for a long time now and I can't seem to understand it. Can't find anything on the processing.org documentation or the forum.

So basically, all I am doing is loading a .mp4 Movie, setting the framerate, and setting it to loop(). Everything draws as it should but the only issue is that the .framerate() doesn't seem to affect the Movie itself. Here is my simplified code for understanding:

String urlCam1 = "Something.mp4";
Movie camera1;

Movie currentCam;    

boolean drawNextFrame = false;

void setup() {
    fullScreen();

    camera1 = new Movie(this, urlCam1);  
    camera1.frameRate(1);
    camera1.loop();

    background(0);
}

void draw() {
    if (drawNextFrame) {
        image(currentCam, 0, 0, 100, 100);
        drawNextFrame = false;
    }
}

void movieEvent(Movie m) {
    print("Video Read");
    m.read();
    drawNextFrame = true;
    currentCam = m;
}

You may wonder why I'm using such a weird structure (notably with the currentCam), that's because I am drawing multiple Movies at once. But I have tried the code with only one Movie (as the code represents) but the issue still prevails.

Notice how the camera1.framerate is set to 1 fps. For some reason, this line seems to be ignored even though no errors are given. The movieEvent() isn't called one time per second, but much more, and therefore, the current frame of the video isn't drawn each second also, even though I have explicitly set the framerate of the Movie to 1fps...

Why is that? Am I missing something here?

Thanks in advance ! :)


Solution

  • I was able to reproduce your problem, but not to correct it. After trying very simplified code based on the example in the Processing documentation, I still couldn't make frameRate() work. I even tried different renderers with no discernable results.

    You can still get a similar result with simple techniques. For once, you can count your frames to only update the movie once every couple frames:

    Movie myMovie;
    int frameCounter = 0;
    int framerate = 30;
    int movieFPS = 3;  // the movie will be updated only 3 times per second
    int updateFrame = 1;
    
    void setup() {
      size(200, 200);
      frameRate(framerate);
      updateFrame = framerate / movieFPS;
    
      myMovie = new Movie(this, "SampleVideo_360x240_30mb.mp4");
      myMovie.loop();
    }
    
    void draw() {
      if (frameCounter++ % updateFrame == 0) {
        image(myMovie, 0, 0);
      }
    }
    
    // Called every time a new frame is available to read
    void movieEvent(Movie m) {
      m.read();
    }
    

    What's interesting here is that the sound won't be affected, as the movie is still read at the same speed, just not graphically displayed every frame.

    If you're going for the "webcam" effect, you can randomize the frame count instead of having it update regularly:

    Movie myMovie;
    int frameCounter = 0;
    int framerate = 30;
    int minFramesBetweenUpdate = 10;
    int maxFramesBetweenUpdate = 45;
    int updateFrame = 1;
    
    void setup() {
      size(200, 200);
      frameRate(framerate);
    
      myMovie = new Movie(this, "SampleVideo_360x240_30mb.mp4");
      myMovie.loop();
    }
    
    void draw() {
      if (frameCounter++ > updateFrame) {
        image(myMovie, 0, 0);
        updateFrame = frameCounter + (int)random(minFramesBetweenUpdate, maxFramesBetweenUpdate);
      }
    }
    
    // Called every time a new frame is available to read
    void movieEvent(Movie m) {
      m.read();
    }
    

    The framerate technically doesn't change the speed at which the movie will be displayed, only the number of frames that will be seen in a certain amount of time. A 10 seconds video with different framerates will always play in 10 seconds.

    If you want to change the speed at which the movie is displayed, you need to use something like myMovie.speed(0.5);. The speed at which the movie is played will change how long it takes to run it. If your movie has sound, playing it at more than 1.0 speed will "chipmunk" the sound, for an example.

    Let me know if I can help with something. And have fun!