Saving video from Processing with the jCodec 2.3

In the former post, I have tested using the jCodec 0.1.5 and 0.2.0 to save the Processing screen into an MP4 file. The latest version of jCodec 0.2.3 has, however, changed its functions for the AWT based applications. Here is the new code for Processing to use jCodec 0.2.3 to save any BufferedImage to an external MP4 file.

To use the code, you need to download from the jCodec website the following two jar files and put them into the code folder of your Processing sketch.

  • jcodec-0.2.3.jar
  • jcodec-javase-0.2.3.jar

The following code will write a frame of your Processing screen into the MP4 file for every mouse pressed action.

import processing.video.*;
import java.awt.image.BufferedImage;
import org.jcodec.api.awt.AWTSequenceEncoder;
 
Capture cap;
AWTSequenceEncoder enc;
 
public void settings() {
  size(640, 480);
}
 
public void setup() {
  cap = new Capture(this, width, height);
  cap.start();
  String fName = "recording.mp4";
  enc = null;
  try {
    enc = AWTSequenceEncoder.createSequenceEncoder(new File(dataPath(fName)), 25);
  } 
  catch (IOException e) {
    println(e.getMessage());
  }
}
 
public void draw() {
  image(cap, 0, 0);
}
 
public void captureEvent(Capture c) {
  c.read();
}
 
private void saveVideo(BufferedImage i) {
  try {
    enc.encodeImage(i);
  } 
  catch (IOException e) {
    println(e.getMessage());
  }
}
 
public void mousePressed() {
  saveVideo((BufferedImage) this.getGraphics().getImage());
}
 
public void exit() {
  try {
    enc.finish();
  } 
  catch (IOException e) {
    println(e.getMessage());
  }
  super.exit();
}

To save only the capture image, you can just replace the following saveVideo command.

saveVideo((BufferedImage) cap.getNative());

Save Processing screen as video with jCodec – new

It may not be easy for readers to get the old jcodec-0.1.5.jar for what I have done in the last post. I tried to work out for a newer solution but found that the latest version did change quite a lot. The latest jcodec source is 0.2.0. I built the latest two files for the Processing test

  • jcodec-0.2.0.jar
  • jcodec-javase-0.2.0.jar

You can download a compressed file of the code folder where you can drop and extract inside the Processing sketch folder. The Processing codes also change to reflect the class structure. Here it is.
 

// Save video file
import processing.video.*;
import org.jcodec.api.awt.AWTSequenceEncoder8Bit;
 
import java.awt.image.BufferedImage;
import java.io.File;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.log4j.BasicConfigurator;
 
static Logger log;
Capture cap;
AWTSequenceEncoder8Bit enc;
String videoName;
String audioName;
boolean recording;
 
void setup() {
  size(640, 480);
  background(0);
  log = LoggerFactory.getLogger(this.getClass());
  BasicConfigurator.configure();
  cap = new Capture(this, width, height);
  videoName = "bear.mp4";
  recording = false;
  int fRate = 25;
  frameRate(fRate);
  cap.start();
  try {
    enc = AWTSequenceEncoder8Bit.createSequenceEncoder8Bit(new File(dataPath(videoName)), fRate);
  } 
  catch (IOException e) {
    e.printStackTrace();
  }
}
 
void draw() {
  image(cap, 0, 0);
  if (recording) {
    BufferedImage bi = (BufferedImage) cap.getNative();
    try {
      enc.encodeImage(bi);
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}
 
void captureEvent(Capture c) {
  c.read();
}
 
void mousePressed() {
  recording = !recording;
  log.info("Recording : " + recording);
}
 
void keyPressed() {
  if (keyCode == 32) {
    try {
      enc.finish();
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

Save video in Processing with JCodec

As a side product of current research, I manage to save a Processing screen in an MP4 video file with the use of the JCodec library. Download the former jcodec-0.1.5.jar into the code folder of your Processing sketch. The simplest way is to use the SequenceEncoder class to add a BufferedImage to the MP4 video. Remember to finish the video file before ending.

The following example captures the live video stream from a webcam and outputs to an external MP4 file in the data folder. Use the mouse click to control the recording.

Here is the source code.

import processing.video.*;
import org.jcodec.api.SequenceEncoder;
import java.awt.image.BufferedImage;
import java.io.File;
 
Capture cap;
SequenceEncoder enc;
String videoName;
boolean recording;
 
void setup() {
  size(640, 480);
  background(0);
  cap = new Capture(this, width, height);
  videoName = "bear.mp4";
  recording = false;
  frameRate(25);
  smooth();
  noStroke();
  fill(255);
  cap.start();
  try {
    enc = new SequenceEncoder(new File(dataPath(videoName)));
  } 
  catch (IOException e) {
    e.printStackTrace();
  }
}
 
void draw() {
  image(cap, 0, 0);
  String fStr = nf(round(frameRate));
  text(fStr, 10, 20);
  if (recording) {
    BufferedImage bi = (BufferedImage) this.getGraphics().getImage();
    try {
      enc.encodeImage(bi);
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}
 
void captureEvent(Capture c) {
  c.read();
}
 
void mousePressed() {
  recording = !recording;
  println("Recording : " + recording);
}
 
void keyPressed() {
  if (keyCode == 32) {
    try {
      enc.finish();
    } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }
}

The program also uses the undocumented functions, getGraphics() and getImage() to obtain the raw image of the Processing sketch window.