在PHP中ffmpeg进度百分比

时间:2018-04-05 22:11:58

标签: php ffmpeg

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最终输出总是100,所以用jquery很容易隐藏进度并显示下载按钮。

使用此命令更改 ffmpeg.php

$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输出是100(数千)以上的不同数字,jquery无法弄清楚ffmpeg进程是否已完成。

当ffmpeg完成工作时如何获得100?我认为我需要在progress.php中进行一些更改,因为progress.txt中的最终结果比以前更长。

1 个答案:

答案 0 :(得分:1)

我建议使用symfony进程组件https://symfony.com/doc/current/components/process.html

您有多种选择:

流程尚未完成时刷新进度

这允许您启动异步过程并检查它是否已完成。

$process = new Process('ffmpeg -i ".$image." -i ".$music." video.avi 1> progress.txt');
$process->run(function ($type, $data) {
    echo $data;
    fflush();
});

更复杂的方法是获取进程ID并检查该进程是否仍然存在以及后续请求。

返回包含进程ID的响应,并使用进度更新REDIS / cache / database

更复杂的方法是获取进程ID并检查该进程是否仍然存在以及后续请求。

// 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()]);