在后台运行ffmpeg进程

Nic*_*ard 5 php fork background ffmpeg exec

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

//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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

我想创建一个单独的.php文件,然后从php cli运行以执行其中一个函数?我只需要稍微轻推一下,然后我可以从那里拿走它.

谢谢!

Pas*_*TIN 10

我想创建一个单独的.php文件,然后从php cli运行以执行其中一个函数?

这可能是我这样做的方式:

  • PHP网页在数据库中添加一条记录,表示"必须处理此文件"
    • 并向用户显示消息; 像"你的文件将很快处理"之类的东西
  • 在CLI中,批处理新插入的文件
    • 首先,将记录标记为"处理"
    • 做ffmpeg的事情
    • 将文件标记为"已处理"
  • 并且,在网页上,您可以向用户显示他的文件所处的状态:
    • 如果尚未处理
    • 如果它正在处理中
    • 或者如果它已被处理 - 您可以给他链接到新的视频文件.

以下是其他一些想法:

  • 应用程序变大的那天,您可以:
    • 一个"网络服务器"
    • 许多"处理服务器"; 在你的应用程序中,它是需要大量CPU而不是服务网页的ffmpeg东西; 因此,能够扩展该部分很好(这是另一个"锁定"文件,在DB中表示它们是"处理":这样,你就不会有多个处理服务器试图处理同一个文件)
  • 您只能使用来自Web服务器的PHP来生成Web页面,这是Web服务器的主要工作
    • 重/长处理不是Web服务器的工作!
    • 对于"处理"部分,您希望切换到PHP以外的其他日期,它会更容易.

你的"处理脚本"必须每隔几分钟启动一次; 如果你在类似Linux的机器上,你可以使用cron.


在看到评论后编辑:更多信息

由于处理部分是从CLI完成的,而不是从Apache完成的,因此您不需要任何"后台"操作:您可以使用shell_exec,当完成它的工作时,它会将命令的全部输出返回到PHP脚本.

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

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

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

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

// 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"
Run Code Online (Sandbox Code Playgroud)

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


希望这可以帮助 :-)