В рамках данной статьи планируется знакомство с 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