This is an old revision of the document!


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, I run the whole screencast session in a nested X server with the help of Xephyr.

Requirements

  • A recent version of FFmpeg compiled with support for the h.264 protocol
  • jack_capture
  • Xephyr
  • A video editor, I use OpenShot myself
  • A screen that has a minmal horizontal resolution of 1280 pixels

Set up the screencast session

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.

Now start your screencast within the nested X server, I use a second script for this:

#!/bin/bash

DATE=`date +%Y%m%d`
TIME=`date +%Hh%M`
export DISPLAY=:2.0

# Start screencast
xterm -display :0.0 -e jack_capture -b 24 $HOME/Screencasts/screencast_audio_$DATE-$TIME.wav &
ffmpeg -an -f x11grab -r 30 -s 1280x720 -i :2 -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. Within the Xephyr session I also use a plain cursor theme without drop shadow because ffmpeg doesn't capture the drop shadow properly.

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:

  • Edit the .wav file in Audacity or Rezound if necessary. I use some extra gain and compression if necessary.
  • Import the two files in OpenShot and crop start and end to your liking.
  • With VLC I made some stills from the video file and with Gimp I edited these to create the titling.
  • Create transitions, fade-ins and fade-outs to your liking with OpenShot.

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

  • Video: 1280×720, 30 fps (this should match the settings of ffmpeg), mp4 videoformat, 40 Mb/s (Blu-ray quality), libx264 videocodec.
  • Audio: mp3 (libmp3lame), 256 Kb/s and 44.1 Khz sample rate.

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

Examples

wiki/screencasttutorial.1289218935.txt.gz ยท Last modified: 2010/11/08 13:22 by autostatic