Вступление
В последнее время люди более охотно смотрят в социальных сетяx видео, нежели просматривают фотографии. Сторис в инстаграм набирает в 3-4 раза больше просмотров, чем просто выложенная фотография.
Ну и конечно же, не перестаём забывать, что социальные сети это не только себя показать, других посмотреть, но и продвижение своих товаров, услуг и т.д. Мы уже давно научились постить во вконтакте свежеопубликованную новость с сайта. А что если пойти дальше? Что если подавать эту информацию как видео? Или выкладывать интересные видео-сторис в инстаграм для привлечения большего внимания аудитории?
Так мне в голову пришла идея о создании библиотеки, которая позволяла бы создавать короткие видео-ролики из фотографий, текста и анимации этих объектов. Да, кто-то может сказать, что сервисы, которые позволяют это делать, уже есть и зачем придумывать велосипед? Во-первых — хочу, во-вторых — могу, в третьих — это будет бесплатно.
Эта статья о том, как работать с библиотекой, как создавать свои собственные сторис из PHP.
Ограничения
Сразу стоит сказать, что библиотека использует FFmpeg для генерации финального видео-файла. FFmpeg обязательно должен быть установлен на сервере. Возможно в будущем, будет вариант генерации сторис как gif-файл, но для себя я выбрал именно видео-файл, как результат работы.
Подготовка
Библиотека устанавливается через композер
composer require borodin-vasiliy/php-stories
Создание сторис
Настало время создать свою собственную сторис. Например, мы хотим видеть фоном фотографию котёнка, которая немного приближается на протяжении всего сторис и отобразить 2 текста на ней с анимацией появления. Легко!
// Мы хотим создать 5 секундное сторис размерами 720x1280
$stories = new Stories([
"width" => 720,
"height" => 1280,
"duration" => 5
]);
Как можете видеть, все параметры переданы как массив. На данный момент можно изменять:
- «width» — Ширина сторис в пикселях
- «height» — Высота в пикселях
- «duration» — Продолжительность в секундах
- «fps» — Количество кадров в секунду, по стандарту — 30
Далее нам нужно добавить 3 объекта (картинку и 2 текста) на наше будущее сторис. На данный момент библиотека позволяет добавлять 4 типа разных объектов — картинка, текст, элепс, прямоугольник. Для каждого объекта предусмотрен свой метод, аргумент метода — массив из параметров добавляемого объекта.
Объекты имеют как общие параметры:
- «top» — позиция объекта от верхнего края сторис
- «left» — позиция элемента от левого края сторис
- «opacity» — прозрачность, как в css [0… 1]
- «rotate» — угол поворота объекта [0… 359]
- «z-index» — слой, как z-index в css — чем больше, тем выше слоем на кадре будет располагаться элемент
- «start» — секунда, когда элемент должен быть добавлен на сторис
- «end» — секунда, когда элемент должен быть убран со сторис
Так и уникальные для каждого типа объекта, например, для картинки:
- «path» — Путь до картинки, которую хотим добавить
- «scale» — Множитель размера изображения (приближение)
// Путь до файла с котиком
$main_image = $dir."/images/1.jpg";
// Получим размеры картинки)
list($image_width, $image_height) = getimagesize($main_image);
// Посчитаем, каким должно быть приближение для картинки, что бы она покрыла весь сторис
$image_start_scale = round(1280 / $image_height, 1);
// Добавление картинки
$stories->addImage([
"path" => $main_image,
"top" => round(-1 * ($image_height * $image_start_scale - $stories_height) / 2), // Вычислим параметр отступа сверху при текущем приближении
"left" => round(-1 * ($image_width * $image_start_scale - $stories_width) / 2), // Вычислим параметр отступа слева при текущем приближении
"scale" => $image_start_scale
]);
Готово! Если прямо сейчас сгенерировать сторис, то 5 секунд мы будем любоваться котиком. Но я обещал, что будет анимация, давайте добавим её.
Анимация для объекта добавляется с помощью отдельного метода, аргументом которого являются массив параметров, к которым должен прийти объект. Анимаций для одного объекта может быть сколько угодно. Стоит сказать, что синтаксис библиотеки подразумевает использование Fluent Interface.
// Путь до файла с котиком
$main_image = $dir."/images/1.jpg";
// Получим размеры картинки)
list($image_width, $image_height) = getimagesize($main_image);
// Посчитаем, каким должно быть приближение для картинки, что бы она покрыла весь сторис
$image_start_scale = round(1280 / $image_height, 1);
//
$image_end_scale = $image_start_scale + 0.5;
// Добавление картинки с анимацией
$stories->addImage([
"path" => $main_image,
"top" => round(-1 * ($image_height * $image_start_scale - $stories_height) / 2), // Вычислим параметр отступа сверху при текущем приближении
"left" => round(-1 * ($image_width * $image_start_scale - $stories_width) / 2), // Вычислим параметр отступа слева при текущем приближении
"scale" => $image_start_scale
])->addAnimation([
"top" => round(-1 * ($image_height * $image_end_scale - $stories_height) / 2), // Вычислим финальное местоположение картинки с учетом финального приближения
"left" => round(-1 * ($image_width * $image_end_scale - $stories_width) / 2),// Вычислим финальное местоположение картинки с учетом финального приближения
"scale" => $image_end_scale,
]);
Как вы могли заметить, для добавления анимации используется метод addAnimation. Обязательные параметры для анимации:
- «start» — Секунда, когда должна начаться анимация. Если не задана, анимация начнётся в момент добавления объекта
- «duration» — Продолжительность анимации в секундах
Массив параметров, на которые он может воздействовать анимация:
- «top»
- «left»
- «opacity»
- «rotate»
- «scale»
- «width»
- «height»
// Добавление заголовка
$stories->addText([
"text" => "Hello world!",
"path" => $dir."/fonts/helvetica.ttf",
"size" => 130,
"color" => "#ffffff",
"width" => 620,
"top" => 200,
"left" => 50,
"opacity" => 0,
"shadow" => [
"color" => "#000000",
"top" => 4,
"left" => 4
]
])->addAnimation([
"duration" => 1,
"opacity" => 1
])->addAnimation([
"start" => 4.5,
"duration" => 0.5,
"opacity" => 0
]);
// Добавление текста
$stories->addText([
"text" => "This is a test of function adding text",
"path" => $dir."/fonts/helvetica.ttf",
"size" => 100,
"color" => "#ffffff",
"width" => 620,
"top" => 750,
"left" => 50,
"start" => 0.5,
"opacity" => 0,
"shadow" => [
"color" => "#000000",
"top" => 4,
"left" => 4
]
])->addAnimation([
"duration" => 1,
"opacity" => 1
])->addAnimation([
"start" => 4.5,
"duration" => 0.5,
"opacity" => 0
]);
Текст имеет свои уникальные параметры:
- «text» — текст, который вы хотите вывести — обязательно
- «path» — путь до шрифта (.ttf) — обязательно
- «size» — размер шрифта
- «color» — цвет, например "#ffffff"
- «width» — ширина блока текста, если задана, то текст автоматически будет разбит на строки
- «align» — выравнивание текста [left, center, right]
- «shadow» — тень
Тень это так же массив параметров:
- «color» — цвет тени
- «top» — отступ сверху
- «left» — отступ слева
$file_hash = $stories->generate("/tmp");
В результате мы получаем имя файла, который находится во временной папке, переданной как аргумент.
Результат работы
Стоит сказать, что скорость создания сторис не велика, на хорошем компьютере 5и секундный ролик генерируется порядка минуты, на простеньком сервере более 3х минут.
Планы по развитию
- Добавлении стандартных сценариев анимации, для сокращения кода
- Текстовые анимации (появление построчно и т.д.)
- Фон для текста
Надеюсь, кому-то подобная библиотека будет полезна. Буду рад услышать критику и пожелания в функционале.
Автор: Jangle_ru