The [pretty much] Complete Guide to Installing ffMPEG and Audio Binaries

Posted by Nessa | Posted in uncategorized | Posted on 07-01-2008

28

I know you’ve provably seen a lot of guides on how to install ffMPEG, but I’ve noticed that most of them are incomplete and don’t cover the possible issues that can arise during installation. I’ve installed ffMPEG on dozens of servers and have devised a standardized procedure on what I feel is the best way to perform this installation.

This walkthrough has been tested on systems running Redhat 9, RHEL 4, and CentOS 4.5 and it may also work on other distributions and versions. Our servers also run cPanel 11, but this is in no way required in order to install ffMPEG. I assume at this point that you have root access and that yum (or another similar package manager) is installed.

ffMPEG commonly consists of and includes the following software:

- Essential / MPlayer
- FLVtool2 (Requires a Ruby Core)
- LAME MP3 Encoder
- php-ffMPEG
- ffMPEG
- libOgg
- libvorbis

To start out, enter into a temporary source directory and download all the binaries:

cd /usr/src
wget http://www3.mplayerhq.hu/MPlayer/releases/codecs/essential-20061022.tar.bz2
wget http://www4.mplayerhq.hu/MPlayer/releases/MPlayer-1.0rc2.tar.bz2
wget http://rubyforge.org/frs/download.php/17497/flvtool2-1.0.6.tgz
wget http://easynews.dl.sourceforge.net/sourceforge/lame/lame-3.97.tar.gz
wget http://superb-west.dl.sourceforge.net/sourceforge/ffmpeg-php/ffmpeg-php-0.5.0.tbz2

*These are the latest stable versions at the time this article was written. If you are unable to download any of the above, you’ll need to visit the distributor’s site and download the latest stable version available.

Now extract everything:

bunzip2 essential-20061022.tar.bz2; tar xvf essential-20061022.tar
tar zxvf flvtool2-1.0.6.tgz
tar zxvf lame-3.97.tar.gz
bunzip2 ffmpeg-php-0.5.0.tbz2; tar xvf ffmpeg-php-0.5.0.tar
bunzip2 MPlayer-1.0rc2.tar.bz2 ; tar -xvf MPlayer-1.0rc2.tar

Create and import the Codecs directory:

