12 June, 2009

Screen Capture with FFmpeg

Sometimes it's useful to capture the display output as a means of archiving a procedure or to demonstrate a user experience. The following command will capture the display region 1680x1050 at 30fps for 90 seconds and shrink it to a 640x480 video at near raw resolution (fixed quantizer scale of 1).

The important thing is to confirm your ffmpeg format supports x11grab, otherwise you'll get the following error:

Unknown input or output format: x11grab



ffmpeg -y -f x11grab -r 30 -s 1680x1050 -i :0.0 -t 90 -qscale 1 -s 640x480 out.mpg


As you can imagine, capturing 30fps adds significant resource loading, if you so choose you can down-sample the frame rate but you may need to use an alternative encoder for non-compliant frame rates of some codecs.

The MJPEG encoder seems to work well enough for slow frame rates, like 1 Hz.


ffmpeg -y -f x11grab -r 1/1 -s 1680x1050 -i :0.0 -t 90 -qscale 1 -s 640x480 -vcodec mjpeg out.avi

07 June, 2009

Code Monkey

This video always makes me smile:

06 June, 2009

Controlling VirtualBox Guest Actions

On the Guest:
vboxcontrol guestproperty set TestState ready
vboxcontrol guestproperty wait foo
"C:\Program Files\Windows Media Player\wmplayer.exe" /prefetch:1

On the Host:
#!/bin/bash

retVal=0
retVal=`VBoxManage guestproperty get WinXp TestState | grep Value | cut -f 2 -d \ `
echo $retVal
while [ $retVal != ready ]; do
echo foo
sleep 1
retVal=`VBoxManage guestproperty get WinXp TestState | grep Value | cut -f 2 -d \ `
done

VBoxManage guestproperty set WinXp foo 1


22 May, 2009

ImageMagick - Montage

I love FFMpeg and ImageMagick. Armed with both, you can create some pretty interesting things. For example, you can create a frame consisting of 4 images by issuing the following command:


montage -geometry 720x480+0+0 -tile 2x2 /var/tmp/00000001.jpg /var/tmp/00000002.jpg /var/tmp/00000003.jpg /var/tmp/00000004.jpg /tmp/output.jpg


This will take these 4 images:





To create the following resultant image:

A framed image like the resultant isn't particularly interesting, unless you incorporate a series of them into a video. For example, at work we wished to determine what frame rate would be necessary to drive a vehicle exclusively using a camera. We investigated this by creating a montage video stream with varying frame rates in each frame.

Another fine use would be comparison of file size using alternative video comparisions. For example, imagine a montage frame with each frame demonstrating a different JPEG image, file size and compression ratio. Heck, you could even generate your very own composite video with each of Charlies Angels in each of their own frames. The uses are endless :)

20 May, 2009

FFmpeg Ninja Moves - part 4

Maintaining video quality during conversion can be a primary concern when converting to an alternative format while maintaining the necessary video quality.

By default, the output codec will utilize a default set of encoder quality specifiers. You can override these values by specifying -sameq, -qmin, -qmax or -qscale factors.

The -sameq specifier tells FFMpeg to maintain the same video quality as the source video file.

$ ffmpeg -i /tmp/video.avi -sameq /tmp/video.mpg


The qmin and qmax specifiers constrain the q-factors to a user-specified range. This applies to variable bit rate output streams. Specifying a narrow range will ensure consistent quality. Specifying a highly constrained, high quality factor will give you a good quality output video.

$ ffmpeg -i /tmp/video.avi -qmin 1 -qmax 1 /tmp/video.mpg


Constraining the scale factor to a single numeric can be alternatively done by specifying -qscale as follows.

$ ffmpeg -i /tmp/video.avi -qscale 1 /tmp/video.mpg


Note, the lower the value the higher the video quality.

18 May, 2009

FFmpeg Ninja Moves - part 4

Continuing on our FFMpeg trek, this post will focus on manipulating frame sizes; specifically, cropping, resizing and padding.

