В рамках данной статьи планируется знакомство с V4L и работа с камерой через него. То есть в статье не будет использоваться возможно привычное ранее
/dev/video0или/dev/video1.
Данная статья основана на использовании:
В данной статье имя пользователя принимается как
orangepi, так как используется готовая сборка от silveralx для Orange Pi 3 LTS
Убедимся, что в системе присутствуют необходимые для правильной работы пакеты:
sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev v4l-utils
sudo usermod -aG video $USER
Чтобы права группы
videoнормально применились, рекомендуется выйти из системы командойlogout, а потом повторно открыть терминал.
Но основная логика подключения и настройки камеры будет идентичной для большинства MJPG камер.
Для определения камеры используется команда
lsusb

По выводу команды видно, что Linux определил наличие USB камеры Logitech C910, получим ее идентификатор:
ls -al /dev/v4l/by-id

В моем случае определилась видеокамера по адресу /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 и в дальнейшем в статье будет использоваться именно он.
У одинаковых USB камер идентификаторы могут быть так же идентичны!
В случае использования двух одинаковых USB камер их идентификатор через by-id может совпдать, что не позволит запустить два стрима. Для решения этой проблемлемы с идентификатором необходимо по аналогии с MCU использовать by-path
Для определения подключенных USB устройств выполните следующую команду:
ls -al /dev/v4l/by-path
v4l2-ctl -d /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --list-formats

Из вывода команды следует, что камера Logitech C910 поддерживает 2 режима работы:
Нас интересует именно режим MJPG, поэтому следующей командой определим доступные разрешения и частоту кадров для них:
v4l2-ctl -d /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --list-formats-ext

Хочу обратить Ваше внимание, что изображение выше - это СИЛЬНО уменьшенный объем вывода информации. В котором оставлены только 3 режима. Один для YUYV и два для MJPG. Красной линией показан основной разрыв выводных данных.
По выводу команды разберем режим MJPG 1280x720. Данный режим позволяет при заданном разрешении получить 5, 7.5, 10, 15, 20, 24 и 30 fps.
В дальнейшем я буду использовать именно его в режиме стриминга: 720p30f или 1280x720 при 30 кадрах в секунду.
Камеры имеют дополнительные настройки, такие как: яркость, контрастность, баланс белого, ручное управление фокусом и другие настройки. Для того чтобы определить доступные конкретной камере настройки выполним команду:
v4l2-ctl -d /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --list-ctrls
где:
/dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 - это камера которую опрашиваем.
Вывод команды будет выглядеть следующим образом:

Теперь настроим яркость brightness
Получаем текущее значение только этого параметра:
v4l2-ctl -d /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --get-ctrl=brightness
А теперь установим его равным 200
v4l2-ctl -d /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --set-ctrl=brightness=200

Подобным образом можно работать со всеми параметрами, которые были перечислены в выводе команды v4l2-ctl --list-ctrls для конкретной камеры.
В своей сути является тем же µStreamer, только имеет более удобную обёртку в виде настроек и соответствующих скриптов. Работать будет так же или как минимум не хуже оригинального µStreamer.
Важно помнить, что одномоментно с камерой может работать только один стример, поэтому если у Вас уже установлен и настроен
µStreamerили наоборот, то все вновь установленные стримеры работать не будут, до удаления предыдущих стримеров.
Для установки и удаления восполюзуйтесь KIAUH
Официальная документация: https://crowsnest.mainsail.xyz/
Конфиг стримера расположен по пути и доступен из веб интерфейса
nano ~/printer_data/config/crowsnest.conf
В базовом своем виде конфиг выгдядит следующим образом:
[crowsnest]
log_path: ~/printer_data/logs/crowsnest.log
log_level: quiet
[cam 1]
mode: mjpg
port: 8080
device: /dev/video0
resolution: 640x480
max_fps: 15
Следовательно, основываясь на блоке V4L выше, приведем конфиг к
[crowsnest]
log_path: ~/printer_data/logs/crowsnest.log
log_level: quiet
[cam 1]
mode: mjpg
port: 8080
device: /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0
resolution: 1280х720
max_fps: 30
Если у Вас есть вторая камера, то в этом же конфиге просто добавьте еще один раздел, со следующим порядковым номером, т.е.: [cam 2]
и уже в нем опишите настройки второй или последующей камеры. Необходимости создавать для каждой камеры новый сервис при исользовании crowsnest - отсутствует.
Легковесный стример, входит в состав crowsnest, поэтому его прямое использование рекомендуется только тем, кто знает что делает.
Важно помнить, что одномоментно с камерой может работать только один стример, поэтому если у Вас уже установлен и настроен
Crowsnestили наоборот, то все вновь установленные стримеры работать не будут, до удаления предыдущих стримеров.
Для установки нам потребуется скачать актуальную верисию µStreamer с GitHub. Для этого необходимо выполнить следующие действия:
sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev v4l-utils
git clone --depth=1 https://github.com/pikvm/ustreamer
cd ustreamer
make
Для полноценной дальнейшей работы запускаем тестовый стрим, где в параметрах передаем устройство /dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0, порт 8080. Параметр --host=0.0.0.0 означает, что стрим будет вестись по всем доступным для данного хоста ip-адресам.
cd ~/ustreamer
./ustreamer --device=/dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --host=0.0.0.0 --port=8080
Если все прошло правильно, то в консоли будет примерно следующее:

