Видеонаблюдение на базе NanoPi R4S, rclone и mediamtx

в 16:05, , рубрики: mediamtx, видеонаблюдение, видеорегистратор, видеорегистраторы, запись видео, запись видео с камеры, запись видеопотока, камеры видеонаблюдения, камеры наблюдения, камеры наружного наблюдения

В этой статье я расскажу, как организовал себе примитивный видеорегистратор, который:

  1. Умеет транслировать видео на любые устройства, где есть браузер с поддержкой h264, причем без использования китайских серверов.

  2. Вести циклическую запись в формате mp4 и сохранять её удалённо.

  3. Стоит меньше 100$.

Изначально у меня была задача организовать себе регистратор, который будет непрерывно писать всё происходящее с камер и по защищённому каналу загружать записи на удалённый сервер. Ошибочно предположив, что это вполне банальная задача, я приобрёл себе регистратор dahua NVR NVR5208-EI… Каково же было моё разочарование, когда выяснилось, что купленное устройство содержит ряд фатальных недостатков:

  1. Из удалённых хранилищ поддерживается только FTP/SFTP. Причем к SFTP невозможно подключиться используя ssh-ключ (только логин и пароль).

  2. Сохраняет видео в неюзабельном dav формате. В природе не существует удобного способа конвертировать это безобразие в mp4.

  3. Дает этим dav-файлам какие-то бредовые имена.

  4. Толком не настраивается — интерфейс настройки весьма скуден.

  5. Глючит (то пишет, то не пишет) и не предоставляет никаких логов.

Скрытый текст

Отдельного упоминания заслуживает некомпетентность поддержки официальной поддержки dahuatech.com . Я приобрел удалённое FTP хранилище, где намеревался хранить записи, но регистратор упорно не мог к нему подключиться. Без проблем подключаюсь разных устройств, а регистратор выдаёт failed… Вместо помощи в решении, поддержка заняла позицию «у вас что-то не то с сервером, разбирайтесь сами». А после того, мой вопрос был перенаправлен в инженерный отдел, спустя 2 недели пришёл ответ «This sftp problem, with the customer's ftp server address, the development side made a lot of attempts, but also adjusted the encryption algorithm, but the authentication of the request sent to the server has been returned to the authentication failure, the device plus print to confirm that the username and password sent out of the problem, which requires the server to assist in investigating the reason why it will reject our login request.» В итоге экспериментальным путём выяснилось, что оборудование dahua работает только с OpenSSL версии 3+, а на сервере был установлен 1.0.2k-fips…

Поняв бесперспективность движения в сторону готовых регистраторов, пришлось искать альтернативные варианты. В итоге на основе R4S, rclone и mediamtx мне удалось создать стабильное решение.

Необходимые компоненты:

  1. Подключение к Интернету с реальным IP-адресом. Если ваш провайдер предоставляет доступ к сети через CGNAT, организовать webrtc трансляцию не получится.

  2. Камеры, способные выдавать RTSP поток в формате h264. В идеале брать камеры, которые способны выдавать 2 качественных потока (h254 и h265) одновременно. Я использую камеры dahua IPC-HDW3841T-ZS-S2.

  3. Хостинг, доменное имя, SSL-сертификат.

  4. Удалённое хранилище, куда при помощи rclone будет загружаться видео. Поддерживаются SFTP, Yandex.Disk, Google Drive, Dropbox и т. п.

  5. NanoPi R4S с OpenWRT (далее просто R4S). Его вполне можно заменить на любой одноплатник с линуксом аналогичной мощности, но в статье я буду использовать именно R4S. У меня он используется в качестве роутера, но, в силу избыточной мощности, вполне способен выполнять ещё и роль регистратора на 8 камер.

Настройка камер

Для живой webrtc трансляции нужно получать от камер RTSP поток с разрешением 1920x1080, видеокодеком H264 и аудиокодеком G711. Для сохранения видео, в идеале получать ещё один поток с видеокодеком H265, аудиокодеком AAC и разрешением 2560x1440.

Настройки одной из моих камер

Настройки одной из моих камер

