Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package exe.media;
- import java.awt.Rectangle;
- import java.awt.Robot;
- import java.awt.Toolkit;
- import java.awt.image.BufferedImage;
- import java.io.File;
- import java.text.SimpleDateFormat;
- import java.util.concurrent.TimeUnit;
- import javax.sound.sampled.AudioFormat;
- import javax.sound.sampled.AudioSystem;
- import javax.sound.sampled.DataLine;
- import javax.sound.sampled.TargetDataLine;
- import com.xuggle.mediatool.IMediaWriter;
- import com.xuggle.mediatool.ToolFactory;
- import com.xuggle.xuggler.IRational;
- import exe.logger.TimeLookup;
- public class CaptureScreen {
- private static IRational FRAME_RATE = IRational.make(15, 1);
- private static volatile boolean recording = false;
- public synchronized static File captureScreen(String name,
- final int duration) {
- SimpleDateFormat dateFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH.mm.ss");
- final File file = new File(name + "-"
- + dateFormat.format(TimeLookup.getTime()) + ".mp4");
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- // This is the robot for taking a snapshot of the
- // screen. It's part of Java AWT
- 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(file
- .getAbsolutePath());
- // 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);
- AudioFormat format = new AudioFormat(8000.0F, 16, 1, true,
- false);
- writer.addAudioStream(1, 0, 1, (int) format.getSampleRate());
- TargetDataLine line = getTargetDataLineForRecord(format);
- final int frameSizeInBytes = format.getFrameSize();
- final int bufferLengthInFrames = line.getBufferSize() / 8;
- final int bufferLengthInBytes = bufferLengthInFrames
- * frameSizeInBytes;
- final byte[] buf = new byte[bufferLengthInBytes];
- final long startTime = System.nanoTime();
- new Thread(new Runnable() {
- @Override
- public void run() {
- long lastTime = startTime;
- double ns = 1000000000 / FRAME_RATE.getDouble();
- double delta = 0.0D;
- double FRAMES_TAKEN = 0.0D;
- while (FRAMES_TAKEN < (duration * FRAME_RATE
- .getDouble())) {
- long now = System.nanoTime();
- delta += (now - lastTime) / ns;
- lastTime = now;
- if (delta >= 1.0D) {
- BufferedImage screen = robot
- .createScreenCapture(screenBounds);
- BufferedImage bgrScreen = convertToType(
- screen,
- BufferedImage.TYPE_3BYTE_BGR);
- writer.encodeVideo(0, bgrScreen,
- System.nanoTime() - startTime,
- TimeUnit.NANOSECONDS);
- FRAMES_TAKEN++;
- delta -= 1.0D;
- }
- }
- recording = false;
- }
- }).start();
- recording = true;
- while (recording) {
- int numBytesRead = 0;
- numBytesRead = line.read(buf, 0, bufferLengthInBytes);
- int numSamplesRead = numBytesRead / 2;
- short[] audioSamples = new short[numSamplesRead];
- if (format.isBigEndian()) {
- for (int i = 0; i < numSamplesRead; i++) {
- audioSamples[i] = (short) ((buf[2 * i] << 8) | buf[2 * i + 1]);
- }
- } else {
- for (int i = 0; i < numSamplesRead; i++) {
- audioSamples[i] = (short) ((buf[2 * i + 1] << 8) | buf[2 * i]);
- }
- }
- writer.encodeAudio(1, audioSamples, System.nanoTime()
- - startTime, TimeUnit.NANOSECONDS); // CaptureScreen.java:118
- }
- writer.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }).start();
- return file;
- }
- /**
- * Convert a {@link BufferedImage} of any type, to {@link BufferedImage} of
- * a specified type. If the source image is the same type as the target
- * type, then original image is returned, otherwise new image of the correct
- * type is created and the content of the source image is copied into the
- * new image.
- *
- * @param sourceImage
- * the image to be converted
- * @param targetType
- * the desired BufferedImage type
- *
- * @return a BufferedImage of the specifed target type.
- *
- * @see BufferedImage
- */
- 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 TargetDataLine getTargetDataLineForRecord(AudioFormat format) {
- TargetDataLine line;
- final DataLine.Info info = new DataLine.Info(TargetDataLine.class,
- format);
- if (!AudioSystem.isLineSupported(info)) {
- return null;
- }
- // get and open the target data line for capture.
- try {
- line = (TargetDataLine) AudioSystem.getLine(info);
- line.open(format, line.getBufferSize());
- } catch (final Exception ex) {
- return null;
- }
- return line;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement