agomezmoron / screen-recorder

Java screen recorder library
MIT License
21 stars 14 forks source link

VideoRecord is not capturing enough frames and the video file generated is very short #14

Open python012 opened 1 year ago

python012 commented 1 year ago

Hi, I find that in Windows 10(I didn't try other OS), the VideoRecord is not capturing enough frames, I added some debug code and found that, looks Thread.sleep(VideoRecorderConfiguration.getCaptureInterval()) in VideoRecord doesn't work as expected.

My test code:

public class TestDemo {
    public static void main(String[] args) throws InterruptedException, MalformedURLException {
        System.out.println("Hello World!");
        VideoRecorderConfiguration.wantToUseFullScreen(true);
        VideoRecorderConfiguration.setVideoDirectory(new File(Paths.get("video").toAbsolutePath().toString()));
        VideoRecorderConfiguration.setKeepFrames(false);
        VideoRecorderConfiguration.setCaptureInterval(50);
        VideoRecorder.start("debug");
        TimeUnit.SECONDS.sleep(5);
        VideoRecorder.stop();
    }
}

It generated a video that only has 1 second. I add a few debug code in VideoRecord class like below, to make it show the real interval between each capturing:

            public void run() {
                Robot rt;
                ScreenCapture capture;
                int now = 999999;
                try {
                    rt = new Robot();
                    do {
                        capture = new ScreenCapture(rt.createScreenCapture(new Rectangle(
                                VideoRecorderConfiguration.getX(), VideoRecorderConfiguration.getY(),
                                VideoRecorderConfiguration.getWidth(), VideoRecorderConfiguration.getHeight())));

                        VideoRecorderEventObject videoRecorderEvObj = new VideoRecorderEventObject (this,capture);

                        //Exploring all the listeners
                        for(VideoRecorderEventListener vr : listeners){

                            //Creating the object that will be sent
                            VideoRecorderEventListener listener = (VideoRecorderEventListener) vr;
                            listener.frameAdded(videoRecorderEvObj);
                        }

                        frames.add(VideoRecorderUtil.saveIntoDirectory(capture, new File(
                                VideoRecorderConfiguration.getTempDirectory().getAbsolutePath() + File.separatorChar
                                        + videoName.replace(".mov", ""))));
                        System.out.println("Frame: " + frames.size());
                        System.out.println(new SimpleDateFormat("HH:mm:ss.SSS").format(new java.util.Date()));
                        if (now == 999999) {
                            now =  Integer.parseInt(new SimpleDateFormat("SSS").format(new java.util.Date()));
                        } else {
                            int newTime = Integer.parseInt(new SimpleDateFormat("SSS").format(new java.util.Date()));
                            if (newTime < now) {
                                newTime += 1000;
                            }
                            System.out.println("Interval: " + abs(newTime - now));
                            now = newTime;
                        }
                        Thread.sleep(VideoRecorderConfiguration.getCaptureInterval());
                        System.out.println();
                    } while (recording);
                } catch (Exception e) {

                    System.out.println(e.getStackTrace());
                    recording = false;
                }

Then I ran the test, and see the logs

...
Frame: 23
16:06:25.215
Interval: 162

Frame: 24
16:06:25.369
Interval: 154

Frame: 25
16:06:25.564
Interval: 195

Frame: 26
16:06:25.729
Interval: 165

Frame: 27
16:06:25.950
Interval: 222

Frame rate: 20
Frame: 28
16:06:26.150
Interval: 801
[Ljava.lang.StackTraceElement;@2c04ec40

Process finished with exit code 0

The real interval is not 50 ms, but is 150~200 ms, and it only captured 28 frames in 5 seconds, it is supposed to take 20 * 5 = 100 frames because I set the interval to 50.

My environment

python012 commented 11 months ago

To anyone who care about this issue, I tried to make some fix to solve it, see the repo I forked and updated -> https://github.com/python012/screen-recorder/tree/master and the TestDemo, with this version the screen video length would be the same as it recorded, test passed on Windows 10, I think it may not be a maturing solution, it's why I didn't raise PR