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 的参数可以参考专栏里其他文章

相关推荐
CodeWithMe5 小时前
【Note】《深入理解Linux内核》 第十九章:深入理解 Linux 进程通信机制
linux·运维·php
wkj0016 小时前
php7.4使用 new DateTime;报错 Class DateTime not found
php
亿坊电商9 小时前
VUE混合开发,选哪个PHP框架最顺手?
前端·vue.js·php
量子联盟1 天前
原创-基于 PHP 和 MySQL 的证书管理系统,免费开源
开发语言·mysql·php
不吃肉的羊1 天前
PHP设置文件上传最大值
后端·php
用户9272472502192 天前
PHP+JS+CSS+JSON 单页新闻系统实现方案
php
Ashlee_code2 天前
什么是Web3?金融解决方案
开发语言·金融·架构·eclipse·web3·区块链·php
Sally璐璐3 天前
IPSAN 共享存储详解:架构、优化与落地实践指南
开发语言·php
程序猿阿伟3 天前
《声音的变形记:Web Audio API的实时特效法则》
开发语言·前端·php
Clownseven3 天前
Shell 脚本实战指南:内网 ARP 洪泛监控与飞书/邮件自动告警
网络·php·飞书