【发布时间】:2016-05-09 23:16:12
【问题描述】:
我正在尝试使用 FFMPEG 对服务器上的视频进行一些处理,而我需要做的是获取进程的进度。
我搜索了一下,发现this solution 告诉我将日志写入文件,然后读取并解析它。
问题
让我发疯的是我告诉 FFMPEG - 使用 exec - (process A) 将日志写入文件,但是当我尝试读取它时 - 使用 file_get_contents() - (process B) 在 process A 完成(或中断 PHP 脚本)之前它不会显示内容。
所以,当 process A 完成或显示“PHP 脚本超时”时,我可以根据需要读取文件,刷新页面(process B ) 并显示当时的内容。
我尝试过的
我尝试使用 fopen() 创建带有 w、w+ 和 a 参数的文件,使用 - 和不使用 - fclose()。我也尝试过使用flock(),以防万一它知道它已经被锁定并且不必等待,它可以更快地读取到进程B,但是FFMPEG无法写入文件。
我也搜索过multithreading,但我认为一定有更简单更简单的方法。
正如this link 建议的那样,我也使用了 CURL 和 HTTP 上下文,但没有运气。
我也尝试过使用 PHP-FFMPEG,但它不支持最新的 FFMPEG 版本,所以我不能使用它。
我之前说“(或中断 PHP 脚本)”是因为我试图等待,当 PHP 超时时, 进程 B 工作正常,文件仍在更新.
代码
进程 A (fileA.php)
exec('ffmpeg -y -i input_file.mp4 output_file.avi 2> C:\Full\Path\To\File\log.txt 1>&2');
进程 B (fileB.php)
$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,几秒钟后,我在另一个 Chrome 选项卡上打开 fileB.php(它保持正在加载)。
我需要什么
我需要能够加载文件并在写入文件时显示我想要显示的信息(通过 exec 和 FFMPEG 或其他 PHP 脚本),所以我可以使用一些更新进度百分比AJAX 调用。
额外信息
此时,我在带有 Windows 7 Professional 的 IIS 7.5 上使用 PHP 5.4。
感谢大家的时间、帮助和耐心!
最好的问候。
【问题讨论】:
-
您是否验证过
Log.txt在进程 A 完成之前已写入并填充了内容? -
是的!它得到!事实上,我可以用记事本打开文件并查看文本,如果我关闭它并再次打开它,它仍然会被写入。
-
但是,如果它没有被写入,我应该会看到一个空白屏幕,因为脚本已经加载了所有内容(它是,没有),但我得到一个“加载”屏幕,直到处理崩溃或完成...
标签: php ffmpeg progress file-writing file-read