I am using jQuery upload file plugin, and when videos are uploaded, they are converted using FFMPEG. For short sized files everything works perfectly but when I try to upload bigger files, nothing is returned in the response. I thought that this could me max_execution_time
issue so I have removed the limit but still it happens, but when I see the folder, the files are converted completely and entered into database so everything seems to work of large files except it doesn't echo
. I tried to remove one FFMPEG conversion statement and convert file to just one size but still the result is same for large files.
and I see this result
Here is my PHP code
$default = ini_get('max_execution_time');
set_time_limit(0);
$fileName = $_FILES["myfile"]["name"];
$fileName = str_ireplace(' ', '_', $fileName);
$fn = $_FILES["myfile"]["name"];
$i = 1;
$actual_name = pathinfo($fileName,PATHINFO_FILENAME);
$original_name = $actual_name;
$extension = strtolower (pathinfo($fileName, PATHINFO_EXTENSION));
while(file_exists($output_dir.$fileName))
{
$actual_name = (string)$original_name.$i;
$fileName = $actual_name.".".$extension;
$filetoconvert = $actual_name.".mp4";
$filetoconvertSD=$actual_name."SD.mp4";
$i++;
}
//echo $fileName;
move_uploaded_file($_FILES["myfile"]["tmp_name"],$output_dir.$fileName);
$url = $output_dir1.$fileName;
$outputnameSD="";
$time="";
$del_url = $output_dir.$fileName;
$i = 1;
while(file_exists($output_dir.$filetoconvert))
{
$actual_name = (string)$original_name.$i;
$fileName = $actual_name.".mp4";
$filetoconvert = $actual_name.".mp4";
$filetoconvertSD=$actual_name."SD.mp4";
$i++;
}
$outputname = $output_dir1.$filetoconvert;
$outputnameSD=$output_dir1.$filetoconvertSD;
$videofile="/var/www/html/".$url;
$xyz = shell_exec("ffmpeg -i \"{$videofile}\" 2>&1"); //Get duration
$search='/Duration: (.*?),/';
preg_match($search, $xyz, $matches);
$tim=explode(".", $matches[1]);
$time=$tim[0];
$ret = exec(' ffmpeg -i /var/www/html/'.$url.' -acodec libfaac -b:a 128k -vcodec libx264 -preset fast -vprofile baseline -b:v 400k -maxrate 400k -bufsize 800k -crf 26 -flags +aic+mv4 /var/www/html/'.$outputnameSD, $out, $err);
$ret = exec(' ffmpeg -i /var/www/html/'.$url.' -acodec libfaac -b:a 196k -vcodec libx264 -preset fast -vprofile high -b:v 1000k -crf 20 -flags +aic+mv4 /var/www/html/'.$outputname, $out, $err);
unlink($del_url);
$url = $output_dir1.$fileName;
Database QUERY HERE
$ret[]= $fileName;
echo '<li>
'.$fileName.'
</li>';
set_time_limit($default);
Incase someone encounter same issue, than this is how I fixed it. I changed the ffmpeg code to
The last part
>/dev/null 2>/dev/null &
lets it believe that exec command is executed while it runs at the background. The only drawback of this solution is that you can't delete the original file after conversion if you want to like I had to.To cater this solution, the answer provided by @hdezela is the way to go about it i.e. to write a cronjob
I had a similar issue when doing the same thing and wasted many hours playing around with all sorts of timeouts. The ones involved are php execution time, server post timeout, server response timeout and javascript timers.
In the end I found it better to break up the process into parts:
The upload form just uploads and executes steps 1 and 2. On the same page I have js that pings my monitor script and shows the relevant info.
This helps a few things. First the user can upload and forget the files without having to sit ther waiting for each one to be processed. Second I can restart the process at any step of the way without having the user go back to the beginning. And finally everything is faster since I can run uploads and conversions in parallel and they each have their own process that can be independently managed.