使用 PHP 在后台运行管道 shell 命令
我正在尝试使用 PHP 在后台执行命令,以便 Web 应用程序可以继续加载,但到目前为止还没有运气。
该命令适用于实时流媒体应用程序,因此涉及以下内容:
<stream pre-process> | ffmpeg <options> | <stream segmenter>
我可以将上述内容粘贴到脚本中,并在 bash 的后台使用 & 很好地执行它,但这在 PHP 中不起作用。我之前也尝试过使用 nohup 和“nohup & echo $!”,但没有运气。
我还将所有 stderr 通过管道传输到 /dev/null,并且我可以在 apache 日志中验证当我执行命令(但它正在执行)时没有生成输出。
下面的一些示例代码.. 在该代码完成之后我所拥有的内容不会执行,直到完成为止,这是很长一段时间。
function streamVid ($mid, $width, $height, $br) {
$cdir = "./temp";
$zmstrm = "zmstreamer -m ".$mid." 2> /dev/null";
$seg = "segmenter - 3 ".$cdir."/sample_".$mid." ".$cdir."/stream_".$mid.".m3u8 ./ 2>/dev/null";
$ffparms = "-f mpegts -analyzeduration 0 -acodec copy -s ".$width."x".$height." -vcodec libx264 -b ".$br." -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate ".$br." -bufsize ".$br." -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -analyzeduration 0 -async 2 - 2> /dev/null";
$url = $zmstrm . " | ffmpeg -t 10 -analyzeduration 0 -i - ". $ffparms . " | " . $seg;
shell_exec("nohup ". $url." & echo $!");
ob_flush();
flush();
}
I'm trying to execute a command in the background using PHP so the web application can continue to load, but having no luck so far.
The command is for a live streaming application, so involves the following:
<stream pre-process> | ffmpeg <options> | <stream segmenter>
I can stick the above in a script and execute it fine in the background in bash with &, but this doesn't work in PHP. I also tried using nohup before, and "nohup & echo $!", but no luck.
I am also piping all of stderr to /dev/null, and I can verify in apache logs that there is no output generated when I execute the command (but it is executing).
Some example code below.. what I have after this code doesn't execute until this finishes, which is a long time.
function streamVid ($mid, $width, $height, $br) {
$cdir = "./temp";
$zmstrm = "zmstreamer -m ".$mid." 2> /dev/null";
$seg = "segmenter - 3 ".$cdir."/sample_".$mid." ".$cdir."/stream_".$mid.".m3u8 ./ 2>/dev/null";
$ffparms = "-f mpegts -analyzeduration 0 -acodec copy -s ".$width."x".$height." -vcodec libx264 -b ".$br." -flags +loop -cmp +chroma -partitions +parti4x4+partp8x8+partb8x8 -subq 5 -trellis 1 -refs 1 -coder 0 -me_range 16 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -bt 200k -maxrate ".$br." -bufsize ".$br." -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -analyzeduration 0 -async 2 - 2> /dev/null";
$url = $zmstrm . " | ffmpeg -t 10 -analyzeduration 0 -i - ". $ffparms . " | " . $seg;
shell_exec("nohup ". $url." & echo $!");
ob_flush();
flush();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果需要流式输出操作结果,请使用 system 或 passthru 方法,或使用 popen 或 proc_open 来完全控制进程的输入和输出。
一般来说,由 Web 服务器触发的 PHP 脚本旨在生成页面并退出。它们不是执行视频编码等后台任务的最佳场所,您的网络服务器将对程序执行时间施加限制,并且很难从浏览器获取状态信息(它会显示为挂起)。
最好的选择是使用 Python(或 PHP)等语言创建一个单独的守护进程,该进程将在您的计算机上运行。当您的 Web 脚本需要对视频进行转码时,它们可以将必要的信息放入可由守护进程轮询的数据库或文件中。守护进程还可以使用状态信息更新数据库。
一般来说,您的网络服务页面应该尽可能“非阻塞”,这意味着如果某些事情需要花费超过一两秒的时间,请在后台执行并在您的网站上创建页面以允许用户查看操作状态并对其进行操作。
If you need to stream out the result of an operation, use the system or passthru methods, or use popen or proc_open to have full control over the input and output of the process.
In general, the PHP scripts which are triggered by your web server are meant to generate a page and exit. They are not the best place to do background tasks such as video encoding, your web server will impost a limit on the programs execution time, and it will be difficult to get status information from your browser (it will appear to hang).
Your best bet is to create a separate daemon process in a language like Python (or PHP) which will run on your computer. When your web scripts need to transcode a video, they can place the necessary information in a database or file which can be polled by the daemon process. The daemon process can also update the database with status information.
In general, your web served pages should be as "non-blocking" as is possible, meaning if something is going to take more than a second or two, do it in the background and create pages on your site to allow the user to view the operations status and manipulate it.