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

Catframes —

программа для объединения кадров в видеоролики, решение для видеофиксации относительно медленных процессов, как проезд грузовиков через контрольно-пропускные пун­к­ты, и хранения этих логов в течение месяцев.

Она принимает файлы в форматах JPEG и PNG с произвольными разрешениями и соотношениями сторон. Способна работать без присмотра по расписанию.

Установить GitHub

Кратко

  • Что такое Catframes?
  • Это Python-скрипт для объединения последовательностей изображений в видео, обёртка над FFmpeg.
  • Что мешает использовать FFmpeg напрямую?
  • Интерфейс FFmpeg для выполнения этой задачи трудно назвать дружелюбным: вы либо указываете формат имён файлов, либо создаете текстовой файл, в котором файлы перечисляются. FFmpeg не сохраняет соотношения сторон при масштабировании. В нём слишком много опций для управления сжатием. Нет возможности вывести метаинформацию поверх изображения. Нет гарантий того, что будет происходить, если каких-то кадров не окажется на диске или не получится получить к ним доступ.
  • Catframes предоставляет такие гарантии?
  • Да, скрипт продолжает работать при самых разных обстоятельствах, включая стирание кадров во время сжатия. Catframes создавался для видеонаблюдения: подобные случаи не замалчиваются — сообщения о них встраиваются в видеоряд.
  • Как масштабируются кадры?
  • Соотношения сторон кадров сохраняются, при необходимости добавляются поля, картинка выравнивается по центру. Цвет полей конфигурируется.
  • Какие видеокодеки использует Catframes?
  • H.264 и VP9.
  • Почему именно такой выбор?
  • H.264 жмёт сильно и быстро, используя мало оперативной памяти. Видео в формате H.264 воспроизводится в мейнстримных браузерах, на самых разных устройствах. H.265 проигрывает ему по скорости сжатия и не может похвастаться воспроизведением на любом утюге.

    Кодек VP9 — стандарт де факто в формате WebM. Картинка на низких битрейтах не распадается на блоки, но становится немного мутной. VP9 кодируется вдвое медленнее H.264, но это наилучший свободный видеокодек на данный момент.

    AV1 требует втрое больше ОЗУ и кодируется в несколько раз медленнее, чем VP9, дает десятипроцентный выигрыш по степени сжатия при аналогичном уровне потерь. Низкая скорость сжатия делает его применение в видеонаблюдении нецелесообразным.
  • Какие указать опции, чтобы получить видео в хорошем качестве?
  • Качество видеофайла складывается из следующих компонентов:
    • качество исходного материала,
    • разрешение,
    • потери алгоритма масштабирования,
    • потери сжатия видеокодека.
    Catframes сам выбирает разрешение, используя данные о разрешениях кадров. Скрипт делает это очень хорошо, в нем нет опций выбора разрешения пользователем.
    Потери масштабирования невысоки.
    Для управления потерями сжатия, предлагается выбор из трёх уровней качества. Ухудшение качества на один уровень уменьшает итоговый файл в 2–3 раза. Уровни качества VP9 в Catframes. У качества HIGH низкие потери, но в нем не гарантируется сохранение оттенков соседних пикселей (субдискретизация 4:2:0).
  • Как выбирается разрешение видео?
  • Скрипт подбирает такое разрешение, чтобы большая часть кадров вписывалась в него без понижения четкости. Часто кадры вставляются совсем без масштабирования.

    Пример:
    Есть 320 кадров...
    
        1280 × 720   —  98 шт.
        1920 × 1080  —  69 шт.
        1280 × 960   —  57 шт.
        1280 × 640   —  30 шт.
        1440 × 1080  —  30 шт.
         800 × 600   —  14 шт.
        4096 × 2160  —  14 шт.
         852 × 480   —  8 шт.
    
    Выбрано: 1920×1080
    Вот как это работает. Вначале алгоритм рассматривает ширину и высоту отдельно. Для каждой оси определяется средневзвешенный размер. Значения ниже этого размера не рассматриваются. Из оставшихся выбираются самые частые размеры.
    На втором шаге для этой выбранной ширины и этой выбранной высоты среди разрешений кадров ищутся средневзвешенные размеры по другой оси, и, если выбранный ранее размер по той оси ниже, кадр расширяется. Таким образом, в спорных ситуациях может появиться еще до двух конкурирующих разрешений. По итогу, выбирается то, в котором больше мегапикселей.
  • Почему скрипт просто не берет максимальные ширину и высоту?
  • Тогда всего один кадр с большим разрешением привел бы к нецелесообразному увеличению разрешения видео. Это привело бы к использованию FFmpeg большого объема ОЗУ и, скорее всего, к небольшому перерасходу дискового пространства.
  • Каковы минимальные системные требования?
  • ОС: тестировалось на Linux и Windows.
    Python: версия 3.7 или выше.

    ОЗУ: 400 МБ для FullHD-видео.
    Диск: HDD (SSD не требуется).

    Не стоит забывать, что многие файловые системы замедляются при наличии большого числа файлов в одной директории, поэтому лучше делать отдельные папки для каждого часа видеонаблюдения или иначе разбивать поток на папки по 2–4 тысячи кадров, не более. Почти наверняка это ускорит работу сильнее, чем переход с HDD на SSD.
  • Сколько стоит Catframes?
  • Нисколько: это открытое программное обеспечение. Скрипт распространяется по лицензии zlib/libpng. У компонентов, от которых он зависит (FFmpeg, Pillow, Python) также открытый исходный код, свободные лицензии. В некоторых странах применение видеокодеков может быть ограничено патентами.

