Конвертация видео с телефона в анимированные GIF с помощью Node, Libav и Imagemagick

Автор: | 28.07.2026

Одной из величайших ироний последних лет стал взрыв популярности анимированных GIF. В то время как браузеры наконец-то начали внедрять передовые технологии, такие как WebRTC, WebSockets и WebGL, технология, впервые поддержанная в Netscape 2.0 в 1995 году, полностью захватила культурный ландшафт интернета. Вы не можете читать спортивный блог, твит или даже посещать технологическую конференцию, не наткнувшись на скромный анимированный GIF.

Несмотря на популярность анимированных GIF, инструменты для их создания не так уж хороши. Лично я хотел что-то простое, что я мог бы использовать для конвертации забавных видео моих детей с телефона в анимированные GIF. Сейчас существует несколько инструментов для конвертации видео в анимированные GIF на вашем компьютере. Недавно некоторые разработчики из Yahoo выпустили Gifshot — инструмент, который конвертирует видео в анимированные GIF прямо в вашем браузере с использованием открытых веб-технологий. Но я хотел создать веб-сервис, поэтому мне нужно было программное обеспечение, которое либо встроено, либо легко добавляется в стандартный дистрибутив Linux-сервера. После некоторых проб и ошибок я остановился на следующей комбинации технологий:

— Ubuntu 14.04 на VPS от Digital Ocean

— Libav — для обработки видео и извлечения кадров

— Imagemagick — для склейки анимированного GIF

— Node.js — для управления и раздачи сгенерированных анимированных GIF

— Twilio — для отправки и получения MMS-сообщений

Вы можете попробовать размещенную версию приложения, которое я создал, отправив короткое видео (подумайте о Vine, 6 секунд или меньше) на:

**США:** (747) 900-4443

**Канада:** (778) 655-4263

После уведомления о том, что ваше видео поставлено в очередь, вы должны получить анимированную GIF-версию вашего видео. В этом посте мы пройдем через процесс создания этого приложения с нуля: запустим Linux VPS, установим необходимое программное обеспечение, создадим простое приложение на Node для управления конвертацией видео в анимированные GIF и подключим его к номеру Twilio. Вот что вы сможете сделать, когда закончите:

Вот две вещи, которые вам понадобятся для начала:

— Аккаунт Twilio с номером телефона, поддерживающим MMS

— Сервер Ubuntu Linux с установленным Node.js

Для целей этого поста я буду использовать droplet Digital Ocean для работы этого сервиса. Если у вас уже есть Ubuntu VPS с установленным Node.js, вы можете перейти к Шагу 2.

Создайте аккаунт Digital Ocean и получите бесплатные 10 долларов по коду **twilio10**. После входа в систему нажмите кнопку «Create», чтобы запустить новый droplet (так они называют VPS).

Дайте вашему droplet имя и выберите самый маленький тарифный план.

Прокрутите вниз и в разделе «Select Image» нажмите «Applications», а затем выберите образ Node/Ubuntu. Это избавит вас от необходимости вручную устанавливать Node на ваш новый droplet.

Наконец, нажмите «Create Droplet». Как только ваш droplet будет запущен, пароль root будет отправлен вам по электронной почте.

Теперь пришло время установить бинарные файлы, которые мы будем использовать для обработки видео и создания анимированных GIF. Откройте терминальную программу на вашем локальном компьютере и подключитесь к вашему droplet по SSH. Если вы еще этого не сделали, создайте пользователя без прав root и предоставьте ему права sudo. Затем установите libav и imagemagick:

Libav — это набор программ для обработки видео, и вы будете использовать программу avconv для извлечения кадров из видео, полученного от Twilio. Убедитесь, что она работает в вашей системе, создав анимированный GIF из видео.

Здесь вы передаете видео в формате 3gp. Если вам интересно, какие форматы видео поддерживает avconv в вашей системе, просто выполните команду avconv -formats.

Вот объяснение флагов, использованных в примере выше:

**-i**: входной файл**-r**: количество кадров в секунду для захвата**-vframes**: максимальное количество кадров для захвата**-f**: формат вывода

Последний параметр команды указывает avconv, как назвать выходные файлы. «%03d» — это специальная маска, которую avconv будет использовать для нумерации каждого файла, начиная с 1. Если все пройдет успешно, вы должны получить 48 (или меньше) файлов jpeg в каталоге tmp.

Как и libav, imagemagick — это набор программ для работы с изображениями. Используйте программу convert, чтобы склеить кадры в анимированный GIF:

Вот флаги, которые я использую:

**-delay**: количество сотых долей секунды паузы между кадрами**-loop**: заставляет GIF повторяться снова и снова

Теперь у вас должен быть анимированный GIF с именем bouncing.gif в вашем каталоге. Посмотрите на этот GIF в вашем браузере с помощью Node.

В вашем домашнем каталоге создайте новый каталог приложения и инициализируйте node:

Когда вы запустите npm init, процесс задаст ряд вопросов, чтобы помочь настроить ваше приложение Node и создать файл package.json. Дайте ему любое имя и используйте путь по умолчанию ( index.js ). Затем добавьте модуль node-static в ваше приложение:

Этот модуль позволит нам легко раздавать сгенерированные GIF как статические файлы. Теперь отредактируйте index.js и добавьте код для раздачи статических файлов:

В каталоге вашего приложения создайте подкаталог с именем public и скопируйте туда анимированный GIF, который вы сгенерировали ранее. Теперь запустите ваш Node-сервер:

Откройте браузер и перейдите по IP-адресу вашего VPS на порт 3000 и добавьте имя сгенерированного GIF: http://your_ip_or_domain:3000/bouncing.gif

