Installing FFMPEG in public hosts

=Intro=

Installing FFMpeg can be tricky. I use FFMpeg in Drupal's Content Management System to stream and view online videos. Often, the FFMpeg that came with our local hosts on CentOS were terribly built, and lacked many codecs. Eventually, I had to compile my own both locally and on the hosts. This tutorial will show you how to get FFMpeg up and running, as well as how to set it up on Drupal if you're using it.

Writing this documentation can be a little bit tricky because i'm trying to instruct in more than one distribution. If it's too messy, please contact me and i'll try and rewrite the parts.

I'll test and see if you could use the binaries I compiled onto any other host of yours. Otherwise, follow these tricks on how to get it working yourselves.

Installing FFMpeg
There are many ways to install FFMpeg. These are the 2 most popular ways that i'll describe.

1) Package Manager
This is the most preferred way. It's the easiest, and will install all the dependancies you want. To install it, it depends on your distro, but it's generally the same. Check out your package manager and search for ffmpeg and install it. Examples are below,

CentOS / Redhat Enterprise yum install ffmpeg

Gentoo emerge -a ffmpeg

Debian / *ubuntu sudo apt-get install ffmpeg

And so on.

WARNING: There is a problem with the above.. The compiled versions you install sometimes have missing codecs in it.. In my case, I installed FFMpeg from Centos 5, and by default it didn't have the 3gpp codec format.. If you have missing codecs or are having problems with these prebuilt binaries, move on to step 2, and compile your own FFMpeg yourself.

2) Compile from Source
This is a bit long.

If both of the above fail, then you'll need to compile your own from source. It goes without saying that you need a compiler, such as GCC. Your Host provider should also and usually does give you access to a compiler. Here are the steps to compile FFMpeg,


 * Get the source from SVN
 * Try to compile, and get any other codecs or dependancies that are missing
 * Compile the source
 * Move the ffmpeg binary to wherever you want.

Now let's start.

To download FFMpeg, you need to check it out from their SVN. Simply do so using the following command, svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg for more information, visit their site.

Now you have the source, change into your ffmpeg directory cd ffmpeg

Now to compile.. By default, if you want a minimum compile, just use

./configure make

But that won't install any codecs. You'll need a lot of codecs. Here is a list of the most important ones you'll need, and the prefix to add to ./configure. If you want details of what they are, or the whole list of what to use, type

./configure --help

and check the External library support: section.

FAAC Codec: --enable-libfaac MP3 Codec: --enable-libmp3lame (for mp3) Theora Codec: --enable-libtheora (for sound) Vorbis Codec: --enable-libvorbis (needed) H2.64 Codec--enable-libx264 (for mpeg) Xvid Codec: --enable-libxvid (for avi and xvid) AMR Codec --enable-libamr-nb (for 3gpp) GPL Codecs --enable-gpl (you have to type this for the codec above)

So, to compile with the above codecs, just type the following

./configure --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libamr-nb --enable-gpl --enable-nonfree

Install any missing codecs or dependancies
If you're on a public host, then you probably wont see any problems,

However, you might get some failed tries If you're on your own machine. That's because you'll need to install both the codecs themselves, as well as the development packages for them in order to use them with ffmpeg. For example,

If you get an error such as

ERROR: libfaac not found

Then with the example above, just search for "faac" (the name of the codec) through your distribution's package manager. , and you'll see many results. The result you're looking for will look like,

Centos: faac2.i386 (the actual faac ) faac2-devel.i386 (the development packages)

Debian libfaac-dev

So just install them as shown below, And run the ./configure line again, and you shouldn't get the error again. Here is a list of the dependancies that you might need for the above,

Debian: apt-get install libfaac-dev apt-get install liblame-dev apt-get install libogg-dev apt-get install libtheora-dev apt-get install libvorbis-dev apt-get install libx264-dev apt-get install libxvidcore4-dev

Note: if you're on debian, you won't find libamrnb easily. Instead, download the latest versions of libamrnb3 and libamrnb-dev from debian multimedia's website. For this tutorial, i'm using the latest stable versions which are as follows. Please make sure to select the right arch for you. I'm using amd64. You might need i386 instead. The installation is the same eitherway.