По умолчанию µStreamer запускается в режиме YUYV с разрешением 640х480 и сам жмёт JPEG с 80% качеством.
Для остановки процесса µStreamer на данном этапе необходимо нажать CTRL+C.
Далее необходимо подобрать настройки, которые будут устраивать лично Вас, а также будут нормально работать на Вашем оборудовании. Выше мы разбирали вывод команды v4l2-ctl --list-formats-ext, поэтому выбирать необходимо из доступных режимов конкретной камеры.
Для себя я выбрал следующие настройки стриминга: 1280х720, 30 кардров, MJPG.
cd ~/ustreamer
./ustreamer --device=/dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --host=0.0.0.0 --port=8080 --resolution 1280x720 --desired-fps=30 --format=MJPEG --drop-same-frames=30
Разберем параметры:
--device=/dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 - вебкамера, в данном случае Logitech C910, которая передается не как /dev/video0 или подобным образом, а конкретным идентификатором, как и MCU, что позволит использовать несколько камер, в том числе однотипных, при этом настройки стримминга для каждой из них не изменятся при перезагрузках и тп.
--host=0.0.0.0 - стрим идет по всем доступным ip-адресам хоста.
--port=8080 - порт, на который идёт стрим.
Обращаю Ваше внимание, что на одном порту может быть только один стриммер. Два стриммера в один порт не влезут.
--resolution 1280x720 - разрешение, с которым ведётся стрим, список доступных режимов для Вашей камеры нужно определить самостоятельно по описанию выше.
--desired-fps=30 - частота кадров, с которой ведётся стрим, список доступных режимов для Вашей камеры нужно определить самостоятельно по описанию выше. В случае, если запрашиваемая частота кадров выше, чем может обеспечить выбранный режим у камеры, то случится чудо, и µStreamer дополнит недостающие кадры путем повторения предыдущих.
--drop-same-frames=30 - настройка, позволяющая экономить трафик, повторяющиеся кадры изымаются из трафика.

По выводу в консоль видно, что стрим успешно запустился, частота кадров соответствует возможностям камеры. Но при этом стример не нашел аппаратный кодировщик MJPG, который бы снизил нагрузку на процессор.
А вот тут будет магия создания сервисов...
Установим µStreamer в систему для возможности нормального использования в сервисах.
cd ~/ustreamer
sudo make install

Из вывода консоли выше видно, что µStreamer установился по следующему пути: /usr/local/bin/ustreamer, который в дальнейшем и необходимо использовать при создании сервисов.
Теперь создаем сервис:
sudo nano /etc/systemd/system/ustreamer-c910.service
где ustreamer-c910.service - название сервиса, для удобства используется префикс сервиса ustreamer, затем добавляется наименование конкретной камеры c910. При этом вы можете назвать сервис любым другим именем, например printsream.service.
Если Вы используете несколько камер, то для каждой камеры нужно создать отдельный сервис µStreamer.
И вставляем туда следующий блок:
[Unit]
Description=uStreamer service c910
After=network.target
[Service]
User=orangepi
ExecStart=/usr/local/bin/ustreamer --process-name-prefix ustreamer-c910 --log-level 0 --device=/dev/v4l/by-id/usb-046d_0821_A212F1B0-video-index0 --host=0.0.0.0 --port=8080 --format=MJPEG --resolution 1280x720 --desired-fps=30 --drop-same-frames=30
[Install]
WantedBy=multi-user.target
Включаем сервис:
sudo systemctl enable ustreamer-c910.service
Запускаем сервис:
sudo systemctl start ustreamer-c910.service
Для проверки успешного запуска сервиса выполним следующую команду:
systemctl status ustreamer-c910
Где ustreamer-c910 – это название ранее созданного, активированного и запущенного сервиса.