Некоторые пояснения:

  1. Я не использую smart codec и AI codec. По ощущениям, они какие-то глючные: только размер сохраняемого файла увеличивается.

  2. Для сохранения оптимально использовать CBR с ключевым кадром не реже чем раз 3 секунды. Bitrate и Framerate подбираются индивидуально. Для трансляции (особенно через сотовые сети) подходит и VBR.

Поскольку ссылка на RTSP поток содержит логин и пароль, для доступа к потокам желательно создавать отдельного пользователя. В моём случае ссылки имеют вид:

  • rtsp://rtsp:password@192.168.1.1/cam/realmonitor?channel=1&subtype=0 – для основного H265 потока

  • rtsp://rtsp:password@192.168.1.1/cam/realmonitor?channel=1&subtype=2 – для дополнительного H264 потока.

Настройка R4S

На R4S необходимо установить OpenWRT. Далее предполагается, что читатель осилит его первоначальную настройку и сможет подключить к Интернету.

Схема работы: медиасервер mediamtx непрерывно сохраняет записи с камер отрывками по 5 минут во временный каталог. Каждые 3 минуты производится перенос файлов в хранилище. Раз в сутки хранилище очищается от устаревших файлов.

Стандартными средствами устанавливаем rclone и luci-app-ttyd. Из главного меню переходим в Services => Terminal, авторизуемся, командой rclone config запускаем интерактивный конфигуратор и создаём подключение к удалённом хранилищу с именем main (ниже будет встречаться в листингах конфигураций).

Чтобы не изнашивать карту памяти, хранить видеофайлы файлы на R4S оптимально во временном каталоге /tmp/cams, который расположен в оперативной памяти. Стандартно раздел для временных файлов довольно мал… Но у R4S на борту аж 4 Гб оперативки! Для роутера с лихвой хватит и 1 Гб, поэтому оставшиеся 3 Гб направляем в пользу временного хранилища. В System => Startup => Local Startup прописываем команду:

mount tmpfs /tmp -t tmpfs -o remount,size=3000m,nosuid,nodev

Чтобы настройки применились уже сейчас без перезагрузки, следует выполнить эту команду ещё и в терминале.

Теперь в настройках файрвола откроем порт 8889 через который будет вестись webrtc трансляция.

В файрволе разрешаем весь входящий трафик на порт 8889 R4S

В файрволе разрешаем весь входящий трафик на порт 8889 R4S

Далее создаём каталог /etc/config/mediamtx в который поместим файлы:

  • certificate.crt и certificate.key – файлы с SSL-сертификатом и его приватным ключом.

  • rclone.sh – запускается планировщиком задач каждые 3 минуты и выполняет перенос видеофайлов в хранилище. Содержимое:

#!/bin/sh

# Перенос файлов в удалённое хранилище
rclone move --min-age 3s --delete-empty-src-dirs --no-traverse /tmp/mediamtx main:/

# Лог последнего переноса
date > /etc/config/mediamtx/move.log
  • rclone_del.sh — запускается планировщиком задач раз в сутки и удаляет из хранилища устаревшие файлы. Содержимое:

#!/bin/sh

# Удаление устаревших файлов спустя неделю
rclone delete --min-age 1w main:/

# Лог последнего удаления
date > /etc/config/mediamtx/delete.log
  • mediamtx и mediamtx.yml – файлы из дистрибутива mediamtx (исполняемый файл и конфигурация). Скачивание доступно по ссылке, для R4S выбираем релиз для arm64v8.

В планировщике задач System => Scheduled Tasks прописываем строки для выполнения rclone.sh и rclone_del.sh:

*/3 * * * * /etc/config/mediamtx/rclone.sh
0 1 * * * /etc/config/mediamtx/rclone_del.sh

Медиасервер mediamtx поставляется в виде исполняемого файла. Чтобы он мог работать в фоновом режиме и запускаться вместе с системой, для него требуется создать initscript. На основе инструкции создаём файл /etc/init.d/mediamtx (обязательно с правами запуска). Содержимое:

#!/bin/sh /etc/rc.common

START=25
USE_PROCD=1

start_service() {
	procd_open_instance "mediamtx"
	procd_set_param command /etc/config/mediamtx/mediamtx /etc/config/mediamtx/mediamtx.yml
	procd_set_param stdout 1
	procd_set_param stderr 1
	procd_close_instance
}

reload_service() {
	echo "It reloads automatically";
	stop
	start
}

