在后台运行一个 ffmpeg 进程

2021-12-26 00:00:00 ffmpeg exec background fork php

我想在 php 中使用 ffmpeg 将视频转换为 .flv.目前我有这个工作,但它会挂起浏览器,直到文件上传并完成.我一直在查看有关如何在后台运行 exec() 进程的 php 文档,同时使用返回的 PID 更新进程.这是我发现的:

I am wanting to use ffmpeg to convert video to .flv in php. Currently I have this working, but it hangs the browser until the file is uploaded and is finished. I have been looking at the php docs on how to run an exec() process in the background, while updating the process using the returned PID. Here is what I found:

//Run linux command in background and return the PID created by the OS
function run_in_background($Command, $Priority = 0)
{
    if($Priority)
        $PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
    else
        $PID = shell_exec("nohup $Command > /dev/null & echo $!");
    return($PID);
}

还有一个技巧,我用它来跟踪后台任务是否正在使用返回的 PID 运行:

There is also a trick which I use to track if the background task is running using the returned PID :

//Verifies if a process is running in linux
function is_process_running($PID)
{
    exec("ps $PID", $ProcessState);
    return(count($ProcessState) >= 2);
}

我是否想创建一个单独的 .php 文件,然后从 php cli 运行以执行这些功能之一?我只需要一点点推动就可以让它工作,然后我就可以从那里开始了.

Am I suppose to create a separate .php file which then runs from the php cli to execute one of these functions? I just need a little nudge in getting this working and then I can take it from there.

谢谢!

推荐答案

我想创建一个单独的 .php然后从 php cli 运行的文件执行这些功能之一?

Am I suppose to create a separate .php file which then runs from the php cli to execute one of these functions?

这可能是我的方式:

  • PHP 网页在数据库中添加了一条记录,表示必须处理此文件"
    • 并向用户显示一条消息;类似于您的文件将很快得到处理"
    • 首先,将记录标记为正在处理"
    • 做 ffmpeg 的事情
    • 将文件标记为已处理"
    • 如果它还没有被处理
    • 如果正在处理
    • 或者如果它已经被处理过——然后你可以给他新视频文件的链接.

    这里有一些其他的想法:

    Here's a couple of other thoughts :

    • 当您的应用程序变大时,您可以:
      • 一个网络服务器"
      • 许多处理服务器";在您的应用程序中,ffmpeg 需要大量 CPU,而不是为网页提供服务;因此,能够扩展该部分是很好的(这是另一个锁定"文件,在数据库中将它们指示为正在处理":这样,您将不会有多个处理服务器尝试处理同一个文件)
      • 繁重/长时间的处理不是网络服务器的工作!
      • 如果您想在处理"部分切换到 PHP 以外的其他内容,那会更容易.

      您的处理脚本"必须每隔几分钟启动一次;如果您使用的是类似 Linux 的机器,您可以使用 cron 来实现这一点.

      Your "processing script" would have to be launch every couple of minutes ; you can use cron for that, if you are on a Linux-like machine.

      看到评论后的更多信息

      由于处理部分是通过 CLI 完成的,而不是来自 Apache,因此您不需要任何背景"操作:您可以使用 shell_exec,当它完成它的工作时,它将把命令的整个输出返回给你的 PHP 脚本.

      As the processing part is done from CLI, and not from Apache, you don't need anykind of "background" manipulations : you can just use shell_exec, which will return the whole ouput of the command to your PHP script when it's finished doing it's job.

      对于观看网页的用户说正在处理",这看起来像是后台处理;并且,在某种程度上,它会是,因为处理将由另一个进程(甚至可能在另一台机器上)完成.

      For the user watching the web page saying "processing", it will seem like background processing ; and, in a way, it'll be, as the processing will be done by another processus (maybe even on another machine).

      但是,对你来说,它会简单得多:

      But, for you, it'll be much simpler :

      • 一个网页(没有背景")
      • 一个 CLI 脚本,也没有背景资料.

      你的处理脚本可能看起来像这样,我想:

      Your processing script could look like something like this, I suppose :

      // Fetch informations from DB about one file to process
      // and mark it as "processing"
      
      // Those would be fetched / determined from the data you just fetched from DB
      $in_file = 'in-file.avi';
      $out_file = 'out-file.avi';
      
      // Launch the ffmpeg processing command (will probably require more options ^^ )
      // The PHP script will wait until it's finished : 
      //   No background work
      //   No need for any kind of polling
      $output = shell_exec('ffmpeg ' . escapeshellarg($in_file) . ' ' . escapeshellarg($out_file));
      
      // File has been processed
      // Store the "output name" to DB
      // Mark the record in DB as "processed"
      

      真的比你最初想象的要容易,不是吗?;-)
      不要再担心后台的东西了:唯一重要的是处理脚本从 crontab 定期启动.

      Really easier than what you first thought, isn't it ? ;-)
      Just don't worry about the background stuff anymore : only thing important is that the processing script is launched regularly, from crontab.


      希望这会有所帮助:-)


      Hope this helps :-)

相关文章