PHP - 读取和写入相同的文件挂起

时间:2016-02-01 13:22:20

标签: php ffmpeg progress file-writing file-read

我正在尝试使用FFMPEG在服务器上制作一些视频,我需要做的是获得进程的进度。

我搜索了一下,发现this solution告诉我将日志写入文件,然后阅读并解析它。

问题

令我发疯的是我告诉FFMPEG - 用exec - (进程A )将日志写入文件,但是当我尝试阅读它时 - 用{ {1}} - (进程B )在进程A 完成(或中断PHP脚本)之前,它不会显示内容。

因此,当进程A 完成或者说“PHP脚本超时”时,我可以根据需要读取文件,刷新页面(进程B )并显示当时的内容。

我尝试了什么

我尝试使用file_get_contents()创建包含fopen()ww+参数的文件,使用 - 而不使用 - a。我还尝试使用fclose(),以防它更快地读取进程B 如果它知道它已经被锁定而不必等待,但是然后FFMPEG无法写入文件。

我也搜索了multithreading,但我认为必须有一种更简单,更简单的方法。

我也使用了CURL和HTTP上下文,如this link所示,但没有运气。

我也试过使用PHP-FFMPEG,但它不支持最后一个FFMPEG版本,所以我不能使用它。

当我之前说过“(或中断PHP脚本)”是因为我试图等待,当PHP得到超时时,进程B 工作正常,文件仍在更新

代码

进程A(fileA.php)

flock()

进程B(fileB.php)

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.phpexec或其他PHP脚本),这样我就可以更新一些AJAX调用的进度百分比。

额外信息

此时,我在使用Windows 7 Professional的IIS 7.5上使用PHP 5.4。

感谢大家的时间,帮助和耐心!

最好的问候。

1 个答案:

答案 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');

现在,如果有人告诉我这是否有意义,或者是否与我无法看到的其他内容有关,我会感到非常高兴。

谢谢!