runnickrun
6/28/2018 - 6:17 AM

[PHP] Create Short Preview from Video

[PHP] Create Short Preview from Video

//
// requirements
// FFMPEG https://www.ffmpeg.org/download.html
// https://github.com/PHP-FFMpeg/PHP-FFMpeg
//

<?php

namespace App\Jobs;

use FFMpeg\Coordinate\TimeCode;
use FFMpeg\FFMpeg;
use FFMpeg\FFProbe;
use FFMpeg\Format\Video\X264;

class ConvertVideo
{
    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        $tempDir         = '/tmp/vid-concat/'; // temporary directory
        $start           = 20; // when to start
        $extension       = 'mp4';
        $snippetDuration = 2; // duration for each snipper
        $snippetCount    = 5; // snippet count

        $ffmpeg = FFMpeg::create([
            'ffmpeg.binaries'  => '/usr/bin/ffmpeg',
            'ffprobe.binaries' => '/usr/bin/ffprobe',
            'timeout'          => 360000,
            'ffmpeg.threads'   => 12,
        ]);

        $ffprobe = FFProbe::create([
            'ffmpeg.binaries'  => '/usr/bin/ffmpeg',
            'ffprobe.binaries' => '/usr/bin/ffprobe',
            'timeout'          => 360000,
            'ffmpeg.threads'   => 12,
        ]);

       
        $input    = '/file/to/input.mp4';
        $file     = $ffmpeg->open($input);
        $duration = $ffprobe->format($input)->get('duration');
        $length   = round($duration);
        $interval = floor(($length - $start) / $snippetCount);
        $output   = '/file/to/output.mp4';
        $format   = new X264('libmp3lame', 'libx264');

        // create snippets  (5x 2sec)
        mkdir($tempDir);
        $snippets = [];
        for ($i = 0; $i < $snippetCount; $i++) {
            $file->filters()->clip(TimeCode::fromSeconds($start), TimeCode::fromSeconds($snippetDuration));
            $file->save($format, $tempDir . '-' . $i . '-.' . $extension);

            $snippets[] = $tempDir . '-' . $i . '-.' . $extension;
            $start += $interval;
        }

        // concat the snippets into 1 $destinationFile
        $file = $ffmpeg->open($input);
        $file
            ->concat($snippets)
            ->saveFromSameCodecs($output, true);

        // remove temp files
        foreach ($snippets as $snippet) {
            unlink($snippet);
        }
        rmdir($tempDir);
    }
}