Question

I am trying to make a record program in Java. I would prefer not to use any external libraries other than JMF (Java Media Framework). I am using two Swing Timers (as its a Swing application), one to capture the screen & add it to a queue and the other to take the BufferedImage out of the queue & write it to a file. Here are my timers: To insert into the queue:

timer = new Timer(1000/FPS, new ActionListener() { //FPS is a user-inputed value from 1-60 by default its 25
        @Override
        public void actionPerformed(ActionEvent ae) {
            executor.execute(new Runnable() { //executor is a java.util.concurrent.Executor;
                //I put them in an executor so the timer wouldn't wait for the code to finish
                @Override
                public void run() {
                    try {
                        images.insert(R.createScreenCapture(Screen)); //Images is my own queue & R is a java.awt.Robot
                        //Screen is a rectangle that is Toolkit.getDefaultToolkit().getScreenSize()
                    } catch (Exception e) {
                        ExceptionPrinter.PrintE(e); //This is just a method to print the exception to me
                        System.out.print(images.length());
                        timer.stop();
                        timer2.stop();
                    } catch (OutOfMemoryError e) { //This is mainly a debug catch
                        timer.stop();
                        timer2.stop();
                        System.out.print(images.length());
                        e.printStackTrace();
                    }
                }
            });
        }
    });

To write the image:

timer2 = new Timer(1000 / FPS, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (images.length() != 0) {
                            if (!(new File("C:").getFreeSpace() <= 10000000)) {
                                String path=AppRunner.AppR3Directory + "VideoTemp" + File.pathSeparator + file + getModifier() + File.pathSeparator + image + ".JPEG";
                                //AppRunner.AppR3Directory is the working directory of the program (never changes)
                                //file is the user-inputed filename & getModifier() is either "" or a number above 0 (for when the program auto-starts another record)
                                ImageIO.write(images.pop(), "JPEG", new java.io.File(path));
                                imagelist.add(path); //This adds it to my list of images for when i change it to a .mov (custom array)
                                image++;
                            } else {
                                throw new SecurityException("Not enough memory!");
                            }
                        }
                    } catch (IOException e) {
                        ExceptionPrinter.PrintE(e);
                        timer.stop();
                        timer2.stop();
                    } catch (SecurityException e) {
                        ExceptionPrinter.PrintE(e);
                        timer.stop();
                        timer2.stop();
                    }
                }
            });

My problem is that it doesn't seem to record fast enough. For example with the default value of 25 FPS I only get 6 FPS. I have tried changing many different things & searched all over the internet and I can not find a solution. I would like to find out where I am incorrect in getting this to record fast enough. Thanks in advance to anyone that figures it out (I have been stuck on this for three days).

Edit: I do plan to change it to one timer & using a method to write (I originally had two because of the write delay) as said by SimonC.

Was it helpful?

Solution

Try the Monte Media Library screen recorder. I got good results from it last time I tested.

Windows Media Player says it can't open it..

AFAIR WMP says that with all MOVs. Quite irritating, given that it claims the file association. Try it with a player that is not WMP.


As to the longer term, you would be looking to convert the MOV to another format. The ones produced using JMF are huge.

OTHER TIPS

Try to run these threads independetly from timers. I mean, do not use these timers. Start Thread and implement timeing by using sleep(1000/FPS).

It's worth keeping the screen capture task using the Swing Timer, but the image writing task should be moved to a simple Thread pulling images off the queue as soon as they are added. Since you would then be co-ordinating between multiple threads, consider changing your queue to a BlockingQueue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top