Skip to content

Latest commit

 

History

History
145 lines (110 loc) · 14 KB

README.ru.md

File metadata and controls

145 lines (110 loc) · 14 KB

µStreamer

CI Discord

[English version]

µStreamer - это маленький и очень быстрый сервер, который позволяет организовать трансляцию видео в формате MJPEG с любого устройства V4L2 в сеть. Этот формат нативно поддерживается всеми современными браузерами и большинством приложений для просмотра видео (mplayer, VLC и так далее). µStreamer был разработан в рамках проекта PiKVM специально для стриминга с устройств видеозахвата VGA и HDMI с максимально возможным разрешением и FPS, которые только позволяет железо.

Функционально µStreamer очень похож на mjpg-streamer при использовании им плагинов input_uvc.so и output_http.so, однако имеет ряд серьезных отличий. Основные приведены в этой таблице:

Фича µStreamer mjpg-streamer
Многопоточное кодирование JPEG
Аппаратное кодирование на Raspberry Pi
Поведение при физическом отключении
устройства от сервера во время работы
✔ Транслирует черный экран
с надписью NO SIGNAL,
пока устройство не будет подключено снова
✘ Прерывает трансляцию 1
Поддержка DV-таймингов - возможности
изменения параметров разрешения
трансляции на лету по сигналу
источника (устройства видеозахвата)
☹ Условно есть 1
Возможность пропуска фреймов при передаче
статического изображения по HTTP
для экономии трафика
2
Стрим через UNIX domain socket
Systemd socket activation
Дебаг-логи без перекомпиляции,
логгирование статистики производительности,
возможность получения параметров
трансляции по HTTP
Возможность сервить файлы встроенным
HTTP-сервером
☹ Нет каталогов
Вывод сигналов о состоянии стрима на GPIO
с помощью libgpiod
Поддержка контролов веб-камер (фокус,
движение сервами) и всяких настроек,
типа яркости, через HTTP
Совместимость с API mjpg-streamer'а :)

Сносочки:

  • 1 Еще до написания µStreamer, я запилил патч, добавляющий в mjpg-streamer поддержку DV-таймингов и предотвращающий его зависание при отключении устройства. Однако патч, увы, далек от совершенства и я не гарантирую его стопроцентную работоспособность, поскольку код mjpg-streamer чрезвычайно запутан и очень плохо структурирован. Учитывая это, а также то, что в дальнейшем мне потребовались многопоточность и аппаратное кодирование JPEG, было принято решение написать свой стрим-сервер с нуля, чтобы не тратить силы на поддержку лишнего легаси.

  • 2 Это фича позволяет в несколько раз снизить объем исходящего трафика при трансляции HDMI, однако немного увеличивает загрузку процессора. Суть в том, что HDMI - полностью цифровой интерфейс, и новый захваченный фрейм может быть идентичен предыдущему в точности до байта. В этом случае нет нужды передавать одну и ту же картинку по сети несколько раз в секунду. При использовании опции --drop-same-frames=20, µStreamer будет дропать все одинаковые фреймы, но не более 20 подряд. Новый фрейм сравнивается с предыдущим сначала по длине, а затем помощью memcmp().


TL;DR

Если вам нужно вещать стрим с уличной камеры и управлять ее параметрами - возьмите mjpg-streamer. Если же вам нужно очень качественное изображение с высоким FPS - µStreamer ваш бро.


Сборка

Для сборки вам понадобятся make, gcc, libevent с поддержкой pthreads, libjpeg8/libjpeg-turbo и libbsd (только для Linux).

  • Arch: sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd.
  • Raspbian: sudo apt install libevent-dev libjpeg8-dev libbsd-dev. Добавьте libgpiod для WITH_GPIO=1 и libsystemd-dev для WITH_SYSTEMD=1.
  • Debian/Ubuntu: sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev.

Для включения сборки с поддержкой GPIO установите libgpiod и добавьте параметр WITH_GPIO=1. Если при сборке компилятор ругается на отсутствие функции pthread_get_name_np() или другой подобной, добавьте параметр WITH_PTHREAD_NP=0 (по умолчанию он включен). При аналогичной ошибке с функцией setproctitle() добавьте параметр WITH_SETPROCTITLE=0.

$ git clone --depth=1 https://github.com/pikvm/ustreamer
$ cd ustreamer
$ make
$ ./ustreamer --help

Для Arch Linux в AUR есть готовый пакет: https://aur.archlinux.org/packages/ustreamer.

Порт для FreeBSD: https://www.freshports.org/multimedia/ustreamer.


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

Для аппаратного кодирования M2M на Raspberry Pi, вам нужно ядро минимальной версии 5.15.32. Поддержка OpenMAX и MMAL для более старых ядер объявлена устаревшей и была удалена.

Будучи запущенным без аргументов, ustreamer попробует открыть устройство /dev/video0 с разрешением 640x480 и начать трансляцию на http://127.0.0.1:8080. Это поведение может быть изменено с помощью опций --device, --host и --port. Пример вещания на всю сеть по 80-м порту:

# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80

❗ Обратите внимание, что начиная с версии µStreamer v2.0 кросс-доменные запросы были выключены по умолчанию по соображениям безопасности. Чтобы включить старое поведение, используйте опцию --allow-origin=\*.

Рекомендуемый способ запуска µStreamer для работы с Auvidea B101 на Raspberry Pi:

$ ./ustreamer \
    --format=uyvy \ # Настройка входного формата устройства
    --encoder=m2m-image \ # Аппаратное кодирование с помощью драйвера V4L2 M2M
    --workers=3 \ # Максимум воркеров
    --persistent \ # Не переинициализировать устройство при таймауте (например, когда был отключен HDMI-кабель)
    --dv-timings \ # Включение DV-таймингов
    --drop-same-frames=30 # Экономим трафик

❗ Обратите внимание, что для использования --drop-same-frames для разных браузеров нужно использовать ряд специальных параметров в /stream (за деталями обратитесь к урлу /).

За полным списком опций обращайтесь ко встроенной справке: ustreamer --help.


Камера Raspberry Pi

Пример использования камеры Raspberry Pi v1:

$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944

❗ Обратите внимание что боле новые модели камеры имеют другое максимальное разрешение. Список поддерживаемых разрешений можно найти в документации PiCamera.

❗ Если камера выдает низкий фреймрейт, возможно что она работает в фото-режиме, где производит более низкий фпс, но более качественную кратинку. Это происходит потому что bcm2835-v4l2 переключает камеру в фото-режим на разрешениях выше 1280x720. Чтобы обойти это, передайте параметры max_video_width и max_video_height при загрузке модуля, например:

$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944

Интеграция

Nginx

Если uStreamer находится на Nginx, то последний будет буферизировать поток и создавать дополнительную задержку в стриме. Чтобы задержки не было, буферизацию можно отключить:

location /stream {
    postpone_output 0;
    proxy_buffering off;
    proxy_ignore_headers X-Accel-Buffering;
    proxy_pass http://ustreamer;
}

Утилиты V4L2

V4L2 предоставляет ряд официальных утилит для управления USB-вебкамерами и получения информации об устройствах. С их помощью можно писать всякие настроечные скрипты и запускать их по крону, если, например, вам требуется изменять настройки экспозиции в зависимости от времени суток. Пакет с этими утилитами доступен на всех дистрибутивах Linux и обычно называется v4l-utils.

  • Вывести список видеоустройств: v4l2-ctl --list-devices.
  • Вывести список доступных контролов устройства: v4l2-ctl -d /dev/video0 --list-ctrls.
  • Вывести список доступных форматов видео: v4l2-ctl -d /dev/video0 --list-formats-ext.
  • Показать текущее значение контрола: v4l2-ctl -d /dev/video0 --get-ctrl=exposure_auto.
  • Изменить значение контрола: v4l2-ctl -d /dev/video0 --set-ctrl=exposure_auto=1.

Больше примеров вы можете найти здесь, а документацию в man v4l2-ctl.


Смотрите также


Лицензия

Copyright (C) 2018-2022 by Maxim Devaev mdevaev@gmail.com

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see https://www.gnu.org/licenses/.