По информации, полученной в выводе статуса сервиса, видно что он активен, ошибок при запуске не обнаружено.
Для остановки и отключения сервиса, используются следующие команды:
sudo systemctl stop ustreamer-c910.service
sudo systemctl disable ustreamer-c910.service
В данном блоке рассмотрим как отобразить RTSP поток в web интерфейсе Fluidd, для этого потребуется конвертер go2rtc, который сможет перевести потоковый стрим из h.264(h.265) в привычный MJPG поток.
В качестве Ip камеры используется HiWath DS-i200, но основные шаги будут идентичны для большиства ip камер которые поддерживают RTSP поток, отличия будут при получении ссылки на сам поток, но об этом ниже.
В качесте хоста используется Raspberry Pi 4, с пользователем pi
Для определения типа и разраядности Вашей операционной системы, выполните:
uname -m

Дистрибутив определился как armv7l - что соответсвутет 32битному arm. Переходим на страницу выпуска go2rtc и скачиваем необходимую версию.
Для большинства одноплатных компьютеров подойдет просто arm версия, скачиваем и устанавливаем флаг исполняемого файла:
cd ~
wget https://github.com/AlexxIT/go2rtc/releases/download/v1.7.1/go2rtc_linux_arm
chmod a+x ./go2rtc_linux_arm
Для камер HiWath DS-i200 используется следующий URL:
rtsp://admin:12345@192.168.200.11:554/ISAPI/Streaming/Channels/101
где:
rtsp — тип используемого протокола
admin — имя учетной записи
12345 – пароль используемой учетной записи
192.168.200.11 — IP-адрес камеры
554 — RTSP порт камеры (по умолчанию 554, может быть изменен в настройках)
101 - это 1 камера 1 поток
201 - это 2 камера 1 поток
102 - это 1 камера 2 поток
Создаем файл настроек c учетом потока:
touch ~/go2rtc.yaml && nano ~/go2rtc.yaml
Добавляем конфигурацию камеры:
streams:
camera1: rtsp://admin:12345@192.168.200.11:554/ISAPI/Streaming/Channels/101
и тестово запускаем камеру:
./go2rtc_linux_arm

Не закрываем терминал, для остановки
go2rtc_linux_armнеобходимо нажать ctrl+c
Проверяем работоспособность, перейдя по ip адресу хоста и указываем порт 1984, должна открыться страница:

Переходим по ссылке: streams выбираем и копируем ссылку для WebRTC

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

В настройках необходимо указать HTTP page, ссылку на камеру получили в предыдущем шаге, а соотношение строн выбираем в соответствии с камерой, HiWath DS-i200 имеет соотношение 16:9.
Убеждаемся в правильном отображении камеры в интерфейсе Fluidd.
Останавливаем go2rtc_linux_arm нажимая ctrl+c.
Для работы транскодинга должен быть установлен ffmpeg
Изменить конфигурацию камеры, добавив дополнительный стрим:
streams:
camera1:
- rtsp://admin:12345@192.168.200.11:554/ISAPI/Streaming/Channels/101
- ffmpeg:camera1#video=mjpeg
Для работы транскодинга должен быть установлен ffmpeg
Изменить конфигурацию камеры, используя ffmpeg с параметром hardware:
streams:
camera1: ffmpeg:rtsp://admin:12345@192.168.200.11:554/ISAPI/Streaming/Channels/101#video=h264#hardware
camera1_mjpeg: ffmpeg:rtsp://admin:12345@192.168.200.11:554/ISAPI/Streaming/Channels/101#video=mjpeg#hardware
Чтобы каждый раз не запускать программу вручную, создадим соответствующий сервис.
Копируем файлы:
cd ~
sudo cp ./go2rtc_linux_arm /usr/local/bin/
cp ./go2rtc.yaml /home/pi/printer_data/config
Теперь создаем сервис:
sudo nano /etc/systemd/system/go2rtc.service
Обратите внимание, что User=pi это пользовательская учетная запись в вашей системе, которая используется в том числе для Klipper.
[Unit]
Description=go2rtc service
After=network.target
[Service]
User=pi
ExecStart=/usr/local/bin/go2rtc_linux_arm -config /home/pi/printer_data/config/go2rtc.yaml
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
Включаем сервис:
sudo systemctl enable go2rtc.service
Запускаем сервис:
sudo systemctl start go2rtc.service
В случае необходимости, остановка сервиса:
sudo systemctl stop go2rtc.service
Удаление сервиса:
sudo systemctl disable go2rtc.service