views:

260

answers:

4

Hello everyone,

I have a Java swing GUI program that renders anywhere between 1 and 25 frames per second. It is only one window and only one panel to which I do all the rendering, e.g. no other Swing components.

I need to be able to produce videos of test runs of my program as it runs. The problem is that regular screen casting tools (e.g. 3rd party apps I start before running my code) often miss some of my frames and I need an accurate video.

I know how to use the Robot class to capture screenshots of my Java window, but I can't possibly be saving them to disk as I run, it will slow everything down too much. Is there a way for me to use the Robot class (or maybe some other piece of code) to create a video of my window on the fly, while running my program?

Thanks!

A: 

If you run your program in Linux, you can take advantage of recordmydesktop. It is one of the better recording programs I have used with controls over the framerate and whatnot.

TheBuzzSaw
Sorry, running under Windows - don't like it very much either :)
Warlax
A: 

Can't you adapt your program to dump the contents of your window after each update along with an accurate timestamp? Then post process these into a movie if you need that.

That will give you full control.

Thorbjørn Ravn Andersen
Thorbjørn, thank you for the quick reply.I was doing that already, but saving a file for every frame is rather slow.
Warlax
It looks like JMF supports encoding several video formats. Might be the way to go to be guaranteed that your video is accurate. http://java.sun.com/javase/technologies/desktop/media/jmf/2.1.1/formats.html
Thorbjørn Ravn Andersen
A: 

If you just want to save the visual changes, you can use some screen capping software:

Open source screenshot capper: http://www.donationcoder.com/Software/Mouser/screenshotcaptor/index.html (or just use plain alt+print screen, ctrl v for each state) Open source video capper: http://camstudio.org/

sibidiba
+2  A: 

You can use ffmpeg wrapper in Java - Xuggler and builtin Java Robot class. Here is sample code with Xuggler.

final Robot robot = new Robot();
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Rectangle screenBounds = new Rectangle(toolkit.getScreenSize());

// First, let's make a IMediaWriter to write the file.
final IMediaWriter writer = ToolFactory.makeWriter("output.mp4");

// We tell it we're going to add one video stream, with id 0,
// at position 0, and that it will have a fixed frame rate of
// FRAME_RATE.
writer.addVideoStream(0, 0,
 FRAME_RATE,
 screenBounds.width, screenBounds.height);

// Now, we're going to loop
long startTime = System.nanoTime();
for (int index = 0; index < SECONDS_TO_RUN_FOR*FRAME_RATE.getDouble(); index++)
{
    // take the screen shot
   BufferedImage screen = robot.createScreenCapture(screenBounds);

   // convert to the right image type
   BufferedImage bgrScreen = convertToType(screen,
   BufferedImage.TYPE_3BYTE_BGR);

   // encode the image to stream #0
   writer.encodeVideo(0,bgrScreen,
   System.nanoTime()-startTime, TimeUnit.NANOSECONDS);
   System.out.println("encoded image: " +index);

   // sleep for framerate milliseconds
  Thread.sleep((long) (1000 / FRAME_RATE.getDouble()));
}
// Finally we tell the writer to close and write the trailer if
// needed
writer.close();

Another option is Screentoaster site - but I'm note sure what frame rate it provide.

cetnar