laravel ffmpeg 转码

郦祯
2023-12-01

先安装php拓展

https://github.com/PHP-FFMpeg/PHP-FFMpeg/

<?php

namespace App\Jobs;

use FFMpeg;
use Illuminate\Bus\Queueable;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\File;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

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


    public $input;  // 定义原始视频文件路径;
    public $output; // 定义转码视频文件路径;
    public $timeout = 3600; // 定义操作延迟时间,单位:秒;
    public $tries = 5;  // 定义队列重试次数;
    public $memory = 1024;  // 定义队列所占最大内存限制;
    public $threads = 2;    // 定义队列所占最大线程数;
    public $section = 60;    // 定义视频切片大小,单位:秒;
    public $progress = 0;   // 当前转码进度;

    /**
     * Create a new job instance.
     *
     * ProcessM3U8 constructor.
     * @param string $input
     * @param string $output
     */
    public function __construct(string $input,string $output)
    {
        $this->input = $input;
        $this->output = $output;
    }

    /**
     * Execute the job.
     * @note The Handle need composer package as php-ffmpeg by command "composer require php-ffmpeg/php-ffmpeg"
     * @afterChange "php artisan queue:restart & php artisan queue:work --queue=video"
     */
    public function handle()
    {
        Log::channel('video')->info('执行转换:'.public_path().$this->output);
        ini_set('memory_limit',$this->memory.'M');
        $ffmpeg = FFMpeg\FFMpeg::create([
            'ffmpeg.binaries'  => exec('which ffmpeg'),
            'ffprobe.binaries' => exec('which ffprobe'),
            'timeout'          => $this->timeout,
            'ffmpeg.threads'   => $this->threads,
        ]);
        $video = $ffmpeg->open(public_path().$this->input);
        $format = new FFMpeg\Format\Video\X264('aac', 'libx264');
        $format
            ->setAdditionalParameters(['-hls_time',$this->section, '-hls_list_size',0,'-strict','-2', '-f','hls'])
            ->setKiloBitrate(1000)
            ->setAudioChannels(2)
            ->setAudioKiloBitrate(256)
            ->setPasses(2);
        $format->on('progress', function ($video, $format, $percentage) {
            if ($percentage > $this->progress){
                Log::channel('video')->info('转换进度:'.$percentage.'%');
                $this->progress = $percentage;
            }
        });
        $directory = pathinfo(public_path().$this->output)['dirname'];
        File::isDirectory($directory) or File::makeDirectory($directory);
        try {
            $video->save($format, public_path().$this->output);
        } catch (\Exception $e) {
            Log::channel('video')->error('错误:'.$e->getMessage());
        } finally {
            $this->result = $this->output;
            Log::channel('video')->info('转换成功:'.public_path().$this->output);
        }
    }
}

 

转码参数由setAdditionalParameters 方法写入

之前采用exec 可以直接执行 但是无法看到任务进度,所以引入第三方扩展

$this->output 为定义的输出文件名,这里指定的是m3u8格式

 

 类似资料: