2018-10-15 06:50:38 +03:00
2018-10-14 20:55:31 +03:00
2018-10-02 13:57:28 +03:00
2018-10-10 00:08:13 +03:00
2018-09-25 11:04:39 +03:00
2018-09-21 04:07:32 +03:00
2018-10-06 00:50:30 +03:00
2018-10-10 00:08:13 +03:00
2018-10-15 06:50:38 +03:00

µStreamer

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

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

Фича µStreamer mjpg-streamer
Многопоточное кодирование JPEG #00aa00 Есть #f03c15 Нет
Аппаратное кодирование с помощью OpenMAX IL на Raspberry Pi #00aa00 Есть #f03c15 Нет
Поведение при физическом отключении устройства
от сервера во время работы
#00aa00 Транслирует черный экран
с надписью NO SIGNAL,
пока устройство не будет подключено снова
#f03c15 Прерывает трансляцию 1
Поддержка DV-таймингов - возможности изменения
параметров разрешения трансляции на лету
по сигналу источника (устройства видеозахвата)
#00aa00 Есть #ffaa00 Условно есть 1
Возможность пропуска фреймов при передаче
статического изображения по HTTP
для экономии трафика
#00aa00 Есть 2 #f03c15 Нет
Дебаг-логи без перекомпиляции,
логгирование статистики производительности,
возможность получения параметров
трансляции по HTTP
#00aa00 Есть #f03c15 Нет
Поддерживаемые входные форматы устройств #ffaa00 YUYV, UYVY,
RGB565, MJPG 3
#00aa00 YUYV, UYVY,
RGB565, MJPG
Поддержка контролов веб-камер (фокус,
движение сервами) и всяких настроек,
типа яркости, через HTTP
#f03c15 Нет #00aa00 Есть
Возможность сервить файлы встроенным
HTTP-сервером, настройки авторизации
#f03c15 Нет 4 #00aa00 Есть

Сносочки:

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

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

  • 3 Поскольку µStreamer писался в первую очередь для устройств видеозахвата, в нем реализованы только те форматы, которые для них были нужны. MJPG в контексте входных данных означает, что устройство умеет самостоятельно сжимать картинку в JPEG и отдавать ее программе, что позволяет значительно снизить загрузку процессора и избавить его от необходимости кодировать картинку софтом. Этот формат поддерживается большинством веб-камер, но не поддерживается ни одним из встреченных мной устройств видеозахвата; его не умеет ни Auvidea B101, ни EasyCap UTV 007. Нет никаких технических сложностей добавить поддержку аппаратного MJPG источника, но у меня просто пока не дошли до этого руки.

  • 4 ... и не будет. µStreamer придерживается концепции UNIX-way, так что если вам нужно нарисовать маленький сайтик со встроенной трансляцией - просто поставьте NGINX.


TL;DR

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


Сборка

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

На Raspberry Pi програма автоматически собирается с поддержкой OpenMAX IL, если обнаружит нужные хедеры в /opt/vc/include.

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

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


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

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

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

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

$ ./ustreamer \
    --format=uyvy \ # Настройка входного формата устройства
    --encoder=omx \ # Использование аппаратного кодирования с помощью OpenMAX
    --dv-timings \ # Включение DV-таймингов
    --quality=20 \ # У OpenMAX нелинейная шкала качества
    --drop-same-frames=30 # Экономим трафик

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


Лицензия

Copyright (C) 2018 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/.

Languages
C 95.8%
Python 1.5%
Makefile 1.4%
Shell 0.5%
Dockerfile 0.5%
Other 0.3%