Создание сторис для Instagram из PHP +17



Вступление


В последнее время люди более охотно смотрят в социальных сетя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х минут.

Планы по развитию


  • Добавлении стандартных сценариев анимации, для сокращения кода
  • Текстовые анимации (появление построчно и т.д.)
  • Фон для текста

Надеюсь, кому-то подобная библиотека будет полезна. Буду рад услышать критику и пожелания в функционале.

Git-репозиторий

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (19):

  1. sazareks
    /#19628258

    Это всё круто, но каким способом вы публикуете в сам инстаграм? Не ручками же?

    • Jangle_ru
      /#19628294

      До реальной публикации пока не дошёл, все время тратится на доработку библиотеки и её развитие. А с публикацией есть трудности?

      • sazareks
        /#19628312

        В целом нет, но иногда возникает трудность в подтверждении аккаунта инстаграм. Знаете, когда авторизируешься с другого IP инстаграм иногда может запрос смс делать или на почту, вот эти самые запросы хочется иногда иметь программно вызывать. Некоторые сервисы вроде так делают.

        • Jangle_ru
          /#19628354

          Да, понимаю о чём вы, но в данной библиотеке я решал всё же другую проблему. Но об этой тоже можно задуматься

      • mitgard
        /#19628792

        На сколько мне известно, трудности есть. У инсты нет оффициального апи. Все либы, что есть являются реверс-инженерингом андроид приложения. Правда могу ошибаться.

        • zzzmmtt
          /#19630218

          Апи то у них есть, но постинга сторис при беглом просмотре я там не увидел.

        • CAJAX
          /#19633308

          Оригинальная версия API закрыта с ноября. Есть новая, через Фейсбук. Там есть постинг фото для "Бизнес Партнёров Инстаграма", но постинга сторис там нет. Статус партнёра просто так не заполучить.


          При этом у инстаграма есть graphql для своего софта, который, в принципе реверсится.

  2. akdes
    /#19628272

    Спасибо за работу и вклад в сообщество PHP разработки.
    Однако, при чём тут инста? По факту статья о создании видео файла с наложением текста и анмиции. По названию ожидал увидеть что-то иное, хотябы интеграцию инсты в скрипт, для дальнейшего авто постинга, как минимум.

    • Jangle_ru
      /#19628286

      На самом деле долго думал над вектором, в котором двигаться. На деле, я для себя не нашёл применения этой библиотеки кроме как в социальных сетях. Но вы правы, на данный момент это просто создание видео из PHP. Инстаграм в заголовке взят как пример.

      • akdes
        /#19628552

        Я думаю название "Генерация/создание видео для статуса/Стори посредством пхп" было бы более приемлемым, благо статус — тема актуальная. ВК, инста, ватсэпп..


        Ну да ладно, рад что вообще ещё вижу PHP на хабре

  3. Taraflex
    /#19628942

    Слишком долго кодом анимацию всю описывать.
    Для реального задачи лично я бы взял flash (уфф. предвкушаю волну негодования).
    В текстовых полях разместил бы плейсхолдеры в стиле {{{тут будет ваша реклама… тут пробелов на пару килобайт...}}}
    Распаковал бы полученный swf в несжатый формат.
    Через php заменил бы плейсхолдеры на требуемый текст обычными регулярками (просто открыв swf как обычный юникод текст).
    Отрендерил тем же ffmpeg полученный swf в mp4.

    • Jangle_ru
      /#19628976

      Это если шаблон использования один, может и сработать, но для широкого использования точно не подойдёт

      • Taraflex
        /#19629058

        Почему не подойдет для широкого использования?
        Кодом анимацию прописывать еще дольше.
        Если хочется все «по-красивше» выполнить, без заглушек из пробелов, то можно заморочиться и завести на сервере (у вас все равно нативная зависимость от ffmpeg получается)
        www.redtamarin.com/about/description — виртуалка для flash байткода в стиле nodejs, но без flash рантайма.
        +
        github.com/claus/as3swf — статичный текст будет храниться в отдельных тегах — подменить не особо сложная задача.

  4. triada63
    /#19630316

    Идея конечно прикольная, но вот язык выбран как мне кажется не совсем тот. Сам я тоже вебщик на PHP, но для такой либы выбрал бы Java или, в крайнем случае, ноду (NodeJS)

    • akdes
      /#19630616

      обычно катаюсь на мерсе, но тут бы на бмв лучше проехал…
      Кто что имеет, тот на том и катается. Не вижу особой разницы…

  5. nikolau
    /#19632614

    Хорошая идея, но из-за времени генерации использовать можно только для своих нужд. Если для какого-нибудь сервиса, то такую генерацию, если это возможно, лучше реализовать в браузере.

    • Jangle_ru
      /#19633312

      Увы, полностью в браузере этого не сделать, генерация видео где-то да будет происходить. Но создание анимации безусловно супер удобно было бы делать в браузере и подобные сервисы есть. Возможно и я дорасту до подобного

  6. 3JIoDeu
    /#19636154

    Это наверно хороший академический проект, но я не до конца понимаю, какой профит даёт php обёртка над ffmpeg?

    • Jangle_ru
      /#19636326

      Это не совсем обертка, ffmpeg нужна что бы склеить кадры в видео и все. А php как раз рисует эти кадры