Настройка mediamtx

В конфигурационном файле /etc/config/mediamtx/mediamtx.yml находим секцию record и правим следующие параметры:

# Ежедневно записи сохраняются в новый каталог с текущей датой
recordPath: /tmp/mediamtx/%path/%Y-%m-%d/%H-%M-%S
recordFormat: fmp4
recordPartDuration: 1s
recordSegmentDuration: 5m
recordDeleteAfter: 7m

Далее переходим в секцию paths: и настраиваем потоки. Для камеры, которая умеет отдавать 2 потока, указываются 2 записи:

paths:
  # H264 поток для webrtc трансляции
  cam1:
    source: rtsp://rtsp:password@192.168.1.1/cam/realmonitor?channel=1&subtype=2
    record: no
    sourceOnDemand: yes

  # H265 поток для записи
  cam1r:
    source: rtsp://rtsp:password@192.168.1.1/cam/realmonitor?channel=1&subtype=0
    record: yes
    sourceOnDemand: no

Если же поток один, то запись выглядит так:

cam2:
  # H264 поток и для записи и webrtc трансляции
  source: rtsp://rtsp:password@192.168.1.2/cam/realmonitor?channel=1&subtype=0
  record: yes  
  sourceOnDemand: no

Если всё сконфигурировано верно, после запуска mediamtx, из локальной сети станут доступны webrtc трансляции по адресам http://r4s:8889/stream-name, а в каталоге /tmp/mediamtx/ начнут появляться mp4 файлы. Также уже должен работать планировщик задач и запускать каждые 3 минуты rclone, чтобы тот загружал эти файлы в удалённое хранилище.

Настройка домена

Используя тот факт, что ssl с проверкой домена защищает не только сам домен, но ещё и его www поддомен, можно сэкономить и обойтись всего одним таким ssl: домен должен указывать на хостинг (где размещено приложение), а поддомен www должен указывать на R4S. В зависимости от того, как провайдер предоставляет провайдер вам реальный IP (статический IP или DDNS), для поддомена www нужно внести соответствующую ресурсную A, AAAA или CNAME запись.

Возвращаемся к mediamtx.yml, переходим в секцию webrtc и прописываем ssl сертификат и домен (example.net указан в качестве примера):

webrtc: yes
webrtcAddress: :8889
webrtcEncryption: yes
webrtcServerKey: /etc/config/mediamtx/certificate.key
webrtcServerCert: /etc/config/mediamtx/certificate.crt
webrtcAllowOrigin: 'https://example.net'
webrtcTrustedProxies: []
webrtcLocalUDPAddress: www.example.net:8889
webrtcLocalTCPAddress: ''
webrtcIPsFromInterfaces: no
webrtcIPsFromInterfacesList: []
webrtcAdditionalHosts: [www.example.net]

После перезапуска, webrtc трансляция должна стать публично доступной по адресу https://www.example.net:8889/stream-name . Если всё ок, переходим к последнему этапу.

Ограничение доступа и просмотр

Доступ к трансляции, понятное дело, следует ограничивать. И мне хотелось перегружать этот маленький проект сложной системой аутентификации и базой данных. К счастью, любой хостинг позволяет ограничить доступ к выбранному каталогу по логину и паролю. На основе framework7 было разработано маленькое SPA приложение , разворачивание которого сводится к 3 шагам:

  1. Загрузите всё содержимое каталога build на хостинг (не обязательно в корень, можно и в каталог).

  2. Ограничьте доступ к каталогу build/restricted http аутентификацией.

  3. Заполните файл build/restricted/cameras.json, указав доступы к вашим потокам.

 {
	"caption":"Cameras",
	"host":"https://www.example.net:8889/",
	"streams":[
		["caption", "stream-name", "material-icon"],

		["East example", "cam1", "east", {"rotate":90}],
		["West example", "cam2", "west", {"rotate":-90}]
	]
}

Перечень иконок material-icon общедоступен. При помощи последнего параметра можно перевернуть изображение с камеры по часовой {"rotate":90} или против часовой {"rotate":-90} стрелки. Это особенно удобно, если камера снимает узкий проход и монтажник перевернул её на 90°.

Скриншоты SPA

Скриншоты SPA

Автор: Sunvas

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js