Entry

code : ffmpeg and ffmpeg-php demo flv conversion system

here is the code for a Proof of concept i did a few months ago. Its a demo ffmpeg and ffmpeg-php video conversion system that will also generate thumbnails. you either upload a file to the server (for large files) or select the file to upload (small files).
the code is offered as is. Please note [...]

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Google
  • Technorati
  • Slashdot
  • LinkedIn
  • E-mail this story to a friend!

here is the code for a Proof of concept i did a few months ago. Its a demo ffmpeg and ffmpeg-php video conversion system that will also generate thumbnails. you either upload a file to the server (for large files) or select the file to upload (small files).

the code is offered as is. Please note this is a first version POC so the code is choppy and theres functionality missing, probably also alot of beta testing code.

*update: wordpress converts some of the characters into invalid code, so download / copy the source file here
http://elsid.net/wp-content/uploads/2007/10/ffmpeg_convert.php.txt

*update: the file works on php5, on at least it did when i tested. change the folder / url path to whatever your using.

you can view the source below

<?php
//error_reporting(2047);
//setup directory vars
$url_dir = "/video-convert-alpha/";
$url_folder="uploads";
$upload_dir = realpath($url_folder)."/";//"";
$url_dir="http://".$_SERVER['HTTP_HOST'].$url_dir.$url_folder."/";

//echo "uploads : ". $upload_dir;
function time_stamp()
{
return gmdate("YmdHis");
}
///my trusty old upload function
function upload_from_form($file_item)
{
global $_FILES, $upload_dir, $url_dir;
//echo "uploading<br>";
if (!empty($_FILES[$file_item]['name'])) {
//echo $_FILES[$file_item]['tmp_name'];

if($_FILES[$file_item]['size']*1==0){
echo "File : ".$_FILES[$file_item]['name']." is either empty or exceeds the file size limit, please reduce the size of this document, check the file, or contact Greg to increase the limit";
return "%";
}else{

$file_name = str_replace(" ", "_" , $_FILES[$file_item]['name']);
$file_name = str_replace("’", "_" ,$file_name);
$file_name = str_replace("\\", "_" ,$file_name);
$file_name = str_replace("#", "_" ,$file_name);
$file_name = str_replace("&", "_" ,$file_name);
$file_name = str_replace("\"", "_" ,$file_name);
$file_name = str_replace("(", "_" ,$file_name);
$file_name = str_replace(")", "_" ,$file_name);
$file_name = str_replace("@", "_" ,$file_name);
$file_name = str_replace("\$", "_" ,$file_name);
$file_name = str_replace("*", "_" ,$file_name);
$file_name = str_replace("~", "_" ,$file_name);
$file_name = str_replace("`", "_" ,$file_name);
$file_name = str_replace("+", "_" ,$file_name);
$file_name = str_replace("=", "_" ,$file_name);
$file_name = str_replace("|", "_" ,$file_name);
$file_name= time_stamp() . "_" . $file_name;

if (!file_exists($upload_dir . $file_name)) {
$file_loc = copy($_FILES[$file_item]['tmp_name'], $upload_dir . $file_name);
} else {
$file_name = time_stamp() . "_" . $file_name;
$file_loc = copy($_FILES[$file_item]['tmp_name'], $upload_dir . $file_name);
}
if ($file_loc != false) {
$file_loc = $upload_dir . $file_name;

return $file_loc;
} else {
echo "Could not find file : ".$_FILES[$file_item]['name'];
return "%";

} }
} else {
echo "upload failed<br>";
return "%";
}

}

 

 

$flvtool2Path=’/usr/bin/flvtool2′;
$ffmpegPath=’/usr/bin/ffmpeg’;
$qualitySettings=array(’low’=>’-ar 22050 -ab 32′,’med’=>’-ab 48k -ac 1 -ar 44100 -deinterlace -nr 500 -croptop 4 -cropbottom 4 -cropleft 8 -cropright 8 -aspect 4:3 -r 25 -b 270k -me_range 25 -i_qfactor 0.71 -g 500′,’high’=>’-ab 64k -ac 2 -ar 44100 -deinterlace -nr 500 -croptop 4 -cropbottom 4 -cropleft 8 -cropright 8 -aspect 4:3 -r 25 -b 650k -me_range 25 -i_qfactor 0.71 -g 500′);
$reqFields="email|password|quality|size|format";
$reqFields=explode("|",$reqFields);
$filesMessage="";
$formatSettings=array(’flv’=>’-f flv -acodec mp3′);

