Manual FFMpeg video transcoding from PHP script

Hi all

The dreamhost flv encoder inspired me to create my own script for my own purposes (the script is below).

I ask the ffmpeg process to only use 1 thread in order to not weigh down the server too much. But I feel like perhaps it’s still quite a heavy task.

So I’m wondering whether what i’m doing is pretty much equivalent to the automatic flv encoder by Dreamhost (i.e. i’ve got nothing to worry about) or whether there’s a much more sensible way to go about this activity.

Basically, I don’t want to annoy any admins or other users, but want to have much more control over what happens when videos are compressed.

Perhaps the Dreamhost encoder actually performs the encoding on a (separate computer as to not weigh down the server?)

Thanks and regards


<?php $nVideos = 0; //these 2 variables are used to render an absolute path //this is important for the the flash flv player //the base url $base_url = ""; //the path on your server where the base url points to //we presume that the flv's are somewhere beneath this path $base_path = "/home/kimchiandchips/kimchiandchips/"; traverse("."); function traverse($path) { echo("


\n"); global $allhtml, $thishtml; $d = dir($path); while (false !== ($entry = $d->read())) { $fullpath = $path . "/" . $entry; if (substr($fullpath,-1) == ".") continue; if (is_dir($fullpath)) traverse($fullpath); if (substr($fullpath, -4) == ".MOV") compress($fullpath); } $d->close(); } function compress ($path) { global $nVideos; $mov = $path; $flv = substr($path, 0, -3) . "flv"; $jpg = substr($path, 0, -3) . "jpg"; shell_exec("ffmpeg -threads 1 -y -i \"" . $mov . "\" -s 1280x720 -f flv -vcodec flv -b 2000000 -ab 128000 -ar 44100 \"" . $flv . "\""); $size = 0; $offset = 2.0; $runtimes = 0; while ($size == 0 && $runtimes < 5) { $command = sprintf("ffmpeg -threads 1 -y -itsoffset -%.1f -i \"" . $mov . "\" -vcodec mjpeg -vframes 1 -s 480x270 \"" . $jpg . "\"", $offset); shell_exec($command); $size = filesize($jpg); $offset /= 2.0; $runtimes++; } $nVideos++; ?>
<h2><? echo $mov; ?></h2>
<div id="v<? echo $nVideos; ?>">
<a href="">Get the Flash Player</a> to see this video.
<script type="text/javascript" src=""></script>
<script type="text/javascript">
var swf = new SWFObject("", "mpl", "480", "270", 8);
swf.addParam("allowfullscreen", "true");
swf.addParam("allowscriptaccess", "always");
swf.addVariable("file", "<? echo getUrl($flv); ?>");
swf.addVariable("image", "<? echo $jpg ?>");
swf.write("v<? echo $nVideos; ?>");
<a href="<? echo $mov; ?>">Original</a>
<a href="<? echo $flv; ?>">FLV</a>
<br />



function getUrl($path) {
global $base_path, $base_url;

$real = realpath($path);
$url = str_replace($base_path, $base_url, $real);
//$url = str_replace(" ", "%20", $url);

return $url;


The settings we use for the video encoder are online at:

The main significant difference between what you’re using and what we use is that we encode to H264, using libx264, rather than flv. H264 has supported by Flash for quite a few years (it’s used by Youtube, for instance), and gives far better visual results relative to filesize.

We don’t run video encoding on separate servers. The feature simply isn’t used frequently enough for that to be worthwhile… yet.

thanks for the response andrew!

i removed the threads=1 flag and used nice instead (looks like a better option all round).

i couldn’t get x264 working as it was complaining that it couldn’t find the presets file (even when local, relative or absolute path).
Then I went on a hunt for directly putting the flags into the command line and drew more blanks.
So stuck with old flv codec
It’s not much of an issue, but you’re right in that x264 would be nicer

this could be worked well into something like Gallery3
would need to setup some kind of cron task to perform the transcoding in a queue in the background.

Ah, it looks as though we’ve made some changes since that page was written. I’ve updated the command on that page; the main significant change is that we’re simply using “-vpre fast” instead of a presets file.