Let us run and record arbitrary GUI programs via xvfb-run (which itself is
a script to run stuff in Xvfb)! I am going to record the session via
and will take a screenshot with
xwd each second. But first things first.
Xvfb is virtual display server -- implementing the X11 display protocol. That basicly means the rendering only exists in memory and the server won't send output to your screen. How cool is that? xvfb-run is a script (please install it as a packge) which will run your command in Xvfb.
xvfb, avconv or
ffmpeg, xwd, vorbis (
libvorbis0a or something like
that), gtk for python (
python-gtk2, maybe?). xdotool, used for testing, is
Caveats (xvfb-run in combination with avconv)
Or: stuff I did wrong so you don't have to.
.Xauthority != ~/.Xauthority: some users stumble into permission problems, because they have their own ~/.Xauthority file. So setting the parameter -f is not an option when you want to access the display server, it is mandatory. The manpage says about -f:
-f file, --auth-file=file Store X authentication data in file. By default, a temporary directory called xvfb-run.PID (where PID is the process ID of xvfb-run itself) is created in the directory specified by the environment variable TMPDIR (or /tmp if that variable is null or unset), and the tempfile(1) command is used to create a file in that temporary directory called Xauthority.
the tricky thing is, --help says:
-f FILE --auth-file=FILE file used to store auth cookie (default: ./.Xauthority)
that gives you the impression, that
~/.Xauthorityis used, because how do you know xvfb-run creates a temp-dir? Right! Read the manpage, read the source. I would like to propose a new acronym (after you RTFMed) you should RTFC (Read The Fucking Code).
--auto-servernumoption won't return the server-number, so either use the simple way (default servernum value of 99 -- thats what I did), or find a display number yourself (which means replicating the
--auto-servernumcode alredy written. Not DRY, but gives you the ability to run multiple instances at once). Once you got a display number, pass it to avconv, the display number is part of the variable
$DISPLAYhas the format:
hostnameis your host (
0 == localhost)
Dis the display number (for example, you could have multiple displays attached to your monitor)
Sis the screen number (a display itself can have multiple screens, i.e.: virtual desktops)
Find some good avconv settings. For example: the formats .mpg and .mov fail horribly, because avconv needs to record longer than the server is running. Ideally, I would to stop the recording, before Xvfb stops. But Xvfb stops, if xvfb-run exits. The problem here is similar to the Halting-Problem. There is no way to predict when the executed GUI-program is going to terminate. The programs will exit in this order: the program you ran terminates, then xvfb-run terminates and xvfb-run terminates Xvfb. So, obivously avconv tries to record a source that is no longer available and will produce a malformed file. Some formats choke on that behaviour. Theora didn't.
- some display-sizes are not compatible with certain depths.
I made a wrapper (xvfb-screenshooter) around the wrapper (xvfb-run) around the wrapper (xvfb) that wraps the output in a virtual display. What could possibly go wrong?
- i included a simple python-gtk-hello-world program.
- there are three behaviours how this wrapper leaves it's main loop:
- run a specified amount of iterations
- kill the application with the name "Hello.*"
- wait until the application exits
- maybe I will include some cli-switches so you can choose a behaviour without changing the code.
What are some fun things to do with this?
- A lot of screenshots?
- Really huge screenshots?
- Emulate a lot of different displays?