$badSubmit=false;
//check for post
if(!empty($_POST['password'])){
//check for pass and user
//echo "checking pass<br>";
if(trim($_POST['password'])==’ricecrispytreat’ && !empty($_POST['email'])){
//check submission
//echo "password excepted<br>";
for($i=0;$i<count($reqFields);$i++){
if(empty($_POST[$reqFields[$i]])){
$badSubmit=true;
echo $reqFields[$i]." not completed<br>";
break;

}
}
//ok we’ve done basic checking - now lets get to work
if(!$badSubmit){
//first lets make sure we have a file
if(!empty($_POST['serverPath']) || !empty($_FILES['fileUploaded'])){
if(!empty($_FILES['fileUploaded'])){

$processFile=upload_from_form(’fileUploaded’);
}else{
$processFile=$_POST['serverPath'];
$processFile=realpath($processFile);
if(!file_exists($processFile)){
$processFile="%";
}

}

 

}else{
$processFile=’%';
}
if($processFile==’%'){
echo " either you have entered a non valid path, or your uploaded file wasn’t in the right format<br>";

}
//end file checks
if($processFile!=’%'){
//now lets see if we have thumbnails to make
if(isset($_POST['useThumbs'])){
//echo "thumbnailing<br>";
//defaults
$maxThumbnails=5;
$thumbnailsFrom=1;

//if they were set
if(!empty($_POST['thumbsMax'])){
$maxThumbnails=$_POST['thumbsMax'];
$maxThumbnails*=1;
}

if(!empty($_POST['thumbStart'])){
$thumbnailsFrom=$_POST['thumbStart'];
$thumbnailsFrom*=1;
}
//echo "making thumbnails";
//lets do the work
//setup ffmpeg-php object, and needed vars
$ffmpegObj = new ffmpeg_movie($processFile);
$totalTime=$ffmpegObj->getDuration();
$frameRate=$ffmpegObj->getFrameRate();
$thumbIncrements=(($totalTime*$frameRate)-($thumbnailsFrom*$frameRate))/$maxThumbnails;
$wide=$ffmpegObj->getFrameWidth();
$high=$ffmpegObj->getFrameHeight();
$startFrame=$thumbnailsFrom*$frameRate;
//echo "frame rate: ".$frameRate;
$filesMessage.="ThumbNails can be viewed at :<p>";
//echo "thumbs being processed now";
for($t=0;$t<$maxThumbnails;$t++){
//$image= @imagecreatetruecolor($wide,$high);
$thumbFile=$processFile.".".$t.".png";
$currFrame=floor($startFrame+($thumbIncrements*$t));
//echo "<br>thumb of frame $currFrame: ".$thumbFile;
$thumb=$ffmpegObj->getFrame($currFrame);

if ($thumb) {
$thumbImage = $thumb->toGDImage();
if ($thumbImage) {
imagepng($thumbImage,$thumbFile);
imagedestroy($thumbImage);
}
}
//echo "<br>saved";
$thumbUrl=$url_dir."".basename($thumbFile);
$filesMessage.="<a href=’".$thumbUrl."’>".$thumbUrl."</a><br>";

}
$filesMessage.="</p>";

}

//echo "outside thumbs";
$newFile=substr($processFile,0,strrpos($processFile,".")).".".$_POST['format'];
$ffmpegCall=$ffmpegPath." -i ".$processFile." ".$qualitySettings[$_POST['quality']]." ".$formatSettings[$_POST['format']]." -s ".$_POST['size']." ".$newFile;

$flvtool2Call=flvtool2Path." -U stdin ".$newFile."";
$encodeCall=$ffmpegCall." | ".$flvtool2Call;
exec($encodeCall);
$fileUrl=$url_dir."".basename($newFile);
$filesMessage.="<p>You Can Now View / Download Your Video @<a href=’".$fileUrl."’>".$fileUrl."</a><br></p>";
$user=$_POST['email'];
mail($user,basename($newFile),$filesMessage);
$foo=@unlink($processFile);
//echo $fileMessage;
}
}

}

}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post" enctype="multipart/form-data" name="form1" id="form1">
<table width="100%" border="1" cellpadding="1" cellspacing="1" bordercolor="#FF0000" bgcolor="#CCCCCC">
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><table width="100%" border="0" cellspacing="1" cellpadding="1">
<tr>
<td colspan="5"><font color="#ff0000"><?php echo $filesMessage;?></font></td>
</tr>
<tr>
<td colspan="5">video convert .01 alpha</td>
</tr>
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td colspan="3">this isn’t pretty, but it gets the job done. consider this a POC. More options to come, and maybe an ajax or flash interface. Probaly Flash :)</td>
</tr>
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td colspan="3">Access and reporting</td>
</tr>
<tr>
<td colspan="3"><label for="email">enter your email address </label>
<input type="text" name="email" id="email" />
<br />
This will be used to notify you once conversion has completed.</td>
</tr>
<tr>
<td colspan="3"><label for="password">Enter the video system password</label>
<input type="text" name="password" id="password" value=’ricecrispytreat’ /></td>
</tr>
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td colspan="3">video file—</td>
</tr>
<tr>
<td><label for="serverPath">file server path</label>
<input type="text" name="serverPath" id="serverPath" /></td>
<td>or</td>
<td><label for="fileUploaded">upload file</label>
<input type="file" name="fileUploaded" id="fileUploaded" /></td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td colspan="3">thumbnails</td>
</tr>
<tr>
<td><label for="label">Make thumbnails</label>
<input type="checkbox" name="useThumbs" id="useThumbs" />
<label for="useThumbs"></label></td>
<td><label for="thumbsMax">how many</label>
<input type="text" name="thumbsMax" id="thumbsMax" />
- defaults to 5 if not set</td>
<td><label for="thumbStart">from what postion</label>
<input type="text" name="thumbStart" id="thumbStart" />
<label for="thumbsMax"> (time in seconds) so 6:05 would be 6*60+5= 365 - defaults to 0 if not set</label></td>
</tr>
<tr>
<td colspan="3">&nbsp;</td>
</tr>
<tr>
<td colspan="3">video settings</td>
</tr>
<tr>
<td><label for="quality">Select quality</label>
<select name="quality" id="quality">
<option value="low">Low</option>
<option value="med">Medium</option>
<option value="high" selected="selected">High</option>
</select></td>
<td><label for="size">Select Size</label>
<select name="size" id="size">
<option value="160×120">160×120</option>
<option value="320×240" selected="selected">320×240</option>
<option value="480×360">480×360</option>
<option value="640×480">640×480</option>
<option value="720×480">720×480</option>
<option value="1024×768">1024×768</option>
<option value="1280×720">1280×720</option>
<option value="1280×1024">1280×1024</option>
<option value="1600×1200">1600×1200</option>
<option value="1920×1080">1920×1080</option>
</select> </td>
<td><label for="format">select format</label>
<select name="format" id="format">
<option value="flv" selected="selected">Flash Video</option>
</select> </td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>Audio Settings</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><input type="checkbox" name="noVideo" id="noVideo" />
<label for="noVideo">Audio Only - not working yet</label></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</table></td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td><label for="button"></label>
<input type="submit" name="button" id="button" value="Submit" /></td>
<td>&nbsp;</td>
</tr>
</table>
</form>
</body>
</html>