wget http://debian-multimedia.org/pool/main/a/amrnb/libamrnb3_7.0.0.2-0.0_amd64.deb wget http://debian-multimedia.org/pool/main/a/amrnb/libamrnb-dev_7.0.0.2-0.0_amd64.deb dpkg -i libamrnb3_7.0.0.2-0.0_amd64.deb dpkg -i libamrnb-dev_7.0.0.2-0.0_amd64.deb

Once you're done installing all the dependancies, the ./configure script should be finished successfully and you may proceed to compiling.

Again, the same can be applied for other distributions.

Compiling FFMpeg
Now all you have to do is run make like so,

make

Now it'll start compiling. It should take roughly 15 to 30 minutes on a 2Ghz machine. Once complete, you'll have several binaries in your ffmpeg/ folder. The most important one is, yes you guessed it, the binary called ffmpeg (usually green in color if you type ls).

Copy the resulting binary anywhere you want
Now just take that ffmpeg binary, and copy or move it anywhere handy, like into your project or website's folder.

That's it. You're ready.

Test the binary
Just in case, let's test the binary you have and make sure it works well. In this example, let's test the 3gp codec format. Download any 3gp file from the Internet (Search on google) here is an example. Run the following to encode it. Let's assume the following


 * our new ffmpeg binary is located in /var/www/html/myproject/ffmpeg
 * the file you want to encode is called coolvideo.3gp
 * the result file you want will be called coolresult.flv

Type /var/www/html/myproject/ffmpeg -y -i coolvideo.3gp -ar 22050 -f flv coolresult.flv

If all is successful, you should see an output such as this,

Centos 5

[xushi@centos videos]$ /var/www/html/myproject/ffmpeg -y -i coolvideo.3gp -ar 22050 -f flv coolresult.flv FFmpeg version SVN-r11604, Copyright (c) 2000-2008 Fabrice Bellard, et al. configuration: --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libamr-nb --enable-gpl libavutil version: 49.6.0 libavcodec version: 51.49.0 libavformat version: 52.5.0 libavdevice version: 52.0.0 built on Jan 24 2008 12:25:03, gcc: 4.1.1 20070105 (Red Hat 4.1.1-52)

Seems stream 0 codec frame rate differs from container frame rate: 29.97 (30000/1001) -> 11.00 (90000/8181) Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'coolvideo.3gp': Duration: 00:00:41.0, start: 0.000000, bitrate: 56 kb/s Stream #0.0(eng): Video: h263, yuv420p, 176x144 [PAR 12:11 DAR 4:3], 11.00 tb(r) Stream #0.1(eng): Audio: libamr_nb, 8000 Hz, mono Output #0, flv, to 'iceresult.flv': Stream #0.0(eng): Video: flv, yuv420p, 176x144 [PAR 12:11 DAR 4:3], q=2-31, 200 kb/s, 11.00 tb(c) Stream #0.1(eng): Audio: libmp3lame, 22050 Hz, mono, 64 kb/s Stream mapping: Stream #0.0 -> #0.0 Stream #0.1 -> #0.1 [flv @ 0x84d73b0]removing common factors from framerate Press [q] to stop encoding frame= 452 fps=  0 q=2.0 Lsize=     714kB time=41.1 bitrate= 142.4kbits/s video:361kB audio:321kB global headers:0kB muxing overhead 4.675591%

Again, here's the same example on Debian [xushi@debian videos]$ /var/www/html/myproject/ffmpeg -y -i dancingkid_bnqosypw.3gp -ar 22050 -f flv dancingkid_bnqosypw.flv FFmpeg version SVN-r13529, Copyright (c) 2000-2008 Fabrice Bellard, et al. configuration: --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libamr-nb --enable-gpl --enable-nonfree libavutil version: 49.6.0 libavcodec version: 51.57.0 libavformat version: 52.14.0 libavdevice version: 52.0.0 built on May 29 2008 12:18:49, gcc: 4.2.3 (Debian 4.2.3-5)

