Php exec() isn't running ffmpeg?

software development

#1

I’m trying to execute ffmpeg from within a php script using exec(). I’ve got the following ffmpeg command, which does work from ssh: /home/magaresa/ffmpeg/bin/ffmpeg -i /home/magaresa/magaresa.dreamhosters.com/web/uploads/1/06-8-20-Test.avi -vcodec png -vframes 1 -an -f rawvideo -s 320x240 /home/magaresa/magaresa.dreamhosters.com/web/uploads/1/06-8-20-Test.png

However, when I place this command as a string inside a php script as exec($command, $output); it doesn’t seem to execute; no errors in the logs or in $output. As a sanity check, I passed in ls as the command instead of the ffmpeg call, and it worked fine. PHP is running as the same user that can execute this command from the shell.

I’m using PHP 5.1.4 (my build, not DreamHost’s), and phpinfo() is available at: http://magaresa.dreamhosters.com/test.php

Any thoughts?


#2

Figured it out on my own. The ffmpeg instance I was using has an external library dependency (the lame mp3 encoder), which I was setting in my .bashrc, so was available when I executed the command through the shell. But when it was being done through php/cgi, of course, the shell isn’t being used, so that variable wasn’t being set.


#3

i found a solution here:
http://lists.mplayerhq.hu/pipermail/ffmpeg-user/2006-October/004773.html

<?
$output = runExternal( "ffmpeg .....", &$code );
if( $code ) echo "bad transcoding:\n" else echo "looks good:\n";

print $output;

function runExternal( $cmd, &$code ) {

$descriptorspec = array(
0 => array("pipe", "r"),  // stdin is a pipe that the child will 
read from
1 => array("pipe", "w"),  // stdout is a pipe that the child will 
write to
2 => array("pipe", "w") // stderr is a file to write to
);

$pipes= array();
$process = proc_open($cmd, $descriptorspec, $pipes);

$output= "";

if (!is_resource($process)) return false;

#close child's input imidiately
fclose($pipes[0]);

stream_set_blocking($pipes[1],false);
stream_set_blocking($pipes[2],false);

$todo= array($pipes[1],$pipes[2]);

while( true ) {
$read= array();
if( !feof($pipes[1]) ) $read[]= $pipes[1];
if( !feof($pipes[2]) ) $read[]= $pipes[2];

if (!$read) break;

$ready= stream_select($read, $write=NULL, $ex= NULL, 2);

if ($ready === false) {
break; #should never happen - something died
}

foreach ($read as $r) {
$s= fread($r,1024);
$output.= $s;
}
}

fclose($pipes[1]);
fclose($pipes[2]);

$code= proc_close($process);

return $output;
}
?>