我正在尝试使用FFMPEG在服务器上制作一些视频,我需要做的是获得进程的进度。
我搜索了一下,发现this solution告诉我将日志写入文件,然后阅读并解析它。
令我发疯的是我告诉FFMPEG - 用exec
- (进程A )将日志写入文件,但是当我尝试阅读它时 - 用{ {1}} - (进程B )在进程A 完成(或中断PHP脚本)之前,它不会显示内容。
因此,当进程A 完成或者说“PHP脚本超时”时,我可以根据需要读取文件,刷新页面(进程B )并显示当时的内容。
我尝试使用file_get_contents()
创建包含fopen()
,w
和w+
参数的文件,使用 - 而不使用 - a
。我还尝试使用fclose()
,以防它更快地读取进程B 如果它知道它已经被锁定而不必等待,但是然后FFMPEG无法写入文件。
我也搜索了multithreading,但我认为必须有一种更简单,更简单的方法。
我也使用了CURL和HTTP上下文,如this link所示,但没有运气。
我也试过使用PHP-FFMPEG,但它不支持最后一个FFMPEG版本,所以我不能使用它。
当我之前说过“(或中断PHP脚本)”是因为我试图等待,当PHP得到超时时,进程B 工作正常,文件仍在更新的
flock()
exec('ffmpeg -y -i input_file.mp4 output_file.avi 2> C:\Full\Path\To\File\log.txt 1>&2');
我只是在Chrome标签页上打开$content = file_get_contents($file);
if($content){
//get duration of source
preg_match("/Duration: (.*?), start:/", $content, $matches);
$rawDuration = $matches[1];
//rawDuration is in 00:00:00.00 format. This converts it to seconds.
$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;
//get the time in the file that is already encoded
preg_match_all("/time=(.*?) bitrate/", $content, $matches);
$rawTime = array_pop($matches);
//this is needed if there is more than one match
if (is_array($rawTime)){$rawTime = array_pop($rawTime);}
//rawTime is in 00:00:00.00 format. This converts it to seconds.
$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;
//calculate the progress
$progress = round(($time/$duration) * 100);
echo "Duration: " . $duration . "<br>";
echo "Current Time: " . $time . "<br>";
echo "Progress: " . $progress . "%";
}
,几秒钟后,我在另一个Chrome标签页上打开fileA.php
(并保持加载)。
我需要能够加载文件并在编写文件时显示我想要显示的信息(通过fileB.php
和exec
或其他PHP脚本),这样我就可以更新一些AJAX调用的进度百分比。
此时,我在使用Windows 7 Professional的IIS 7.5上使用PHP 5.4。
感谢大家的时间,帮助和耐心!
最好的问候。
答案 0 :(得分:0)
现在似乎正在运作。在没有工作的情况下进行了这么多次尝试后,我做的唯一修改似乎就是在调用session_write_close()
命令之前编写exec
。所以,按照我的例子,它将是:
session_write_close();
exec('ffmpeg -y -i input_file.mp4 output_file.avi 2> C:\Full\Path\To\File\log.txt 1>&2');
现在,如果有人告诉我这是否有意义,或者是否与我无法看到的其他内容有关,我会感到非常高兴。
谢谢!