Sunday, June 26, 2016

How to capture desktop in Java: Fast method!

If you are developing software in Java, you may need to capture the desktop at some point.  There is the Robot API that does provide a simple way to capture the desktop, but it's not very efficient.

I've found a better way to capture the desktop, or the webcam in Java, relying on FFMpeg.  There is no need for JNI bindings or other obscure libraries dependencies.  All you need is an executable FFMpeg binary in your path.

Why not use Robot?

The Robot API is really easy to use but it has a major drawback: Speed.  On some computers, you may be able to capture up to 30 fps but on other, you'll struggle to capture images at 3 fps.  It seems that the operating system and the video driver are sensitive areas for the Robot API.

FFMpeg?

FFMpeg is a console application that can capture, transcode and even stream video and audio file.  It's a swiss army knife for multimedia content.  It is available on almost all Linux distros, OS X and Windows.

If not already installed, you can download it here: https://ffmpeg.org/

How to capture video?

Once FFMpeg is installed on your system, you can invoke the binary using the Process class as any other executable.

The trick is to retrieve the captured data directly from FFMpeg using the Process class.  Once the raw data is captured, use a BufferedImage to store those raw data and you'll end up with an Image available for whatever you want to do with it.

Here's the code snippet:

BufferedImage buffer = new BufferedImage(720, 480, BufferedImage.TYPE_3BYTE_BGR);
 
String command = "ffmpeg -nostats -loglevel 0 -f x11grab -r 30 -video_size "+ buffer.getWidth() +"x" + buffer.getHeight() + "-i :0.0 -f rawvideo -pix_fmt bgr24 -";

Process p = Runtime.getRuntime().exec(command);
java.io.DataInputStream in = new java.io.DataInputStream(p.getInputStream());
 
byte[] data = ((DataBufferByte) buffer.getRaster().getDataBuffer()).getData(); 

while (!stopMe) {
     in.readFully(buffer);
}
in.close();
p.destroy();

 This code will capture at the highest frame rate that the computer can support.  The speed of the computer will be the limit of your capture processing speed.

The thing you need to focus is the output format of FFMpeg.  The video encoding must be "rawvideo" with a pixel format matching the BufferedImage.  In this example, a 24 bit/pixel is used in BGR format (Blue, Green, Red).  The data is them exported directly to the console (notice the "-" at the end of the command line...) instead of a file.  That means that using the InputStream from the Process class, Java is able to read the data as fast as it can.

Execute this capture process in a Thread making the BufferedImage available for other parts of your software. 

See the whole thing running...

Using this method, I have built ScreenStudio to capture the desktop into a virtual video mixer built entirely in Java.  If you want to see it running live, download the source code of ScreenStudio at http://screenstudio.crombz.com


Leave you questions in the comments or tweet me at http://twitter.com/patrickballeux


Have fun!







Friday, June 24, 2016

Rediscovering Gnome, moving away from Unity

While testing other desktop managers on my laptop running Ubuntu 16.04, I've accidentally broke my installation.

The main culprit is me as I did force a few things to happen.  Ubuntu has been my main distros since 2004.  The passage to Unity did upset me a little bit but I got used to the new interface and eventually, I liked it.

Today, I wanted to try out the other desktop manager available in the Ubuntu repository.  I could not get a decent performance from KDE, but others like XFCE and Mate were running smoothly on my old laptop.


Eventually, I've tried Gnome...  I was expecting something similar to Mate with a few bells and whistles on the top.  It's not a lightweight desktop but it does have its charms.  I must say, I do like this desktop metaphor way more than Unity.


The way I understand it, an app is meant to run in full screen all the time.  That is something that I do like in OS X as a full screen app is considered as a "new" desktop space.  That's exactly how Gnome 3 does work.



Of course, you still can have multiple apps running in the same desktop space, but I hate switching between apps as I do prefer everything to be maximized.  The the Unity Desktop, you can have multiple desktop spaces but you have to pre-configured the layout.  In Gnome, desktop spaces are dynamic so if you need one more, just go to the last desktop space.

Another great feature of Gnome is the Gnome Shell itself.  It does support Extensions that can be added at the top and I've found a few plugins that made my day. 

Finally, I just re-installed the Ubuntu Gnome from scratch to ensure that nothing from Unity would survive on my laptop.  It is a bit more flexible than Unity and does provide a lot of features.

You can download for free at: https://ubuntugnome.org/

Tuesday, June 21, 2016

Running Steam on Ubuntu 16.04 (amd64)

If you try to install the Steam app to access great games on Ubuntu 16.04, you will find that it does not work out-of-the-box.



After searching the web for a few tips and tricks, I finally managed to make it run.


  • Install the i386 architecture (sudo apt-get install libc6:i386)
  • Install the default debian package from the Steam website (http://store.steampowered.com/about/)
  • Create a small script to launch Steam

Steam.sh
LD_PRELOAD='/usr/$LIB/libstdc++.so.6' DISPLAY=:0 steam
  • Make the script executable: chmod +x Steam.sh
  • Execute your script
It's sad that we need to apply this workaround until the Steam team does provide a better package, but it does work.


Tuesday, June 14, 2016

Are you lazy for not learning the command line?

Last week-end, I was reading a blog somewhere on the Internet about Linux and how easy and powerful it is.  Mainly, the text was targeted at Ubuntu, but I'm pretty sure it would apply to any main distros.  

In the comments, readers were starting another (sigh) flame war between Windows, Ubuntu and OS X (oh, sorry, macOS).  This is my guilty pleasure:  Reading those endless comments about how one is a sheep and an another one is a zealot.  One comment did catch my attention as it was stating that if you are too lazy to learn simple commands to execute in a terminal, you should not be allowed to use a computer...

I am a power user and I do use the command line quite often.  Assuming that someone is lazy because he or she does not care about some advanced possibilities is simply senseless.  Too all power users out there:  YOU ARE NOT GODS!

Being interested in computers does not make you a special person.  There is no point at displaying your knowledge, assuming that anyone below your technical level is a complete idiot.  Let's be clear: the time you spent learning about advanced scripting by copy/pasting from the web, others have spent that time on something else.

Even if I do use my computers to do some development, I do enjoy using my iPad for it's simplicity.  There are people out there who really do not care about automation, scripting and other geeky stuff.  All they wanna do is use a computer as they drive their car or watch T.V.    

Laziness is not taking the time to help others with simple issues that you know how to solve.

Knowledge is meant to be shared...