Package org.arquillian.extension.recorder.video.desktop.impl

Source Code of org.arquillian.extension.recorder.video.desktop.impl.VideoRecorder$TestTimeoutTask

/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.arquillian.extension.recorder.video.desktop.impl;

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.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

import org.arquillian.extension.recorder.video.Video;
import org.arquillian.extension.recorder.video.VideoConfiguration;
import org.arquillian.extension.recorder.video.VideoType;
import org.jboss.arquillian.core.spi.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
*
* @author <a href="mailto:pmensik@redhat.com">Petr Mensik</a>
*/
class VideoRecorder {

    private static final Logger logger = LoggerFactory.getLogger(VideoRecorder.class);

    public static final int DEFAULT_FRAMERATE = 20;

    public static final int MIN_FRAMERATE = 0;

    public static final int MAX_FRAMERATE = 100;

    private int frameRate = DEFAULT_FRAMERATE;

    private final Dimension screenBounds;

    private volatile boolean running = false;

    private Thread thread;

    private File recordedVideo = null;

    private Timer timer;

    private VideoConfiguration configuration;

    public VideoRecorder(VideoConfiguration configuration) {
        Validate.notNull(configuration, "Video configuration is null!");
        this.configuration = configuration;
        this.frameRate = configuration.getFrameRate();
        screenBounds = Toolkit.getDefaultToolkit().getScreenSize();
    }

    public void startRecording(final File toFile) {
        if (isRecording()) {
            throw new IllegalStateException("Already recording");
        }

        recordedVideo = toFile;

        try {
            recordedVideo.createNewFile();
        } catch (IOException ex) {
            throw new RuntimeException("Unable to create file to which video will be saved: " + recordedVideo.getAbsolutePath());
        }

        running = true;

        thread = new Thread(new Runnable() {
            @Override
            public void run() {

                final IMediaWriter writer = ToolFactory.makeWriter(recordedVideo.getAbsolutePath());
                writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, screenBounds.width / 2, screenBounds.height / 2);

                long startTime = System.nanoTime();

                timer = new Timer();
                timer.schedule(new TestTimeoutTask(), TimeUnit.SECONDS.toMillis(configuration.getTestTimeout()));

                while (running) {
                    BufferedImage bgrScreen = convertToType(getDesktopScreenshot(), BufferedImage.TYPE_3BYTE_BGR);
                    writer.encodeVideo(0, bgrScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);

                    try {
                        Thread.sleep(500 / frameRate);
                    } catch (InterruptedException ex) {
                        logger.error("Exception occured during video recording", ex);
                    }
                    if (!running) {
                        writer.close();
                    }
                }
            }
        });
        thread.start();
    }

    public synchronized Video stopRecording() {
        if (!running) {
            throw new IllegalStateException("It seems you are not recording anything yet. Please call startRecording()");
        }

        running = false;

        try {
            thread.join();
        } catch (InterruptedException ignored) {
            throw new RuntimeException("Unable to stop video recording.");
        }

        timer = null;
        Video video = new DesktopVideo();
        video.setResource(recordedVideo);
        video.setResourceType(VideoType.valueOf(configuration.getVideoType()));
        video.setWidth(screenBounds.width / 2);
        video.setHeight(screenBounds.height / 2);
        return video;
    }

    public int getFrameRate() {
        return frameRate;
    }

    /**
     *
     * @return true if this recording is recording some video right now, false othewise
     */
    public boolean isRecording() {
        return running;
    }

    /**
     *
     * @param frameRate framerate to set has to be between {@link VideoRecorder#MIN_FRAMERATE} and
     *        {@link VideoRecorder#MAX_FRAMERATE} exclusive to take effect.
     */
    public void setFrameRate(int frameRate) {
        if (frameRate > MIN_FRAMERATE && frameRate < MAX_FRAMERATE) {
            this.frameRate = frameRate;
        }
    }

    private BufferedImage convertToType(BufferedImage sourceImage, int targetType) {
        BufferedImage 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 BufferedImage getDesktopScreenshot() {
        try {
            Robot robot = new Robot();
            Rectangle captureSize = new Rectangle(screenBounds);
            return robot.createScreenCapture(captureSize);
        } catch (AWTException e) {
            logger.error("Exception occured while taking screenshot for video record", e);
            return null;
        }
    }

    private class TestTimeoutTask extends TimerTask {

        @Override
        public void run() {
            stopRecording();
            cancel();
        }
    }

}
TOP

Related Classes of org.arquillian.extension.recorder.video.desktop.impl.VideoRecorder$TestTimeoutTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.