Наложение метаинформации

Catframes умеет выводить текстовую информацию о кадрах и о системе поверх изображения, впечатывать ее в итоговое видео.

Положение надписей не зависит ни от разрешений, ни от соотношений сторон. Надписи читаются как на светлом, так и на тёмном фоне

Пример вывода метаинформации о кадре. Цвет текста подстраивается под фон.

Установка

Из PyPI

Вы можете установить Catframes через pip. Установка из-под root наиболее удобна, т.к. исполняемый файл сразу попадает в PATH для всех пользователей и не редактируется кем попало.

Пример установки на чистый Alpine:

apk add python3
python3 -m ensurepip
python3 -m pip install catframes

apk add ffmpeg
apk add font-dejavu

Для установки FFmpeg должна быть раскоментирована строчка community-репозитория в /etc/apk/repositories.

Вручную

Catframes — это скрипт. Всё, включая тесты, содержится в одном файле, который можно самостоятельно закинуть в систему.

Пример установки в Alpine:

apk add python3
apk add py3-pillow
apk add ffmpeg
apk add font-dejavu

cp catframes.py /usr/local/bin/
chmod 755       /usr/local/bin/catframes.py
ln -s /usr/local/bin/catframes.py /usr/local/bin/catframes

Тесты рекомендуется запускать не из-под рута:

python3 -m unittest discover /usr/local/bin/ -p catframes.py

Использование

Это консольная команда, принимающая список папок и путь к получающемуся видеофайлу. Опции по-умолчанию: 30 кадров в секунду, чёрный цвет полей, среднее качество. Формат видео выводится из расширения файла (поддерживаются mp4 и webm).

Папки будут склеены в том порядке, в котором они указаны, а кадры внутри — в естественном порядке (natural order).

Это «полуинтерактивный» режим: команда упадёт, если директории заданы неправильно или в них нет изображений, а также при существующем видеофайле.

catframes папка1 папка2 папка3 результат.webm

Если вы прописываете команду в CRON или иначе запускаете ее автоматически, скорее всего, падение недопустимо: данные должны быть пережаты и удалены, даже если что-то идет не так, чтобы освободить место на диске.

Две опции сделаны специально для этого:

  1.    -s, --sure
  2.    -f, --force
catframes -sf папка1 папка2 папка3 результат.webm

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

Вторая опция приводит к перезаписи файла, если он есть.

Скрипт использует протокол HTTP, чтобы передавать обработанные кадры FFmpeg. Так кадры могут обрабатываться во время сжатия без необходимости записывать их на диск. HTTP-порт выбирается автоматически из свободных портов. Это не проблема при запуске на домашнем компьютере. На серверах обычно порты распределены между сервисами. Если случайно занять порт сервиса во время перезапуска сервиса, с точки зрения пользователя может произойти отказ системы. Чтобы этого избежать, есть еще опция для указания разрешенного диапазона портов: -p минимальный:максимальный.

Надписи добавляются параметрами --left, --right, --top-left и т. п. Они могут содержать произвольный текст и значения в фигурных скобках. Подробнее об этом «языке разметки оверлеев» читайте в документации.