Добавляем валидацию длительности загружаемого видео в Laravel

Если в вашем проекте есть необходимость загрузки видео, то наверняка вам приходилось много раз придумывать, как проверить длину загружаемого видео. Laravel такого не предоставляет из коробки. Давайте воспользуемся специальным композер пакетом и напишем свое правило валидации.

composer require pbmedia/laravel-ffmpeg

Данный пакет предоставляет много интересных возможностей:

  • легко добавить водяные знаки
  • склеить два и более видео
  • поддержка HLS (AES-128)
  • мониторинг процесса перекодирования
  • можно указывать файлы из интернета
  • множественные конверсии
  • и много всего еще

Но нам потребуется лишь только получить информацию о продолжительности.

Используем фабрику для создания объекта работы с видео

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

Получаем информацию о длительности видео

$duration = $ffprobe
                ->format($filePath)
                ->get('duration');

Вот так просто работать с этой библиотекой. А теперь давайте соберем все эти знания в одном классе правила валидации:

<?php

namespace App\Rules;

use FFMpeg\FFProbe;
use Illuminate\Contracts\Validation\Rule;

class VideoDurationRule implements Rule
{
    public $min;

    public $max;

    public $duration;
    
    public function __construct($min = 0, $max = PHP_INT_MAX)
    {
        $this->min = $min;
        $this->max = $max;
    }

    public function passes($attribute, $value)
    {
            $ffprobe = FFProbe::create([
                'ffmpeg.binaries' => '/usr/bin/ffmpeg',
                'ffprobe.binaries' => '/usr/bin/ffprobe',
                'timeout' => 3600,
                'ffmpeg.threads' => 12,
            ]);

            $duration = round($ffprobe
                ->format($value->getRealPath()) 
                ->get('duration'));

            $this->duration = $duration;

            return $duration >= $this->min 
                     && $duration <= $this->max;
    } 
    
    public function message()
    {
        if ($this->duration < $this->min) {
            return "Video is smaller than $this->min minute. upload should be between $this->min-$this->max minute";
        } else {
            return "video is larger than $this->max minute. upload should be between $this->min-$this->max minute";
        }
    }
}

Как пользоваться?

$validator = Validator::make($request->all(), [
            'video' => [
                    'required', 
                    'file', 
                    'mimetypes:video/x-m-asf,video/x-flv,video/mp4,application/x-mpegURL,video/MP2T,video/3gpp,video/quicktime,video/x-msvideo,video/x-ms-wmv,video/avi,video/webm', 
                    new VideoDurationRule(1, 3)]
        ]); 

Есть вопросы? Не стесняйтесь задавать их в комментариях.

Рейтинг
( Пока оценок нет )
Maxyc Webber/ автор статьи
Мне 35 лет. Опыт профессиональной разработки 15 лет. Занимаюсь разработкой и поддержкой корпоративных систем автоматизации бизнеса, а также высоконагруженными проектами. Мне нравится решать нестандартные проблемы бизнеса. Имею опыт формирования команд под проект, налаживания процесса разработки, коммуникации программистов и заказчиков. Есть опыт работы с зарубежными заказчиками (ОАЭ, Польша, Германия, Швейцария).
Понравилась статья? Поделиться с друзьями:
Комментарии: 2
  1. ян

    Как используется метод public function passes($attribute, $value) в данном контексте?

  2. Maxyc Webber (автор)

    если безуспешно завершилась проверка размера видео то выдать ошибку, функционал инкапсулирован в валидаторе

Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.