Seems stream 0 codec frame rate differs from container frame rate: 29.97 (30000/1001) -> 10.00 (90000/9000) Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'dancingkid_bnqosypw.3gp': Duration: 00:00:54.42, start: 0.000000, bitrate: 102 kb/s Stream #0.0(eng): Video: h263, yuv420p, 128x96 [PAR 12:11 DAR 16:11], 10.00 tb(r) Stream #0.1(eng): Audio: libamr_nb, 8000 Hz, mono Output #0, flv, to 'dancingkid_bnqosypw.flv': Stream #0.0(eng): Video: flv, yuv420p, 128x96 [PAR 12:11 DAR 16:11], q=2-31, 200 kb/s, 10.00 tb(c) Stream #0.1(eng): Audio: libmp3lame, 22050 Hz, mono, 64 kb/s Stream mapping: Stream #0.0 -> #0.0 Stream #0.1 -> #0.1 [flv @ 0x7d9000]removing common factors from framerate Press [q] to stop encoding frame= 543 fps=360 q=2.0 Lsize=    1563kB time=54.30 bitrate= 235.8kbits/s video:1096kB audio:426kB global headers:0kB muxing overhead 2.717253%

If not, then panic...

The same can be tried with any other codec format, like wmv, Xvid etc... Feel free to check. But now we can see that it works.

You're all set! The next step is to configure Drupal to get it to work.

Configuring Drupal for FFMPEG
First of all, copy the ffmpeg binary you created above into the root of your CMS project. You can instead put it anywhere you like.. Just make sure to link to it correctly with the path.

Video module & FFMpeg Helper
You will need to download the video.module module from Drupal's site. Install and activate it, as well as the FFMpeg Helper sub-module. Please note that i use a version of the video module prior to February 2008, so i'm not sure how stable the latest dev version is. Here is a link where you can download a previous 2007 build. It may or may not work. The version i'm using is 5x-1.6.

Go to the ffmpeg helper section through the following link

admin/content/video/ffmpeg_helper

Make sure to use the following settings.


 * Set the path to your ffmpeg binary there.
 * Enable resolution helper
 * Enable playtime helper
 * auto thumbnail videos
 * use auto-thumbnail exclusively for video images
 * Video T Options: -i %videofile -an -y -f mjpeg -ss %seek -vframes 1 %thumbfile
 * Auto Conversion for videos
 * Video C Options: -y -i %videofile -f flv -ar 22050 -ab %audiobitrate -b %videobitrate %convertfile

Note that the -s %size from the video compression options is removed.. It caused major problems.

Also note that the ffmpeg binary path you give above to me seems useless, because the renderer and encoder take their binary path from the one statically written in the video_renderer.php and video_scheduler.php files. However, you still need to enter a correct path to your binary otherwise it'll complain.

video renderer and scheduler.php
Next, you need to copy the video_renderer.php and video_scheduler.php from the video module's folder into your root folder. They are located in modules/video/plugins/video_ffmpeg_helper/

Once they're copied to the CMS root, all you have to do is edit the paths in both files. The two main paths include VIDEO_RENDERING_FFMPEG_PATH and VIDEO_RENDERING_TEMP_PATH. They mostly fall under

define('VIDEO_RENDERING_FFMPEG_PATH', '/usr/bin/ffmpeg'); and define('VIDEO_RENDERING_TEMP_PATH', '/var/www/html/myproject/tmp/video'); and any other paths in the code too.

Scheduler
Finally, you need a scheduler. I'm still not sure which is better, to set a low or high schedule time..

High: Guaranteed not to corrupt, but it still means it'll take a long time until the video is ready to be viewed

Low: Quicker conversions and videos are ready, but i wonder if you have many videos to encode, or one huge video, that will not finish before the next schedule. Does the next schedule know not to touch these files as they're being encoded by the first one? Or will it also encode and corrupt twice? I haven't tested yet.

Anyway, to set a scheduler, create a file called doscript.sh in your Drupal root folder, and inside it, have the following.

cd /var/www/html/myproject php -f video_scheduler.php
 * 1) this is for the dev

Make sure the script is excutable chmod a+x doscript.sh

Finally, edit the crontab with crontab -e and add the following line */1 * * * * sh /var/www/html/myproject/doscripts.sh to execute the script once a minute. Follow the Using Cron for more info on crons.

The crontab wil execute doscripts.sh, which will in turn execute video_scheduler.php, which will in turn execute the video_renderer.php for encoding. Yes i know, you're asking why use doscripts.sh and not use video_scheduler.php directly? try for yourself... but you'll get too many path problems if you execute the script from outside the directory.

That's it for FFMpeg and video on Drupal. I hope it helps anyone. Any comments are welcome.