Если все работает, вы должны увидеть это:

Теперь, когда ваша система может успешно конвертировать видео в анимированные GIF, пришло время добавить логику в ваше приложение Node для приема видеоконтента от Twilio, управления его конвертацией и возврата анимированного GIF. Добавьте следующие модули в ваш проект. Я расскажу, что делают эти модули, по мере создания вашего сервиса.

Откройте index.js и добавьте следующий код в начало:

Модуль url встроен в Node и даст вам простой способ получения информации о каждом веб-запросе к вашему приложению Node. Вы можете спросить, почему я не использую фреймворк вроде Express или Hapi для создания этого приложения. Ответ заключается в том, что это приложение обрабатывает только два вида запросов и не делает ничего сложного с входными или выходными данными. Я посчитал, что это хорошая возможность работать на низком уровне.

Измените код вашего HTTP-сервера для анализа входящего запроса и вызова функции handleMessage, когда путь — /message .

В функции handleMessage вам нужно определить, является ли отправленный вам медиафайл действительно видео. Если да, отправьте пользователю сообщение о том, что его видео поставлено в очередь и будет обработано в ближайшее время. Если нет, отправьте им сообщение о том, что им нужно прикрепить правильный видеофайл.

На высоком уровне функция processVideo должна сделать несколько вещей:

— Скачать видео в локальную файловую систему.

— Вызвать avconv для конвертации этого видеофайла в кадры.

— Вызвать convert для склейки этих кадров в анимированный GIF.

— Отправить пользователю сообщение со ссылкой на размещенный GIF.

Поскольку в этом процессе будут создаваться файлы (некоторые из них временные и подлежат последующему удалению), вы можете использовать модуль node-uuid для создания практически уникального префикса для этих файлов.

Функция os.tmpdir возвращает временный каталог операционной системы, в котором вы можете создавать и удалять файлы. Модуль request помогает вам получить этот URL и сохранить его во временном каталоге с именем файла, равным сгенерированному UUID. Когда загрузка завершена, пора начать обработку видео.

В Node есть два способа запустить дочерний процесс: exec и spawn . Главное отличие между ними заключается в том, что exec буферизует вывод из дочернего процесса и возвращает его целиком, а spawn передает поток вывода из дочернего процесса по мере его поступления. Поскольку вас не интересует вывод (stdout, stderr и т. д.) процесса, вы можете просто использовать exec.

Exec принимает строку, представляющую команду операционной системы, которую Node выполнит. Эта команда будет идентична той, которую вы выполнили вручную ранее. Модуль util помогает отформатировать строку команды с переменными, представляющими временный каталог операционной системы, UUID и текущий каталог процесса Node. Обратите внимание, что вы объединяете 3 процесса вместе с помощью оператора оболочки && . Это приводит к тому, что последующие команды выполняются только в том случае, если предыдущая команда выполнилась без ошибок.

Второй аргумент для exec — это обратный вызов (callback). Если какой-либо из процессов вернул ошибку, отправьте пользователю SMS с извинениями за ошибку. Если ошибки не было, вы можете написать функцию sendGif для отправки MMS пользователю, которая будет включать сгенерированный анимированный GIF.

Чтобы отправить MMS обратно пользователю, вы должны создать полный URL к анимированному GIF. Twilio загрузит анимированный GIF из этого места, чтобы создать MMS, которое оно доставит пользователю. Это легко сделать, используя информацию о хосте, включенную в заголовки запроса, и сгенерированный вами UUID.

Независимо от того, успешно ли завершился процесс exec или нет, обязательно очистите все временно сгенерированные файлы. Модуль glob позволяет легко получить все файлы в каталоге, соответствующие заданной маске.

Шаг 8: Тестирование приложения

Сохраните файл index.js. Теперь пришло время подключить это приложение к вашему номеру Twilio с поддержкой MMS и протестировать его!

Сначала установите следующие переменные среды:

TWILIO_CALLER_ID должен быть установлен на тот же номер, который вы будете использовать для приема сообщений. Теперь запустите процесс Node: node .

Перейдите в панель управления вашего аккаунта Twilio и нажмите на номер, который вы собираетесь использовать. Обновите Messaging Request URL, чтобы он указывал на ваш VPS на порту 3000 с путем /message . Убедитесь, что выбран HTTP GET , ваш код ожидает передачи GET-параметров. Нажмите «Save».

Момент истины. Отправьте короткое видео (6 секунд или меньше) на ваш номер Twilio. Вы должны получить немедленный ответ о том, что ваш запрос поставлен в очередь, а затем ответ, включающий новенький анимированный GIF.

В этом посте я показал вам, как использовать Node.js для конвертации видео, отправленных на номер телефона Twilio, в анимированные GIF. Это включало:

— Запуск Ubuntu VPS с установленным Node.js на Digital Ocean

— Установку бинарных файлов Libav и Imagemagick

— Использование Node.js для управления этими программами и раздачи статических файлов

— Интеграцию Twilio для приема MMS-видео и отправки анимированных GIF

Читателю остаются два упражнения, необходимые для того, чтобы сделать этот сервис более надежным:

— Использование очереди заданий (например, Bull) для упорядоченной обработки задач конвертации. Это важно, потому что программы, выполняющие конвертацию (acconv и convert), ограничены процессором и быстро поглотят системную память и ресурсы.

— Настройка сервера для запуска Node в качестве демона и запуска процесса при загрузке.

Весь этот код размещен на Github: https://github.com/crabasa/gifit

Надеюсь, вам понравился этот урок, удачного хакинга!