Title: processing - how can I record,save and play the video in the same processing sketch?
Tags: video;export;processing;movie
Question: I'm already able to record and save the video by pressing a button and pressing the button again to stop recording and export the video. I can play the video if i stop my processing sketch and start it up again. That is because when I'm recording the video in processing and stop the recording, the video file is being made in the data folder but it's not complete yet. Like the size of the video is around 50 bytes and there is no thumbnail visible while my processing sketch is still active. But as soon as i stop my processing sketch the video will be made. Then a thumbnail image will be visible in my folder and the size increases to around 600kb and the file is playable. So i need to stop and restart my sketch to finish the video. Is there any other way to finish my video and being able to play my video back as soon as I'm done recording? So in short i want my sketch to be able to open the webcam image. Record the video and play the video back when i push a button or click the mouse. Would that be possible?
This is the code I have so far:
import com.hamoid.*;
import processing.video.*;
import ddf.minim.*;
Minim minim;
AudioPlayer player;
AudioInput in;
AudioRecorder recorder;
Movie myMovie;
Movie myMovie1;
Movie myMovie2;
Movie myMovie3;
int currentScreen;
int videoCounter = 0;
VideoExport videoExport;
boolean recording = false;
Capture theCap;
Capture cam;
int i = 0;
int countname; //change the name
int name = 000000; //set the number in key's' function
// change the file name
void newFile()
{
countname =( name + 1);
recorder = minim.createRecorder(in, "file/Sound" + countname + ".wav", true);
// println("file/" + countname + ".wav");
void setup() {
size(500,500);
frameRate(30);
noStroke();
smooth();
//myMovie = new Movie(this, "video0.mp4");
//myMovie.loop();
//myMovie1 = new Movie(this, "video1.mp4");
//myMovie1.loop();
//myMovie2 = new Movie(this, "video2.mp4");
//myMovie1.loop();
//myMovie3 = new Movie(this, "video3.mp4");
//myMovie1.loop();
//if (videoCounter &gt;= 1){
//myMovie = new Movie(this, "video0.mp4");
//myMovie.loop();
//}
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[3]); //built in mac cam "isight"
cam = new Capture(this, 1280, 960, "USB-camera"); //externe camera Lex, linker USB
cam.start();
println("Druk op R om geluid en video op te nemen.Druk nog een keer op R om het opnemen te stoppen en druk op S om het op te slaan Druk vervolgens op Z om verder te gaan.");
videoExport = new VideoExport(this, "data/video" + i + ".mp4");
minim = new Minim(this);
player = minim.loadFile("file/Sound1.wav");
// get a stereo line-in: sample buffer length of 2048
// default sample rate is 44100, default bit depth is 16
in = minim.getLineIn(Minim.STEREO, 2048);
// create a recorder that  will record from the input to the filename specified, using buffered recording
// buffered recording means that all captured audio will be written into a sample buffer
// then when save() is called, the contents of the buffer will actually be written to a file
// the file will be located in the sketch's root folder.
newFile();//go to change file name
textFont(createFont("SanSerif", 12));
void draw() {
switch(currentScreen){
case 0: drawScreenZero(); break; //camera
case 1: drawScreenOne(); break; //1 video
case 2: drawScreenZero(); break; //camera
case 3: drawScreenTwo(); break; // 2 video's
case 4: drawScreenZero(); break; //camera
case 5: drawScreenThree(); break; //3 video's
case 6: drawScreenZero(); break; //camera
case 7: drawScreenFour(); break; //4 video's
default: background(0); break;
void mousePressed() {
currentScreen++;
if (currentScreen &gt; 7) { currentScreen = 0; }
void drawScreenZero() {
//println("drawScreenZero camera");
if (cam.available() == true) {
cam.read();
image(cam, 0,0,width, height);
// 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 (recording) {
videoExport.saveFrame();
for(int i = 0; i < in.bufferSize() - 1; i++)
line(i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50);
line(i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50);
if ( recorder.isRecording() )
text("Aan het opnemen...", 5, 15);
text("Druk op R als je klaar bent met opnemen en druk op S om het op te slaan.", 5, 30);
text("Gestopt met opnemen. Druk op R om op te nemen, druk op S om op te slaan.", 5, 15);
void drawScreenOne() {
background(0,255,0);
//fill(0);
//rect(250,40,250,400);
//println("drawScreenOne 1 video");
if (videoCounter &gt;= 1){
myMovie = new Movie(this, "video0.mp4");
myMovie.loop();
image(myMovie, 0,0, (width/2),(height/2));
player.play();
} else if (videoCounter == 0) {
text("geen video", 5, 15);
void drawScreenTwo(){
background(0,0,255);
//println("drawScreenTwo 2 videos");
//triangle(150,100,150,400,450,250);
//image(myMovie, 0,0, (width/2),(height/2));
//image(myMovie1, (width/2),(height/2),(width/2),(height/2));
void drawScreenThree(){
//fill(0);
//rect(250,40,250,400);
background(255,0,0);
println("drawScreenThree 3 videos");
//image(myMovie, 0,0, (width/2),(height/2));
//image(myMovie1, (width/2),(height/2),(width/2),(height/2));
//image(myMovie, (width/2),0, (width/2),(height/2));
void drawScreenFour(){
//triangle(150,100,150,400,450,250);
background(0,0,255);
//println("drawScreenFour 4 videos");
//image(myMovie, 0,0, (width/2),(height/2));
//image(myMovie1, (width/2),(height/2),(width/2),(height/2));
//image(myMovie, (width/2),0, (width/2),(height/2));
//image(myMovie1, 0,(height/2),(width/2),(height/2));
void keyPressed() {
if (key == 'r' || key == 'R') {
recording = !recording;
println("Recording is " + (recording ? "ON" : "OFF"));
} else   if (key == 's' || key == 'S') {
i++;
videoExport = new VideoExport(this, "video" + i + ".mp4");
videoCounter++;
println(videoCounter);
//currentScreen++;
//if (currentScreen &gt; 7) { currentScreen = 0; }
} else if (key == 'z' || key == 'Z') {
currentScreen++;
if (currentScreen &gt; 7) { currentScreen = 0; }
void movieEvent(Movie m) {
m.read();
void keyReleased()
if ( key == 'r' )
// to indicate that you want to start or stop capturing audio data, you must call
// beginRecord() and endRecord() on the AudioRecorder object. You can start and stop
// as many times as you like, the audio data will be appended to the end of the buffer
// (in the case of buffered recording) or to the end of the file (in the case of streamed recording).
if ( recorder.isRecording() )
recorder.endRecord();
else
/*#######################################*/
newFile();
/*#######################################*/
recorder.beginRecord();
if ( key == 's' )
// we've filled the file out buffer,
// now write it to the file we specified in createRecorder
// in the case of buffered recording, if the buffer is large,
// this will appear to freeze the sketch for sometime
// in the case of streamed recording,
// it will not freeze as the data is already in the file and all that is being done
// is closing the file.
// the method returns the recorded audio as an AudioRecording,
// see the example  AudioRecorder &gt;&gt; RecordAndPlayback for more about that
name++; //change the file name, everytime +1
recorder.save();
println("Done saving.");
println(name);//check the name
void stop()
// always close Minim audio classes when you are done with them
in.close();
minim.stop();
super.stop();
Comment: Can you please try to narrow your problem down to a [mcve]? You've included a ton of code that's not related to your problem, which makes it very hard to read, which makes it very hard to help you. Try cleaning up your code as much as possible before posting it.

Comment: If i go to the next screen, after I've recorded and exported the video, I'm not able to see the video and as soon as I stop the processing application i get this error: (Processing core video:587): GStreamer-CRITICAL **:
Trying to dispose element Movie Player, but it is in READY instead of the NULL state.
You need to explicitly set elements to the NULL state before
dropping the final reference, to allow them to clean up.
This problem may also be caused by a refcounting bug in the
application or some element.

Here is the accepted answer: Take a look at the reference for the VideoExport library, which is really just one class.
That reference shows us this function:
dispose()
Called automatically by Processing to clean up before shut down
We can then take a look at the source of the VideoExport class to see what that function does:
public void dispose() {
if (ffmpeg != null) {
try {
ffmpeg.flush();
ffmpeg.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (process != null) {
process.destroy();
}
So now we know that the dispose() function is calling flush() on ffmpeg, which is an OutputStream. We also know that the dispose() function is only called at the end of the sketch.
So the first thing I would try is simply calling the dispose() function when you want to finalize the video.
If that doesn't work, or if it causes other Exceptions, then you might want to find a different video library that allows you to save them on command, or you could even create your own using the source of VideoExport as inspiration. There really isn't much to it.
Comment for this answer: Sorry for my late reaction and I'll keep that in mind for future questions. Dispose() stopped the application running but videoExport.dispose() did the trick, thank you for your help.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 2, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2016:00:06/03/16', 'FavoriteCount': None, 'PostTypeId': 1, 'Tags': '<video><export><processing><movie>', 'Title': 'processing - how can I record,save and play the video in the same processing sketch?', 'ViewCount': 1622, 'id': 37609837, 'user_AboutMe': None, 'user_AccountId': 7218842.0, 'user_DisplayName': 'grunter-hokage', 'user_Reputation': 67.0, 'user_Views': 21.0, 'user_id': 5510201.0}}