Hope this helps someone

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • StumbleUpon
  • Google
  • Technorati
  • Slashdot
  • LinkedIn
  • E-mail this story to a friend!

18 Comments

  1. September 24, 2007 at 7:33 am | Permalink

    I cut and pasted your code and Noda zip nothing dont work, Do you have a working example as this is all new to me.

  2. September 24, 2007 at 8:21 am | Permalink

    what version of php? this was written / tested with php4. also do you have ffmpeg-php installed?

  3. September 24, 2007 at 8:25 am | Permalink

    yes I all the ffmpeg-php installed and it’s showing up in phpinfo just fine.
    I am using php-5 and the script will not work on my server.
    thanks

  4. September 24, 2007 at 8:29 am | Permalink

    if your getting a blank page you need to force error reporting, then post what’s the error response, and i’ll try to make the script php5 compatible.

    i posted on forcing errors here: http://elsid.net/2007/08/31/tip-force-php-error-display/

  5. September 24, 2007 at 8:34 am | Permalink

    Great I am sure it’s something small it always is LOL

    I am very pleased that you jumped on this as fast as you did. if you want I can upload the file to my main server and let you review the status. I would assume “bad woding on my part” that the file is cut and past from
    correct and not split up into more then one file ie ” html and php “?

  6. September 24, 2007 at 8:36 am | Permalink

    nope one file, an ugly file, but one file. lol.

  7. September 24, 2007 at 8:38 am | Permalink

    send me the link and we’ll see if we can find the php5 issue

  8. October 11, 2007 at 9:51 am | Permalink

    the source file has been uploaded to resolve errors. wordpress converts some of the characters which makes the code invalid. you can download or copy an paste from :

    http://elsid.net/wp-content/uploads/2007/10/ffmpeg_convert.php.txt

  9. November 23, 2007 at 9:18 am | Permalink

    I just wanted to ask exactly what all I would have to change throughout the code to make it work on my server. If you could send me your example highlighting the changes I would have to make I think Icould get this to work.

  10. November 24, 2007 at 8:52 am | Permalink

    hey josh, just change or remove $url_dir to the folder that the file is running in. also download the updated file

    Sid

  11. November 26, 2007 at 11:47 am | Permalink

    if you could could you send me in my email the script that your using so I can see the changes you made throughout. if not thats cool but I think it would help me out alot to compare both.

  12. November 26, 2007 at 11:51 am | Permalink

    one more question. will this code play the video or just make thumbnails?

  13. November 26, 2007 at 12:27 pm | Permalink

    http://elsid.net/wp-content/uploads/2007/10/ffmpeg_convert.php.txt

    the file is a basic poc system that does thumbnailing and conversion

  14. November 29, 2007 at 4:57 am | Permalink

    hi admin,

    i have a site having same requirment where someone upload video on site will convert to flv format. i m using php5 and using your code ,give me no error but not convert the file to flv. here is you use $flvtool2Path=’/usr/bin/flvtool2′; and $ffmpegPath=’/usr/bin/ffmpeg’; where this two variable($flvtool2path and $ffmpegPath) point to , is it point to flvtool2 folder or point to any class of flvtool , please explain to me,i apperciat your help. any other chages make to this script. or only path to be set, i m using linux server.

    thanks an advance , please reply to my email address, if you have any other script to solve my problem i will be very thankful to you.

    thanks

    irfan

  15. May 23, 2008 at 1:50 am | Permalink

    Hello Friends,

    I am using ffmpeg to create thumbnail, and it works great … BUT THE ISSUE is with converting the avi file to flv… it create the .flv file but it has null content …

    Please help me I have stuck here form last 2 days … Any help will be greatly appreciated …

    Thanks in advance ,
    Justin

  16. August 28, 2008 at 2:31 am | Permalink

    Why you do not use free FFlib.NET? See http://www.intuitive.sk/fflib/ :o)

  17. November 5, 2008 at 8:55 pm | Permalink

    It’s fun. ATP Subscribe to the RCC perhaps

  18. November 26, 2008 at 8:07 am | Permalink

    Justin

    Maybe the codec used by the avi isn’t supported by ffmpeg. I had trouble coz ffmpeg doesn’t support Indeo 5 which is what a lot of web cams use.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*