Tuesday, November 2, 2010

The dark art of desktop capture in linux

I recently had to record a video demo for an application of mine. Quite an experience it turned out to be. I was told that XvidCap and Istanbul, apps available on ubuntu 10.04, were the way to go. Unfortunately with GLSL shader messing with the FB and for reasons that I'm not willing to venture into I never managed to get them to record what I wanted.

Finally I learned that in linux ffmpeg has a decent desktop capture mechanism. My initial source was from here. Much of that deals with setting up ffmpeg. The relevant piece of command to record the desktop was

/ffmpeg -vcodec mpeg4 -sameq -r 25 -vd x11:0,0 -s 1024x768 ~/screen_op.avi


This produced a video that was close enough to the original visualization. Unfortunately the video turned out to be like 300 Mb for 3 mins which was quite unacceptable.

Furthermore readablity of text was necessary. Straightforward downsizing introduced unacceptable artifacts especially to text elements.

I found Mencoder with the xvid codec to do a good job here. A small bash script to perform a 2 pass encoding:


for pass in 1 2
do
mencoder ~/screen_op.avi -ovc xvid \
-xvidencopts chroma_opt:vhq=4:bvhq=1:quant_type=mod_quant:pass=${pass}:bitrate=4000 \
-o screen_op_xvid.avi
done


Much of the docs for the options were from here and the mplayer man pages on section "xvidencopts".

In general the two pass approach with quant_type=mod_quant(2pass needed for this) seems to work well for text. I found that throttling the bitrate beyond a certain point produced unacceptable results. Further downsizing of videos upto 640x480 retained smooth animations with readable text. I managed to encode about 3 mins of video at 25 fps into about 33mb with text elements readable. I still think more can be done.

One thing that was annoying is that I could never acceptably reduce framerate from the original recording. If I did the result was either jerky or blurry both of which were not ok. As far as I understand there's no getting around unless you are willing to reduce it by an integral factor.