Cropping
Selectively cropping out a portion of each frame in the video allows you to focus on particular regions. The input video has 720x480 dimensions, suppose you were only interested in the inner 360x240 frame contents. You can crop the video frames by specifying the left, right, top and bottom crop bands (specified in pixels). As an example, the following command crops the innter 360x240 frame contents.

$ ffmpeg -i /tmp/video.avi -croptop 120 -cropbottom 120 -cropleft 180 -cropright 180 /var/tmp/video.avi

Resizing
If instead of cropping the image you wish to resize it, you can specify a desired frame size WxH. For example, if you wish the output video file dimensions to consist of 360x240 you can specify the -s size specifier as follows:

$ ffmpeg -i /tmp/video.avi -s 360x240 /var/tmp/video.avi

Unlike cropping, all frame contents are retained but the lesser dimensions gives the effect of dropping every other pixel contents.

Padding
If you require expanding the video dimensions you can pad the left, right, top and bottom to attain the desired frame dimensions. To convert the 720x480 video dimensions to 800x600 you can specify

ffmpeg -i /tmp/video.avi -padtop 40 -padbottom 40 -padleft 60 -padright 60 -padcolor FFFFFF /var/tmp/video.avi

I specified a white pad color to allow you to see the pad effects. A keen reader will notice that in order to preserve the aspect ratio the output video is actually 840 x 560.

16 May, 2009

FFmpeg Ninja Moves - part 3

Continuing on, this post will focus on time with respect to video files.

Altering Video Frame Rate
Let's start by playing with the frame rate. Given a 30 frames/sec input file, we can specify a desired alternative frame rate for the output file by specifying the rate specifier.

We can downsample to 5 frames per second by issuing the following command:

$ ffmpeg -i /tmp/video.avi -r 5/1 /var/tmp/video.avi


$ ffmpeg -i /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/tmp/video.avi':
Duration: 00:00:57.4, start: 0.000000, bitrate: 297 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 5.00 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file




Similarly, we can upsample to 60 frames per second by issuing the following:

$ ffmpeg -y -i /tmp/video.avi -r 60/1 /var/tmp/video.avi
$ ffmpeg -i /var/tmp/video.avi
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
configuration: --enable-gpl --enable-pp --enable-pthreads --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
libavutil version: 0d.49.0.0
libavcodec version: 0d.51.11.0
libavformat version: 0d.50.5.0
built on Mar 26 2007 14:28:38, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/tmp/video.avi':
Duration: 00:00:57.3, start: 0.000000, bitrate: 889 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 720x480, 60.00 fps(r)
Stream #0.1: Audio: mp2, 48000 Hz, stereo, 64 kb/s
Must supply at least one output file


Time-Specified Clip
A common practice concerns extracting a video clip from a video stream. Perhaps you're only interested in the first 2 minutes of the video, perhaps the middle 30 seconds is of interest. In either case, the ability to grab a portion of the video is always valuable. The -ss specifier allows seeking into the input file, the -t duration specifier defines how long a clip you wish; both use seconds as the units.

For example, to seek into the source video 32 seconds and extract the next 2.5 seconds you can specify:

$ ffmpeg -y -i /tmp/video.avi -ss 32 -t 2.5 /var/tmp/video.avi
Repeat
Introducing a repeated video sequence can be a necessary feature to author videos. FFMpeg does not directly support this feature, instead the ability to incorporate multiple video streams allows simultaneous concurrent streams rather than sequential videos. The multiple, simultaneous video streams can be incorporated much like DVD contents allow multiple view angles. FFMpeg however does indirectly allow concatenating videos to give a repeat or sequence of video clips. The trick is to convert your source video files into a concat-able format such as MPEG and simply join them together using the cat utility. For example:


$ ffmpeg -i /tmp/video.avi -sameq /tmp/video.mpg
$ cat /tmp/video.mpg /tmp/video.mpg > /tmp/biggie.mpg

The output file now has 2 iterations of /tmp/video.mpg.