You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何实现代码后台运行?以FFmpeg视频合并为例

Laravel后台运行视频合并代码的实现方案

一、使用Laravel任务队列(最推荐)

这是Laravel原生支持的异步处理方案,自带失败重试、进程监控等功能,完全适配耗时的视频处理场景。

步骤:

  1. 生成任务类
    运行Artisan命令创建处理视频合并的任务:
php artisan make:job MergeVideoJob
  1. 编写任务逻辑
    打开app/Jobs/MergeVideoJob.php,在handle方法里实现视频合并和状态更新:
<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class MergeVideoJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $video1;
    protected $video2;
    protected $id;

    public function __construct($video1, $video2, $id)
    {
        $this->video1 = $video1;
        $this->video2 = $video2;
        $this->id = $id;
    }

    public function handle()
    {
        // 执行FFmpeg合并命令
        $cmd = "ffmpeg -i concat:{$this->video1}|{$this->video2} -c copy merged_{$this->id}.mp4";
        exec($cmd);

        // 更新合并状态
        updateStatusMerge($this->id, 'ready');
    }
}
  1. 在控制器中分发任务
    修改你的video_merge方法,直接分发任务后立即返回响应:
public function video_merge()
{
    $video1 = "video1.mp4";
    $video2 = "video2.mp4";
    $id = "xxxxxxxxxxxxx";

    // 分发任务到队列,后台异步执行
    \App\Jobs\MergeVideoJob::dispatch($video1, $video2, $id);

    return response()->json([
        'status' => 'processing',
        'id' => $id 
    ]);
}
  1. 启动队列Worker
    最后需要启动队列进程来处理任务:
php artisan queue:work

如果需要后台持久运行,可以用supervisor或者nohup来守护进程,避免进程意外终止。

二、直接修改exec命令让系统后台执行

如果不想依赖队列,也可以直接通过修改shell命令让FFmpeg在系统后台运行,同时把状态更新逻辑绑定到命令执行完成后。

实现方式:

把FFmpeg命令和状态更新命令用&&串联,确保合并完成后再更新状态,最后加上后台运行标识:

public function video_merge()
{
    $video1 = "video1.mp4";
    $video2 = "video2.mp4";
    $id = "xxxxxxxxxxxxx";
    
    // 拼接命令:先执行合并,完成后调用Artisan命令更新状态,后台运行
    $cmd = "ffmpeg -i concat:$video1|$video2 -c copy merged_{$id}.mp4 && php " . base_path('artisan') . " app:update-merge-status $id > /dev/null 2>&1 &";
    
    exec($cmd);

    return response()->json([
        'status' => 'processing',
        'id' => $id 
    ]);
}

然后创建一个Artisan命令来处理状态更新:

php artisan make:command UpdateMergeStatus

打开app/Console/Commands/UpdateMergeStatus.php,编写逻辑:

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class UpdateMergeStatus extends Command
{
    protected $signature = 'app:update-merge-status {id}';
    protected $description = 'Update video merge status';

    public function handle()
    {
        $id = $this->argument('id');
        updateStatusMerge($id, 'ready');
    }
}

这种方式的缺点是没有失败重试机制,若FFmpeg命令执行失败,状态不会更新,也缺少日志记录,仅适合简单场景。

三、使用Laravel Process类(替代exec)

Laravel提供了Illuminate\Support\Facades\Process类来执行系统命令,API更友好,也能实现后台运行:

use Illuminate\Support\Facades\Process;

public function video_merge()
{
    $video1 = "video1.mp4";
    $video2 = "video2.mp4";
    $id = "xxxxxxxxxxxxx";

    // 后台运行命令,不阻塞当前请求
    Process::timeout(3600)->runInBackground(function ($type, $output) {
        // 可选:在这里处理命令输出或日志
    }, "ffmpeg -i concat:$video1|$video2 -c copy merged_{$id}.mp4 && php " . base_path('artisan') . " app:update-merge-status $id");

    return response()->json([
        'status' => 'processing',
        'id' => $id 
    ]);
}

这个方式和直接用exec逻辑类似,但Process类提供了更便捷的错误处理和输出控制。


内容的提问来源于stack exchange,提问作者lCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 04:53:25