Problem when making .mp4 from screenshot

126 views
Skip to first unread message

Steven

unread,
Jan 20, 2016, 7:22:18 PM1/20/16
to xuggler-users
Hello,

I have the following problem when trying to convert a buffered image into a string using Base64 encoder; and then from a string back to a buffered image (using base64 decoder). The reason behind this was that I wanted to make screenshots periodically from client, then send it to the server, server then create the .mp4 file.

Following is the test code:

import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;

import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.ICodec;

public class CaptureScreen
{

private static final double FRAME_RATE = 20;
private static final int SECONDS_TO_RUN_FOR = 20;
private static final String outputFilename = "c:/temp/mydesktop.mp4";
private static Dimension screenBounds;

public static void main(String[] args)
{
// let's make a IMediaWriter to write the file.
final IMediaWriter writer = ToolFactory.makeWriter(outputFilename);
screenBounds = Toolkit.getDefaultToolkit().getScreenSize();

// 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, ICodec.ID.CODEC_ID_H264,
screenBounds.width, screenBounds.height);
long startTime = System.nanoTime();
for (int index = 0; index < 100; index++)
{
// take the screen shot
BufferedImage screen = getDesktopScreenshot();
// convert to the right image type
BufferedImage bgrScreen = convertToType(screen,
BufferedImage.TYPE_3BYTE_BGR);

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try
{
ImageIO.write(bgrScreen, "png", baos);
baos.flush();
byte[] imgBytes = baos.toByteArray();
baos.close();
String img = Base64.getEncoder().encodeToString(imgBytes);

byte[] imageAsBytes = Base64.getDecoder().decode(img.getBytes());
ByteArrayInputStream inputStream = new ByteArrayInputStream(imageAsBytes);
BufferedImage bufferedImage = ImageIO.read(inputStream);
BufferedImage original = convertToType(bufferedImage, BufferedImage.TYPE_3BYTE_BGR);

// write image to stream #0
writer.encodeVideo(0, original, System.nanoTime() - startTime,
TimeUnit.NANOSECONDS);
// // sleep for frame rate milliseconds
// try
// {
// Thread.sleep((long) (1000 / FRAME_RATE));
// }
// catch (InterruptedException e)
// {
// // ignore
// }
}
catch (IOException ex)
{
ex.printStackTrace();
}
finally
{
// tell the writer to close and write the trailer if needed
writer.flush();
writer.close(); <= exception happens here.
}
}
}

private static BufferedImage convertToType(BufferedImage sourceImage, int targetType)
{
BufferedImage image;
// if the source image is already the target type, return the source image
if (sourceImage.getType() == targetType)
{
image = sourceImage;
}
// otherwise create a new image of the target type and draw the new image
else
{
image = new BufferedImage(sourceImage.getWidth(),
sourceImage.getHeight(), targetType);
image.getGraphics().drawImage(sourceImage, 0, 0, null);
}
return image;
}

private static BufferedImage getDesktopScreenshot()
{
try
{
Robot robot = new Robot();
Rectangle captureSize = new Rectangle(screenBounds);
return robot.createScreenCapture(captureSize);
}
catch (AWTException e)
{
e.printStackTrace();
return null;
}
}
}

I got exception when closing the writer:

10:25:11.446 [ 3148] ERROR org.ffmpeg [ ] [ ] [mp4 @ 00000000003630F0] no streams
Exception in thread "main" 10:25:11.462 [ 3164] ERROR com.xuggle.xuggler [ ] [ ] Error: could not write header for container (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:827)
10:25:11.462 [ 3164] WARN com.xuggle.xuggler [ ] [ ] writeTrailer() with no matching call to writeHeader() (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:863)
java.lang.RuntimeException: error Operation not permitted, failed to write trailer to c:/temp/mydesktop.mp4
at com.xuggle.mediatool.MediaWriter.close(MediaWriter.java:1306)
at com.saabusa.gator.occ.server.clientrecorder.CaptureScreen.main(CaptureScreen.java:83)

Anybody has a better idea how to approach this?

Thanks.

Ed St Louis

unread,
Jan 21, 2016, 12:49:40 PM1/21/16
to xuggle...@googlegroups.com
I'm not sure what you're specifically doing wrong, but here is some code I wrote that does work:

I just run the main method (ScreenRecordingExample.java) passing in the filename of the video to save. 



--
You received this message because you are subscribed to the Google Groups "xuggler-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to xuggler-user...@googlegroups.com.
To post to this group, send email to xuggle...@googlegroups.com.
Visit this group at https://groups.google.com/group/xuggler-users.
For more options, visit https://groups.google.com/d/optout.



--
Ed St. Louis
Cell: 801-999-8844
Home: 801-964-1855
Reply all
Reply to author
Forward
0 new messages