Reputation: 368
ffmpeg.php
$sCmd = "ffmpeg -i ".$image." -i ".$music." video.avi 1> progress.txt";
$proc = popen($sCmd." 2>&1", "r");
progress.php
$content = @file_get_contents('progress.txt');
if($content){
preg_match("/Duration: (.*?), start:/", $content, $matches);
$rawDuration = $matches[1];
$ar = array_reverse(explode(":", $rawDuration));
$duration = floatval($ar[0]);
if (!empty($ar[1])) $duration += intval($ar[1]) * 60;
if (!empty($ar[2])) $duration += intval($ar[2]) * 60 * 60;
preg_match_all("/time=(.*?) bitrate/", $content, $matches);
$rawTime = array_pop($matches);
if (is_array($rawTime)){$rawTime = array_pop($rawTime);}
$ar = array_reverse(explode(":", $rawTime));
$time = floatval($ar[0]);
if (!empty($ar[1])) $time += intval($ar[1]) * 60;
if (!empty($ar[2])) $time += intval($ar[2]) * 60 * 60;
$progress = round(($time/$duration) * 100);
echo $progress;
}
progress.php final output was always 100, so it was easy with jquery to hide progress and show download button.
BUT after changing ffmpeg.php with this command:
$sCmd = "ffmpeg -loop 1 -r 1 -i ".$image." -i ".$music." -c:a copy -shortest video.avi 1> progress.txt";
$proc = popen($sCmd." 2>&1", "r");
progress.php output is different numbers above 100(thousands) and jquery can't figure out ffmpeg process finished or not.
How to get 100 when ffmpeg finishs working? I think i need some changes in progress.php because final result in progress.txt is longer than before.
Upvotes: 1
Views: 1735
Reputation: 4468
I would recommend using symfony process component https://symfony.com/doc/current/components/process.html .
You have multiple options:
Flushing progress while the process has not finished
This allow you to start an async process and check if it has finished or not.
$process = new Process('ffmpeg -i ".$image." -i ".$music." video.avi 1> progress.txt');
$process->run(function ($type, $data) {
echo $data;
fflush();
});
A more complicated way is to get the process ID and check if that process is still alive with subsequent requests.
Return a response with the process id and update REDIS/cache/database with the progress
A more complicated way is to get the process ID and check if that process is still alive with subsequent requests.
// Setup process and an std output that updates redis
$process=new Process(...);
//Start process
$process->start(function ($type, $data) use ($redisService, $process){
$pid=$process->getPid();
$redisService->received($pid, $type, $data);
});
$pid=$process->getPid();
return JsonResponse(["pid"=>$pid, "running"=>$process->isRunning()]);
Upvotes: 1