I got this code working, but I want to improve it with 3 points, but unable to.

Hello,

The code below works perfectly, but I want to improve it. I'm learning Processing in my free time just for the fun.

My goal is to record for x amount of seconds, so if I say 10 seconds, it will stop recording after 10 seconds. Then I'll save the pictures as the jpeg files. I wanted this too happen offscreen, which I've done by using setLocation. My second problem is that I want to see the movie, after those 10 seconds. So I want it to record for 10 seconds, without any interface. Then I want it to show me that 10 seconds video of earlier. And I want to save it as a mp4 as well, but at the moment I did it with jpeg files, so I can later make it to mp4.

If people can help me improving it with:
- Stop recording after 10 seconds
- Show video after those 10 seconds.
- Save video as mp4 instead of many many pictures?

Thanks in advance!

import processing.video.*;
import processing.opengl.*;

Capture cam;

void setup() {
  size(640, 480, OPENGL);
  frame.setLocation(10000,0);

  String[] cameras = Capture.list();

  if (cameras.length == 0) {
    println("There are no cameras available for capture.");
    exit();
  } else {
    println("Available cameras:");
    for (int i = 0; i < cameras.length; i++) {
      println(cameras[i]);
    }

    // The camera can be initialized directly using an 
    // element from the array returned by list():
    cam = new Capture(this, cameras[0]);
    cam.start();     
  }      
}

void draw() { 
if (cam.available() == true) { 
  cam.read(); }
  image(cam, 0, 0);
  // The following does the same, and is faster when just drawing the image 
  // without any additional resizing, transformations, or tint. 
  //set(0, 0, cam);
  saveFrame("output-####.jpeg");
}
Tagged:

Answers

  • You can use millis() and record inside block:

    if (millis()<10000){
    //saving frames
    }
    

    It is in milliseconds, so it is 10k. About movie.. Usually you export frames and then use Movie Maker tool to create a video out of image sequence, so I'm not sure how to achieve what you want in code, I can think only of showing all the pictures one by one.

  • Can I use Processing to show the pictures one by one? With 30FPS? If that's possible, that would of course save me from troubles, then there's no need to save it as a video, but I can use the pictures so later I can indeed use Movie Maker.

    I tried using your code, but this doesn't work, unsure what you mean with blocks though. Thanks for helping me though, Ater, I appreciate it.

    import processing.video.*;
    import processing.opengl.*;
    
    Capture cam;
    
    void setup() {
      size(640, 480, OPENGL);
      frame.setLocation(10000,0);
    
      String[] cameras = Capture.list();
    
      if (cameras.length == 0) {
        println("There are no cameras available for capture.");
        exit();
      } else {
        println("Available cameras:");
        for (int i = 0; i < cameras.length; i++) {
          println(cameras[i]);
        }
    
        // The camera can be initialized directly using an 
        // element from the array returned by list():
        cam = new Capture(this, cameras[0]);
        cam.start();     
      }      
    }
    
    void draw() { 
    if (cam.available() == true) { 
      cam.read(); }
      image(cam, 0, 0);
      // The following does the same, and is faster when just drawing the image 
      // without any additional resizing, transformations, or tint. 
      //set(0, 0, cam);
      if (millis()<4000){
      saveFrame("output-####.jpeg");
      }
    }
    
  • edited March 2016

    OK, first I think this should work, if not tell what exactly does not work:

     if (millis()<4000){
      saveFrame("output-####.jpeg");
      }
    

    use println(millis()); to see if you fit in the range.

    Second - yes, you can use saved pictures and show them one by one, you can use frameRate(30); in setup to set fps, then you need to have array of PImage[] imgs and load your saved images, something like:

    for (int i= 0; i < imgs.length; i++){
    String num = nf(i, 4);
    imgs[i] = loadImage("output-"+ num + ".jpeg");
    }
    

    and you can use it to show images in draw:

    image(imgs[n], 0, 0);
    n+=1; // each frame next image.
    

    However there's a problem here - loading images takes time and you can't do it each frame, you need to create a function that will run once after you finished saving frames and load images inside it. Here's a good tutorial explaining timing: https://forum.processing.org/two/discussion/8084/how-do-i-display-a-message-for-a-few-seconds#latest If that is not clear for you, please ask for more help.

  • edited March 2016

    Alright, I tried using millis but couldn't get that to work, so I found a different solution. I know that the cam records with 30fps, so I know if I want to record for 10 second I'd have 300 frames. So I used FrameCount to quit the program.

    import processing.video.*;
    import processing.opengl.*;
    
    Capture cam;
    
    void setup() {
      size(640, 480, OPENGL);
      frame.setLocation(10000,0);
      frameRate(30);
    
      String[] cameras = Capture.list();
    
      if (cameras.length == 0) {
        println("There are no cameras available for capture.");
        exit();
      } else {
        println("Available cameras:");
        for (int i = 0; i < cameras.length; i++) {
          println(cameras[i]);
        }
    
        // The camera can be initialized directly using an 
        // element from the array returned by list():
        cam = new Capture(this, cameras[0]);
        cam.start(); 
      }      
    }
    
    void draw() { 
    if (cam.available() == true) { 
      cam.read(); }
      image(cam, 0, 0);
      // The following does the same, and is faster when just drawing the image 
      // without any additional resizing, transformations, or tint. 
      //set(0, 0, cam);
      if(frameCount < 100){
      saveFrame("output-####.jpeg");
      }
      else 
      {
         cam.stop();
         exit();
      }
    }
    

    Now I still don't get the pictures to work, I tried with the flashy one but failed there already. Thanks for helping me though!

This discussion has been closed.