Laravel 10.x 里如何使用ffmpeg

原理上很简单,就是使用命令行去调用ffmpeg,然后分析一下输出是不是有错误。

安装

首先安装 symfony/process,主要用于包装一下,用来代替 exec, passthru, shell_exec and system

bash 复制代码
composer require symfony/process
composer require symfony/filesystem

要注意 Laravel 10.x 是锁定 symfony 6.4的,所以无法安装最新的 7.0 ,但用起来也没什么问题。

创建服务

照例创建服务,服务类:VideoMakerService,接口类:VideoMakerContract,服务提供类:VideoMakerProvider,快捷名称:videomaker,Facade类:VideoMaker

参考 保姆级教程:Laravel中添加Service

暂时就提供一个服务,把图片生成几秒视频。

php 复制代码
    public function imageToBaseVideo(string $imageFile, string $targetFile, float $duration): bool{
        // $workingDir=$this->ffmpegTempDir;
        $params=[
            $this->ffmpegFile,
            '-loop', '1',
            '-framerate', '30',
            '-i', $imageFile,
            '-vf', 'scale=1080:1920:force_original_aspect_ratio=decrease,pad=1080:1920:(ow-iw)/2:(oh-ih)/2,setsar=1',
            '-c:v', 'libx264',
            '-t', $duration,
            '-y',
            $targetFile,
        ];
        return ExecHelper::run($params);
    }

这里使用了 ExecHelper 来运行,只是对Process做了包装

php 复制代码
class ExecHelper{

    public static function run(array $params){
        $success=false;
        $process = new Process($params);
        $code=$process->run(function ($type, $buffer): void {
            if (Process::ERR === $type) {
                Log::debug('ERR > ', $buffer);
            } else {
                Log::debug('OUT > ', $buffer);
            }
        });
        $success=$code===0;

        return $success;
    }
}

创建命令行

命令行类:ProcessVideo

php 复制代码
    public function handle(VideoMakerContract $videoMakerContract)
    {
        $imageFile = $this->argument('imageFile');
        $targetFile = $this->argument('targetFile');
        $duration = $this->option('duration');
        // print params
        $this->info('imageFile: '.$imageFile.' , targetFile: '.$targetFile.' , duration: '.$duration);
        // convert to absolute path
        $imageFile=PathHelper::toAbsolutePath($imageFile);
        // validate imageFile
        if(!file_exists($imageFile)){
            $this->error('imageFile not exists');
            return;
        }
        $targetFile=PathHelper::toAbsolutePath($targetFile);
        // validate targetFile
        if(!file_exists($targetFile)){
            $this->error('targetFile not exists');
            return;
        }
        // validate duration
        if(!is_numeric($duration)){
            $this->error('duration must be numeric');
            return;
        }
        $success=$videoMakerContract->imageToBaseVideo($imageFile, $targetFile, $duration);

        $this->info('success: '.$success);
    }

参考:保姆级教程:Laravel里如何创建自己的命令行

这里面用到PathHelper就是简要地补全一下路径

php 复制代码
class PathHelper{
    public static function toAbsolutePath(string $path): string{
        return Path::makeAbsolute($path, self::currentPath());
    }

    public static function currentPath(): string{
        return realpath('.');
    }
}

准备好图片

复制任意一张图片到 storage/app/tmp/t.jpg

运行命令行

bash 复制代码
./artisan process:video ./storage/app/tmp/t.jpg ./storage/app/tmp/t.mp4 --duration=5

轻松生成 t.mp4 ,ffmpeg 的参数可以参考专栏里其他文章

相关推荐
BingoGo18 小时前
2025 年 PHP 常见面试题整理以及对应答案和代码示例
后端·php
Bruce1232 天前
web专题之php代审(二)
php
BingoGo2 天前
PHP-FPM 深度调优指南 告别 502 错误,让你的 PHP 应用飞起来
后端·php
亿坊电商2 天前
物联网领域中PHP框架的最佳选择有哪些?
物联网·struts·php
wuzuyu3652 天前
用php做一个简易的路由
php·路由
老六ip加速器3 天前
手机ip隔离方法
tcp/ip·智能手机·php
rockmelodies3 天前
【PHP7内核剖析】-1.3 FPM
php
真正的醒悟3 天前
上网管理行为-ISP路由部署
服务器·php·接口隔离原则
张晓~183399481213 天前
短视频矩阵源码-视频剪辑+AI智能体开发接入技术分享
c语言·c++·人工智能·矩阵·c#·php·音视频
2zcode3 天前
基于Matlab可见光通信系统中OOK调制的误码率性能建模与分析
算法·matlab·php