How to get a crisp, exact color match for lossless screen-cast? Background

Recording a screen-cast (no audio) in Xubuntu Linux. The following image shows a side-by-side comparison of the video (left) versus the desktop (right):



The screen-cast is recorded using:

ffmpeg -r 30 -f x11grab -s $WIN_GEO -i :0.0+$WIN_XY -vcodec huffyuv -preset ultrafast -qp 0 output.mkv


Here, $WIN_GEO stores the browser dimensions (1030x794) and $WIN_XY has the browser location (1020x221).

$ cat /etc/issue
Ubuntu Trusty Tahr (development branch) \n \l


Problem

The colours in the video differ from the colours shown on the desktop, resulting in a slightly blurry playback. I have read that this could be due to conversion between RGB and YUV colours.

Question

How do you record a desktop video (screen-cast) that when played back (e.g., using mplayer, VLC, or ffplay) results in an exact match to the original desktop colours and crispness?

Related

Relevant pages:


http://www.unixuser.org/~euske/vnc2swf/
http://technically.us/pictures/test.html
http://ubuntuforums.org/showthread.php?t=1392026
https://askubuntu.com/questions/347574/how-to-do-screencasting-desktop-recording-with-high-quality-audio-and-video
http://step4wd.com/2012/08/03/recording-screencast-in-ubuntu-linux/
https://unix.stackexchange.com/questions/73622/how-to-get-near-perfect-screen-recording-quality
https://unix.stackexchange.com/questions/65970/washed-out-colours-with-screencast-software-but-not-screenshot-on-ubuntu-all-ve
https://trac.ffmpeg.org/wiki/How%20to%20grab%20the%20desktop%20%28screen%29%20with%20FFmpeg
http://rayslinux.blogspot.ca/2012/04/capturing-linux-desktop-via-command.html
Capturing the video frames in XWD format then converting to PNG yields results that are almost pixel perfect when encoded with ffmpeg.

Install xvidcap:

mkdir -p $HOME/dev
cd $HOME/dev
svn checkout svn://svn.code.sf.net/p/xvidcap/code/trunk xvidcap-code
cd xvidcap*
./autogen.sh
LIBS="-ldl -lX11 -lXext" ./configure --prefix=/usr/local
make &amp;&amp; sudo make install


Capture stills at 25 frames per second:

mkdir -p $HOME/video
cd $HOME/video
xvidcap --fps 25 --quality 100 --cap_geometry 1024x768+768+288 --file out%05d.xwd


This creates a series of X Windows capture files inside $HOME/video. Convert the files to PNG format using ImageMagick then combine into a video:

for i in out*.xwd; do convert -define png:color-type=2 $i $(basename $i .xwd).png; done
ffmpeg -i out%05d.png -c:v huffyuv -preset veryslow -qp 0 -qscale:v 0 output.avi


An example script:

echo "Click window to capture..."

INFO=$(xwininfo -frame)
WIN_GEO=$(echo $INFO | grep -oEe 'geometry [0-9]+x[0-9]+' | grep -oEe '[0-9]+x[0-9]+')
WIN_XY=$(echo $INFO | grep -oEe 'Corners:\s+\+[0-9]+\+[0-9]+' | grep -oEe '[0-9]+\+[0-9]+' | sed -e 's/\+/,/' )

OUTPUT_DIR=$HOME/video

echo Capturing to $OUTPUT_DIR...
rm -rf $OUTPUT_DIR
mkdir -p $OUTPUT_DIR
cd $OUTPUT_DIR

WIN_XY=$(echo $WIN_XY | tr , +)

xvidcap --fps 25 --quality 100 --cap_geometry $WIN_GEO+$WIN_XY --file out%05d.xwd

# Convert captured images to PNG format
echo "Converting XWD to PNG..."
for i in out*.xwd; do convert -define png:color-type=2 $i $(basename $i .xwd).png; done

ffmpeg -i out%05d.png -c:v huffyuv -preset veryslow -qp 0 -qscale:v 0 output.avi


This creates a high-quality video that looks sharp with VLC, can be edited in OpenShot, and uploaded to various video hosts. Playback with MPlayer yields slightly fuzzy and off-coloured results.