在windows下使用php中的shell_exec作为后台进程运行ffmpeg命令


Running ffmpeg command using shell_exec in php as a background process in windows

我正在尝试将视频从.mp4转换为.flv在php使用:

shell_exec("ffmpeg -i input.mp4 output.flv 1>output.txt 2>&1");

我还在output.txt文件中输出整个过程,以便在javascript中创建进度条时使用它(这不是这里的问题)。

问题是:如果视频(input.mp4)大小>50Mb,那么完成shell_exec需要太长时间(>30秒)。这会不必要地挂起UI。

所以我想知道的是:

  • 是否有办法使shell_exec与脚本的其余部分一起工作?

  • 我只需要通过php脚本启动ffmpeg.exe,然后php脚本可以终止。

  • 一旦进程被启动,javascript将开始它的魔术(在客户端)。

所以我需要执行shell_exec异步。与脚本的其余部分。一旦进程启动,脚本应该通过简单的echo通知客户端。它不应该等待ffmpeg.exe完成它的工作。这可能吗?

我在SO上看到过几个类似的问题,其中很多都描述了同样的问题

,

在后台运行ffmpeg进程

异步运行PHP任务

ffmpeg进度条- PHP编码百分比

ffmpeg可以显示进度条吗?

等。

他们都使用linux操作系统或使用curl。我使用windows 8 (wamp没有卷曲和任何其他附加组件,除了ffmpeg.exe)。

所以这是可能的吗?这里的专家能再帮我一次吗?

这里有一个重要的注意事项。ffmpeg命令行工具使用stderr输出错误日志消息,stdout保留用于可能使用的管道(将从ffmpeg生成的输出媒体流重定向到其他命令行工具)。也就是说,如果您在后台运行ffmpeg,您很可能希望将标准错误重定向到一个日志文件,以便以后能够检查它。

另一件需要注意的事情是标准INPUT (stdin)。命令行ffmpeg工具被设计为一个交互式实用程序,它接受用户的输入(通常来自键盘),并在用户当前的屏幕/终端上报告错误日志。当我们在后台运行ffmpeg时,我们希望告诉ffmpeg不应该接受(也不等待)来自标准输入的输入。我们可以告诉ffmpeg,再次使用I/O重定向。

<?php

echo "Starting ffmpeg...'n'n";
echo shell_exec("ffmpeg -y -i input.avi output.avi </dev/null >/dev/null 2>/var
/log/ffmpeg.log &");
echo "Done.'n";
?>

"-y"选项用于自动覆盖输出文件(output.avi),而不要求是/否确认。如果需要相反的场景,即在输出文件已经存在的情况下自动取消整个过程,则使用"-n"选项。

一些PHP库允许将ffmpeg调用包装到PHP对象中,如果您不喜欢使用命令行,还可以提供很好的语法。其中之一是积极维护的PHP-FFMpeg。除了安装PHP组件外,它只要求您下载最新的ffmpeg和ffprobe构建。然后可以像这样运行PHP代码:

$ffmpeg = FFMpeg'FFMpeg::create();
$video = $ffmpeg->open('video.mpg');
$video->filters()->resize(new FFMpeg'Coordinate'Dimension(320, 240))->synchronize();
$video->save(new FFMpeg'Format'Video'X264(), 'export-x264.mp4')

注意:ffmpeg-php是一个自2007年以来没有开发的扩展(并且需要"ffmpeg-0.4.9_pre1或更高版本"),这意味着您只能使用非常旧的ffmpeg版本,而无法将其更新到最新版本。由于每天都在ffmpeg的代码中进行了大量的更改/改进,因此ffmpeg-php与最新的ffmpeg不兼容。

是的,您可以在windows中使用以下命令在后台运行FFmpeg,而无需重新加载整个页面。

 pclose(popen("start /B C:/xampp/htdocs/video/bin/ffmpeg  -i input.mp4 output.flv , r"));

这是ffmpeg在我的电脑的位置,你可以使用你的ffmpeg的位置。