【问题标题】:PHP - Read and write the same file hangsPHP - 读写同一个文件挂起
【发布时间】: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() 创建带有 ww+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(它保持正在加载)。

我需要什么

我需要能够加载文件并在写入文件时显示我想要显示的信息(通过 execFFMPEG 或其他 PHP 脚本),所以我可以使用一些更新进度百分比AJAX 调用。

额外信息

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

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

最好的问候。

【问题讨论】:

  • 您是否验证过 Log.txt 在进程 A 完成之前已写入并填充了内容?
  • 是的!它得到!事实上,我可以用记事本打开文件并查看文本,如果我关闭它并再次打开它,它仍然会被写入。
  • 但是,如果它没有被写入,我应该会看到一个空白屏幕,因为脚本已经加载了所有内容(它是,没有),但我得到一个“加载”屏幕,直到处理崩溃或完成...

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


【解决方案1】:

现在看来可以了。经过这么多没有工作的尝试,我做的唯一修改似乎有意义的是写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');

现在,如果有人告诉我这是否有意义,或者与我看不到的其他事情有关,我会非常高兴。

谢谢!

【讨论】:

  • 现在它在某些时候不再工作......它随机工作并停止工作。我会尝试检查我的 IIS 和 PHP 配置,因为我什么都不懂。无论如何,谢谢大家的时间!
猜你喜欢
  • 2017-03-02
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 2013-07-12
  • 2021-04-29
  • 2011-03-09
  • 1970-01-01
相关资源
最近更新 更多