mkdir /usr/local/lib/codecs/
mv essential-20061022/* /usr/local/lib/codecs/
chmod -Rf 755 /usr/local/lib/codecs/

Install Subversion and Ruby

yum install subversion
yum install ruby  (If you're on cPanel you can alternatively use /scripts/installruby)
yum install ncurses-devel

Get ffMPEG and MPlayer from SVN:

svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
svn checkout svn://svn.mplayerhq.hu/mplayer/trunk mplayer

Install LAME:

cd /usr/src/lame-3.97
./configure && make && make install

Install libOgg and libVorbis:

yum install libogg.i386
yum install libvorbis.i386
yum install libvorbis-devel.i386

Install flvtool2

cd /usr/src/flvtool2-1.0.6/
ruby setup.rb config
ruby setup.rb setup
ruby setup.rb install

Install MPlayer:

cd /usr/src/MPlayer-1.0rc2
./configure && make && make install

HTML Email Template Pack - PC Version

Install ffMPEG:

cd /usr/src/ffmpeg/
./configure --enable-libmp3lame --enable-libvorbis --disable-mmx --enable-shared
make && make install

This is the typical configure line that I use, but you can customize this to what you need. For available configure options, type ./configure –help. Your custom configuration may require the installation of additional software on the server.

ln -s /usr/local/lib/libavformat.so.50 /usr/lib/libavformat.so.50
ln -s /usr/local/lib/libavcodec.so.51 /usr/lib/libavcodec.so.51
ln -s /usr/local/lib/libavutil.so.49 /usr/lib/libavutil.so.49
ln -s /usr/local/lib/libmp3lame.so.0 /usr/lib/libmp3lame.so.0
ln -s /usr/local/lib/libavformat.so.51 /usr/lib/libavformat.so.51

You may get an error about a library path not being found, if so, run

export LD_LIBRARY_PATH=/usr/local/lib

If this is being installed on a dedicated server, you might also get an error about the /tmp directory not be executable, which is common when installing on a dedicated server with a separate /tmp partition mounted noexec. In this case, you will need to create a tmp dir in the ffmpeg folder and use that as the tmp disk for now:

mkdir tmp
chmod 777 tmp
export TMPDIR=./tmp

Then run the configure command and set the TMPDIR variable back.

export TMPDIR=/tmp

Install ffMPEG-php

cd /usr/src/ffmpeg-php-0.5.0/
phpize
./configure && make && make install
ln -s /usr/local/bin/ffmpeg /usr/bin/ffmpeg
ln -s /usr/local/bin/mplayer /usr/bin/mplayer

When the installation is complete, it will give you a long path to the shared libraries. This needs to be copied to the php.ini as so:

[ffmpeg]
extension=/usr/local/lib/php/extensions/no-debug-non-zts-20020429/ffmpeg.so

or in most cases where the extension_dir variable is set, just do:

extension="/ffmpeg.so"

The ‘no-debug-non-zts-xxxxxxxx’ directory will be the one provided during installation. When this is done, restart Apache and check that the module is loaded in PHP:

/etc/init.d/httpd restart
php -r 'phpinfo();' | grep ffmpeg

Look for this:

ffmpeg
fmpeg support (ffmpeg-php) => enabled
ffmpeg-php version => 0.5.0
ffmpeg.allow_persistent => 0 => 0

If you only get output for the ‘PWD’ variables, make sure that the extension_dir path is correct in the phpinfo file. Sometimes there are two specified, and if that is the case then the incorrect one should be commented out.

Test out ffmpeg for errors just by typing ffmpeg at the command line. The most common error is:

ffmpeg: error while loading shared libraries: libavformat.so.51: cannot open...

To correct this, edit /etc/ld.so.conf and add the line

/usr/local/lib

then save and exit.

Now run this command to reload the library cache:

ldconfig -v

You’re all done…enjoy!

Whitespace is Evil

Posted by Nessa | Posted in uncategorized | Posted on 19-12-2007

2

I have this recurring nightmare of PHP apps that don’t trim whitespace when entering info. As a habitual copy and paster, it would be nice if some programmers could tend to my laziness and reluctance to type. Yes, Tony, I’m talking about you. Ever hear of the trim() function? Yea, it’s the Brazilian wax of PHP you inconsiderate bastard.

$text = "some text with extra spaces ";
$trimmed = trim($text);
echo $trimmed;

More of Using PHP for Server Info

Posted by Nessa | Posted in uncategorized | Posted on 17-12-2007

1

I’ll eventually get the whole thing up here, but I’ve been working on a simple server info script to help me and the other members of the system admin team keep up with the gazillion servers we have and all their different configurations. One of the reasons it’s taking so long (aside from my recent alcohol binges) is that it has to be portable to every server without the need for specific modifications, regardless of their setup. This eventually calls for using a simple if statement and empty() function to decide what info to output. Really, it’s so easy that I don’t even know why I’m posting it, but it kinda supplements this and this.

I’ll take the Ruby example I used earlier to find out what version of Ruby is installed:

$rubyver = exec("ruby -v |awk {'print $2'}"); ?>

Most of our servers don’t have Ruby installed, so I instead of getting an ugly ass error or nothing at all, I’d rather the script gracefully output its absence:

if (empty($rubyver)) {
echo "<font color='red'>Ruby is not installed on this server</font>";
} else {
echo "Ruby Version $rubyver";
}

This code fragment will check the output of the $rubyver variable, so if Ruby is not installed then the variable will return no value. Since the variable is then considered empty, the first echo statement is executing telling the viewer that Ruby is not installed on the server. If Ruby is installed on the server, then the second echo statement will run.

Common PHP Errors

Posted by Nessa | Posted in uncategorized | Posted on 07-12-2007

7

I’m going back to the basics here, you know, when you wrote your first PHP script and saw an ugly-ass error message pop up on your screen? Error messages are the best tool a programmer has.

Set up Error Reporting

Most PHP errors are straight forward, but there are times where you don’t see any which makes it very difficult to tell what the problem is.

The first step of PHP troubleshooting is to turn error reporting on. For security reasons you’ll want error reporting off by default, but if something goes wrong you’ll need the information for debugging. You can usually enable error reporting by adding this line to the problem script:

<?php error_reporting(E_ALL) ?>

Or you can add these lines to the root .htaccess:

php_flag display_errors on
php_value error_reporting 6143

This will usually display an error useful for troubleshooting, that is, if the software and your server configuration allows it.

Parse Errors

Parse error: parse error, unexpected T_STRING in……

This is a syntax error. Perhaps you forgot a semi-colon at the end of a line, or you forgot a double quote (“) or an end bracket (}) after you started one. For quote and semicolon issues, the problem is usually the line above the one reported in the error. For brackets, it may be at the end of the script.

Parse error: syntax error, unexpected $end in

You’re most likely missing a } somewhere. Make sure that each { you have is also closed with a }.

Parse error: syntax error, unexpected T_STRING, expecting ‘,’ or ‘;’ in..

There may be double quotes within double quotes. They either need to be escaped or brought to single quotes. It’s also possible that a new PHP statement was started before the previous was finished.

Header Errors

Warning: Cannot add header information – headers already sent by (output started at /home/vnessa5/www/errors.php:9) in….

Warning: Cannot send session cache limiter – headers already sent in somefile.php on line 222

Naturally, HTML will parse before PHP. The script is trying to send header information after you’ve already sent output to the browser. HTTP headers are required to be sent before any output from your script, which means that a header function must be placed before any html or even a white space. There are two solutions for this. Either (1) Set the header tags the top of the document, or (2) insert a header redirect by adding this to the very top of the page to force the output buffer:

<?php ob_start();

Then this at the very end of the page (not usually required)

ob_end_flush(); ?>

mySQL Result Source Errors

Warning: Warning: mysql_fetch_array(): supplied argument is not a valid MySQL result resource in…

You need to take a look at the $result variable used to define the loop. More than likely there is a syntax error on the reported line before the $result field, or the value of $result does not exist.

Supplied argument is not a valid stream resource…

This is usually caused when your code is looking for a table or other resource in the database that does not exist.

Sessions are not being created or maintained

This can apply to any of the scenarios below:

(1) The program isn’t remembering your login
(2) Your shopping cart won’t hold items
(3) Your php script is redirecting like crazy
(4) “Call undefined function session_start” error
(5) PHP isn’t processing pages called by something like index.php?page=home&id=7

Your site is most likely dependent on register_globals. You can enable them by putting this line in your .htaccess (or just enabling in your php.ini if you have access):

php_flag register_globals On

Stream Errors

Warning: failed to open stream…

Warning: main(/index.php): failed to open stream: No such file or directory in…

This is usually because either the specified file is missing, or a file declared in a require() or include() function is missing. The easiest way to fix this is by re-installing the PHP program from a freshly-uploaded copy, or restoring the original config.php and just changing the db information. The include path may also be incorrect, but either way your script is looking for a file that isn’t there, or it is looking in the wrong place.

Warning: fopen(…): failed to open stream: Permission denied in…

This is a permissions and/or ownership issue. Try first setting the permissions to 777 just to see if the script will run. If so, you should narrow down the permissions to 775. If not, set the user/group to user:nobody.

Warning: <…> is not a valid stream resource…

Warning: fread(): supplied argument is not a valid stream resource in…

This is an error seen when trying to use functions like fopen(), fread(), feof(), etc. and are usually caused by an invalid or unavailable resource that is being called in the line specified. For instance, if the fread() function is returning this error, it could be that the file it is trying to access does not have the correct permissions or does not exist.

Warning: Failed opening….

Warning: Failed opening ‘…’ for inclusion (include_path=’.:/usr/local/lib/php’) in Unknown on line 0

Make the sure that the file mentioned (and its holding directorie) has read + execute permissions, and that the path to the file is correct. If not, you’ll need to add the path into the PHP code: (or .htaccess)

include(“/path/to/files”);
Blank PHP Pages

You go to a .php page, but it’s blank.

The scope of what can cause blank pages is very broad, but there are a few things to look at:

-Is error reporting turned off anywhere in the script or in the .htaccess? If so, turn it on to see what is happening (php_flag display_errors on), or add the lines at the top of this page into the script.

-Is the PHP script even generating any output (usually you can tell my finding the print function?

-Check the database connection, i.e, username, dbname, user added to db, etc.

-Try using the full <?PHP ?> tags, rather than the shorter versions <? ?>

Also, if the software is prebundled (like phpBB or Gallery), then the index or one of the include pages could be corrupted. Usually you can just replace the problem page with a working version from another installation.
Max Execution Time Error

You receive some variant of a “Max_execution_time” error when loading a page.

This is caused when a PHP script takes longer to execute than the server allows, but can be adjusted by adding a PHP directive to your .htaccess: (in seconds, 0 = unlimited) or modifying the value in php.ini.

php_value max_execution_time 0

Open_basedir Errors

Warning: Unknown(): open_basedir restriction in effect.

This is a protective feature of Apache that restricts PHP from accessing files/folders outside the user’s home directory. Most of the time this is due to an incorrect include path in one or more of the config files (which are usually mentioned). Look for something like this:

/includes/somefile.php
/admin/files/anotherfile.php

The heading / tells the filesystem that these folders are on the server root, and thus prevents PHP from accessing them. You can usually fix this by changing the path to these files to be absolute to their location:

/home/username/public_html/includes/somefile.php

or

./includes/somefile.php

Convert Database to UTF-8

Posted by Nessa | Posted in uncategorized | Posted on 06-12-2007

15

We seriously see a ton of customers coming in with the type of databases that are a nightmare to move over. When you’re dealing with special characters in a database, you have to make sure that the charset and collation are dumped *with* the database, so that when you move it to another server the tables and data create properly. The biggest annoyance so far is converting tables back to UTF-8, as when this is done through the MySQL shell or phpmyadmin is had to be done table-by-table. So, I wrote this simple PHP script to do it all at once:

<?php
// Database info

$dbhost = 'localhost';
$dbuser = 'db_user';
$dbpass = 'password';
$dbname = 'db_name';

//---------------

header('Content-type: text/plain');

$dbconn = mysql_connect($dbhost, $dbuser, $dbpass) or die( mysql_error() );
$db = mysql_select_db($dbname) or die( mysql_error() );


$sql = 'SHOW TABLES';
$result = mysql_query($sql) or die( mysql_error() );

while ( $row = mysql_fetch_row($result) )
{
$table = mysql_real_escape_string($row[0]);
$sql = "ALTER TABLE $table DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci";
mysql_query($sql) or die( mysql_error() );
print "$table changed to UTF-8.\n";
}


mysql_close($dbconn);
?>

If course, you can adjust the ALTER TABLE statement to any character set and collation that you need.

Using an .htaccess with PHP Compiled as CGI

Posted by Nessa | Posted in uncategorized | Posted on 06-12-2007

3

We recently started installing suPHP on a few of our servers, which is an implementation of phpsuexec, only a ton faster and with less overhead. Yesterday I posted a tutorial on how to install suPHP on a PHP5/Apache server outside of EasyApache, but today I shall go over how to enable PHP directives in your .htaccess instead of using the php.ini.

First of all, if you’d rather use the .htaccess than the php.ini capabilities of a phpsuexec environment, then shame on you. But, we have some customers who are terrified of php.ini and would rather use the .htaccess. So what? Ok, well there is a workaround. Mr. Joye released a newer version of htscanner that now works with suPHP, and allows you to use php directives in your .htaccess just like you did when PHP was installed as and Apache module. All you have to do is download the tarball and install like any other PHP module:

wget http://pecl.php.net/get/htscanner-0.8.1.tgz

tar -xvzf htscanner-0.8.1.tgz

cd .htscanner-0.8.1

./configure && make && make install

Then add a loader for the resulting binary to your php.ini:

extension=”/htscanner.so”

From here, you can add your php_value and php_flag statements to your .htaccess as usual within <ifmodule> tags. I should note that the reason why you normally would not be able to overwrite php.ini values in your .htaccess is because .htaccess is an Apache file. Under phpsuexec/suPHP, PHP runs as a CGI module so Apache does not understand what those mean, so it will either ignore them all together or return a nasty 500 error.

How to Upgrade PHP

Posted by Nessa | Posted in uncategorized | Posted on 04-12-2007

5

Whether you compiled manually or with EasyApache, running a PHP upgrade from a previous version is super easy but also one of the most common questions I get. There are 3 likely assumptions about your current environment (specific to Linux servers, sorry Windows users):

1. You are running a cPanel server and have PHP compiled by EasyApache

2. You compiled PHP manually from source

3. You used Yum, Aptitude, or another package manager

EasyApache

Perhaps the easiest (but least efficient time-wise), simply log into WebHost Manager > Apache Update and select “Previously Saved Config” option and “Start Customizing Based on Profile“. The next screen should take you to the Apache version, which you can keep the same or upgrade as well. Then you’ll be taken to select either PHP 4 or PHP 5, proceeded by the actual version you wish to run and then the options for both Apache and PHP on the next two steps (Advanced Configuration). You usually do not need to change the options if your target is just a simple upgrade within the same version family, but if you changed the Apache version, updated cPanel recently, or are upgrading to a different PHP version family (like 4.4.7 to 5.2.x), then you’ll want to double-check the Apache/PHP build options to make sure they are what they need to be before selecting “Save and Build.” If you are running older versions of EasyApache (usually with cPanel 10 or early versions of cPanel 11 STABLE) then all you have to do is select ‘Load Previous Config‘, pick your PHP version, and ‘Build‘.

Source

If you’ve compiled PHP from source (./configure && make && make install method), you can use your previous configure arguments to compile against a different version. Refer to your server’s phpinfo file (if you don’t have one just create a PHP script with <?php phpinfo(); ?>) and copy the entire ./configure statement into notepad and remove the single quotes. Once you’ve done this, download the source tarball of the new PHP version, untar, and then enter the installation directory. From there, all you have to do is paste the configure statement from notepad. For instance, for PHP 5.2.5:

wget http://www.php.net/get/php-5.2.5.tar.gz/from/this/mirror

tar -xvzf php-5.2.5.tar.gz

cd php 5.2.5

./configure –options-from-your-phpinfo

After the configuration is complete, the script may indicate at the end of its output that you’ve specified configuration options that do not exist. This usually will not affect your build, but you’ll want to review them and consult the PHP documentation on the correct syntax or alternatives to the invalid build options, as these can change depending on which version of PHP you are installing. Doing a ./configure –help will also display the valid options you can use.

Once you have a good configuration, you can go ahead with the make and make install to install the new version of PHP. If you have PHP integrated with Apache (usually you would unless you compiled as CGI) then the installation should have already updated the PHP binary for Apache and module loader in httpd.conf. However, you may need to manually comment out old module loaders if there are conflicts. You’re looking for something like this:

LoadModule php5_module        modules/libphp5.so

Package Installation

Some people have PHP installed via package manager, like Yum or Aptitude. Since the package software usually handles all aspects of the configuration and installation (outside of modules you may have installed via PEAR or Pecl), then you can use its update function to take care of the upgrade as well. Most have a specific option for upgrades, for instance Yum uses:

yum update php

For more information, see NixCraft’s article on PHP installations with Yum.

Massive Upgrade Time

Posted by Nessa | Posted in uncategorized | Posted on 01-12-2007

0

I decided to stop being lazy and get around to those upgrades I needed for my site and server:

- Upgrade PHP to 5.2.5 and Apache 2.2.6

- Upgrade Gallery2 and the WPG2 plugin for WordPress

- Upgrade WordPress to 2.3.1

First, I should admit that I do use the EasyApache installer from WHM, as it has vastly improved to the point where I don’t have to troubleshoot its builds afterwards, nor do I have to go back and reinstall eAccelerator and Suhosin – The current release of cPanel now includes those options and I must say that they have become rather flawless. In other words, it saves me the time of compiling shit by hand when all I have to do is click a few buttons and it’s all done.

Second, I was avoiding the Gallery2/WPG2 upgrade because I remember that the first time I set it up it was hell, and since it was so long ago I didn’t want to go through that again.

Third, since my last WordPress upgrade I had numerous problems with plugins and as a result I had to tweak most of them because their developers hadn’t released an upgrade yet. I finally decided to just suck it in and upgrade, though it wasn’t as bad as I thought it would be. There are a few things to point out:

- Ultimate Tag Warrior has been discontinued due to WordPress 2.3.1′s native support for tagging. If you’re a UTW user like me, you can still keep your sexy tag cloud by follow these steps:

  1. In your admin section, go to Manager > Import and use the UTW import tool to convert your UTW tags to WordPress tags. Then go to Manage > Categories and convert your categories to tags too, if they were linked to UTW before.
  2. In your theme code where you normally would display your categories, change the code to <?php the_tags(”); ?> instead of <?php the_categories(”); ?> or whatever it was before.
  3. Since your tag cloud is now gone, remove the UTW code and replace it with <?php wp_tag_cloud(”); ?>. You can read more about configuring the tag cloud here.

Since removing UTW and upgrading my plugins and WP, I noticed that my site loads a ton faster though, so I’m overall glad that I finally got around to doing this stuff. If you’re lazy like me and still haven’t upgraded to WP 2.3.1, below is a helpful guide on how to do so:

http://polymathprogrammer.com/2007/10/29/upgrade-wordpress-2pt2-to-2pt3/

MX Validation in PHP

Posted by Nessa | Posted in Uncategorized | Posted on 01-12-2007

9

Hosting companies have all kinds of tactics to keep spam away from their customers, but one very common complaint I get is the amount of spam coming in through contact forms. Even though we don’t allow ‘nobody’ mail through the php mail() function and we provide the best server-side spam filters available, local mail cannot be filtered or limited. In other words, no spam filter in the world is going to save you from your shitty contact form.

I started recommending to our customers to implement MX checks in their forms as spam bots nowadays can easily get past things like captcha and textual confirmations. Spammers rarely send email from valid mail hosts so it’s very easy to filter these out with just a few lines of code:

<?php
list($user, $domain) = split(“@”, $email);
if (checkdnsrr($domain, “MX”)) {
} else {
}

?>

To explain the code a little bit, you’re basically taking your stored email address variable ($email) and using the split() function to single out the domain name into one variable, $domain. When you pass the domain through the checkdnsrr() function, PHP will return either a ’1′ or ’0′ result, which is interpreted as either true or false. The above is just the basic code, but you can have it spit out errors as well:

if (checkdnsrr($domain, “MX”)) {
} else {
echo "Invalid email";
}

The checkdnsrr() function can also be used to check for other records as well, like A, CNAME, NS, etc.

A Simple Way to Save Bandwidth in PHP

Posted by Nessa | Posted in Uncategorized | Posted on 18-11-2007

12

If you were ever looking for a quick and sexy way to save bandwidth on your PHP-based porn high traffic site, all you have to do is add these two lines to the beginning of your PHP scripts:

<?php
@ini_set('zlib.output_compression_level', 1);
@ob_start('ob_gzhandler');
?>

This will automatically tell the server to compress the PHP page before sending it to the browser. However, sometimes this can causes excess load and a decrease in the speed of your website, but it’s hardly noticable.