Table of Contents

Screencasting with FFmpeg, jack_capture and Xephyr

Introduction

Not satisfied with the quality of the screencasts made with recordMyDesktop I started looking for an alternative that might yield better results, especially the video part. The JACK support of recordMyDesktop is a big plus and quite solid too but recordMyDesktop converts all video to Theora only and this has proved inconvenient when uploaded to a webservice like YouTube. The video quality just degraded too much.
So I needed a different toolset. For the video part I chose FFmpeg for its unrivaled flexibility and support for input and output formats. FFmpeg also has JACK support but I found the JACK input client to be too xrun prone so for the audio part I chose jack_capture, a lightweight, flexible commandline driven recording tool.
To prevent webservices like YouTube having to downscale or upscale your videos, which deteriorates the quality of your videos drastically, you can optionally run the whole screencast session in a nested X server with the help of Xephyr.

Requirements

Screencast script

I use a simple script like this:

#!/bin/bash

DATE=`date +%Y%m%d`
TIME=`date +%Hh%M`

# Start screencast
xterm -e jack_capture -b 24 $HOME/Screencasts/screencast_audio_$DATE-$TIME.wav &
ffmpeg -an -f x11grab -r 30 -s 1280x720 -i 0:0 -vcodec libx264 -vpre lossless_ultrafast -threads 4 $HOME/Screencasts/screencast_video_$DATE-$TIME.mkv

killall jack_capture

You might need to adjust the number of threads for the ffmpeg -threads parameter to match the number of cores of your CPU. If unsure, set it to 0, ffmpeg should then set the numbers of threads automatically.

jack_capture by default captures all the audio that is connected to system:ouput. If you want to be able to manually make connections to jack_capture with jack_connect, qjackctl or whatever, you have to pass it the -mc option (you need at least version 0.9.58 for this)

Optional Xephyr script

Set up a Xephyr nested X server with a resolution of 1280×720 as this resolution yields the best result when uploading the final video to a webservice like YouTube. I use a little script for this:

#!/bin/bash

# Set up nested X server
Xephyr -keybd ephyr,,,xkbmodel=evdev -br -reset -host-cursor -screen 1280x720x24 -dpi 96 :2 &
sleep 3
export DISPLAY=:2.0
/etc/X11/Xsession &

As you can see I set up a session by calling /etc/X11/Xsession. In Ubuntu >= 9.10 this starts up a new fresh Gnome session and because I use IceWM for my main session in which I run Xephyr this works very well. If you're using Gnome as your DE using /etc/X11/Xsession won't work properly so in that case you will have to resort to a different start-up option. This also holds for distributions that don't use /etc/X11/Xsession.

TODO:other distros

After you ran this Xephyr script, you should run the above screencast script, taking care of making the following changes to it:

Within the Xephyr session I also use a plain cursor theme without drop shadow because ffmpeg doesn't capture the drop shadow properly. As of FFmpeg revision 25690 this has been fixed.

Editing, rendering and uploading to a webservice

Now you have two separate files, an .mkv and a .wav file and because jack_capture was started right after ffmpeg audio should be no more out of sync then just a few millisecs. You can now edit the audio and video parts to your liking:

For rendering/exporting I use the following settings in OpenShot:

Now you can upload the resulting mp4 file to a webservice. The settings I've used will yield optimal results for YouTube.

Examples

Tiny Tutorial: Vocoding in Qtractor

The Infinite Repeat - Unaware of a Direction

The Infinite Repeat - Money or Love (DJ AutoStatic Remix)