Как создать анимированное превью для видео средствами php + ffmpeg-php + imagick
Для того, чтобы извлекать из видео высококачественные скриншоты и создавать
из них анимацию с произвольным количеством, и задержкой кадров, достаточно,
чтобы ваш хостинг поддерживал php, imagick и ffmpeg-php. Но imagick по умолчанию не
работает с ffmpeg. Исправить это не сложно, нужно лишь добавить делегат для
imagick ( прописать в файл delegates.xml вот такую строчку: <delegate
decode="ffmpeg" command='"ffmpeg" -i "%i" -y -vcodec
png -ss %s -vframes 1 -an -f rawvideo "%o"' /> ). Если у вас нет доступа к
конфигурационным файлам сервера, попросите сделать это хостера.
Если все установлено и настроено правильно, то можно приступать
непосредственно к скрипту.
В начале откроем тег php и зададим несколько переменных. Делается это для
удобства.
<?php
$frames = 5; // Количество кадров
$height = 100; // высота изображения
$width = 100; // ширина изображения
$delay = 50; // задержка кадров мс.
$file = 'video.avi'; // путь к файлу видео
Теперь нам нужно узнать длительность ролика. Создаем объект ffmpeg_movie и
узнаем длительность ролика.
$movie = new ffmpeg_movie($file);
$duration = $movie -> getDuration();
Обычно видео начинается и заканчивается черным экраном. Нам не нужны черные
кадры в анимации, поэтому к количеству кадров прибавим 2 и поделим длительность
ролика на то, что получилось.
$cut = round($duration / ($frames + 2));
Таким образом мы вычислили промежуток времени, через который будут
извлекаться кадры. А игнорируя первый и последний, избавимся от черных кадров.
И так, с подсчетами закончили, переходим к работе с анимацией. Создаем
графический объект для добавления к нему кадров и задаем формат изображения
GIF.
$image = new Imagick();
$image -> setFormat('GIF');
Чтоб php не ругался, создадим переменную, в значение которой будет
записываться время каждого кадра.
$ftime = 0;
Теперь в цикле для каждого кадра подсчитываем время. Далее создаем объект и
извлекаем в него кадр из ролика. Меняем размер, задаем формат GIF т.к.
добавленный нами делегат извлекает кадр в формате PNG. Добавляем его к анимации
и задаем время задержки кадра.
for($i=0;$i<$frames;$i++)
{
$ftime = $ftime + $cut; // время кадра
$frame = new Imagick(); // новый объект
$frame -> newPseudoImage($height, $width, 'ffmpeg:'.$file.'['.$ftime.']'); //
извлечение
кадра из видео
$frame -> cropThumbnailImage($width, $height); // уменьшаем
$frame -> setFormat('GIF'); // формат
$image -> addImage($frame); // добавление к анимации
$image -> setImageDelay($delay); // задержка кадра
}
Все, анимация собрана. Сохраним ее в файл animation.gif и закрываем тег php.
$image -> writeImages('animation.gif', true); // если true заменить на false, то
каждый кадр сохранится в отдельный файл
?>
Для вывода анимации в браузер нужно прописать следующий код до
закрывающего тега php
header('Content-Type: image/gif');
echo $image->getImagesBlob();
Функция cropThumbnailImage() уменьшает изображение и отрезает лишние края.
Если обрезать края не требуется, то следует вместо cropThumbnailImage() применить
функцию ThumbnailImage()
$frame -> ThumbnailImage($width, $height);
А для того, чтобы сохранялись пропорции изображения, нужно выбрать один из
параметров, по которому будет изменяться размер, а второму задать значение 0
(нуль) и он подгонится автоматически.
Пример:
$frame -> ThumbnailImage($width, 0); // по ширине
или
$frame -> ThumbnailImage(0, $height); // по высоте
Вот такой маленький и не хитрый код выполнит всю кропотливую работу и
создаст превосходную анимацию. Пользуйтесь на здоровье. Создание и продвижение сайтов - sites4u.info
Конечно данный способ не идеален, у него тоже есть некоторые недостатки.
FFMPEG создает большую нагрузку на процессор, к тому же медлителен. А у php-
скрипта время работы ограничено и процесс может просто завершиться по истечении
отведенного ему времени, так и не закончив работу. Не следует работать с очень
большим видео, а небольшие ролики по 5 - 10 минут он вполне потянет.
В принципе на этом все, если есть желание то можно еще почитать о
Программирование Delphi исходники,
компоненты, уроки
|