¶ Обязательные требования

Если выбрать режим кодирования, отличный от H.264, например, на некоторых камерах по умолчанию стоит H.265, то изображение не сможет корректно отобразиться в мобильном приложении РосДомофон.
Опыт показал, что при битрейте камеры более 1024Кбит/с начинаются проблемы проигрывания видео на мобильных устройствах конечных пользователей. Сказываются ограничения как каналов мобильной связи, так и самих устройств.
- Количество кадров в секунду (FPS — frames per second) — 15 кадров.
Исходя из нашего опыта, 15 простых кадров в секунду, это — идеальное сочетание качества и объема трафика.
- Частота опорных кадров (I Frame Interval, i-frame, frame rate) — 1 кадр в секунду или каждые 15 простых кадров
Частота опорных кадров критична при передаче live-видео. Чем больше расстояние между опорными кадрами, тем больше задержки видео от реальных событий. Для комфортного просмотра live-видео необходимо устанавливать минимальные значения частоты опорных кадров. Наш опыт показал, что 1 опорный кадр в секунду — это комфортный предел.
- Для корректной передачи видео-потока необходимо отключать RTSP шифрование.
- На видео-потоке обязательно должны быть выведены дата, время и адрес которые легко читаются в любое время суток.
Для абонентов, просматривающих видео в архиве важно знать точное время происходящих событий. Это особенно важно при разборе инцидентов. Поэтому на кадре всегда должно отображаться в хорошо видимой части дата и время. Пожалуйста, учитывайте, что это индивидуальное требование для каждой камеры.
- На камере обязательно должна быть включена синхронизация даты и временис NTP сервером.
Камеру могут перезагрузить в любой момент, например, при отключении питания в доме. Поэтому дата и время должны восстанавливаться автоматически. Для этого необходимо использовать синхронизацию с NTP сервером.
- Для камер с приватным видео-потоком (трансляция видео-потока идет через РДА) необходим статический локальный IP-адрес. Привязка производится на веб-интерфейсе роутера, ip-адреса камеры должен быть привязан к её mac-адресу.
Если не привязать локальный IP-адрес к MAC адресу приватной камеры, то при перезагрузке роутера у камеры сменится IP-адрес. В этом случае РДА не сможет получить видео-поток, так как в личном кабинете RDEA будет указан предыдущий IP-адрес. Как это сделать: найдите настройку на роутере «Привязка IP к МАС». Укажите свободный локальный IP-адрес и МАС адрес камеры, затем сохраните настройку и перезагрузите роутер.
- Должен быть открыт доступ на чтение с IP адресов: Список_IP-адресов_серверов_РосДомофон
На стороне, где размещены видеокамеры, возможны ограничения доступа по IP. В этом случае необходимо добавить IP адреса серверов РосДомофон в white list. Это требование не относится к «приватным» камерам, у которых используется локальный серый IP-адрес.
- Через 1 РДА (Pro,classic) можно пропустить не более 6ти приватных видео-потоков.
¶ Как правильно выставить значение опорного кадра (I Frame Interval, I-Frame, frame rate).
Особенность заключается в том, что одни производители камер привязывают значение опорного кадра к единице времени, секунде. Если производитель в настройках камеры дает нам возможность выбрать значение от «1» до «12» (или 20), следовательно, в этом поле необходимо выставить значение равное количеству опорных кадров, которое мы хотим получать с камеры за 1 секунду.
В этом случае необходимо выставить значение «1», что соответствует одному кадру в секунду. (см. скриншот ниже).

Другие производители камер привязывают значение опорного кадра к количеству простых кадров, через которое происходит опорный кадр (от 1 до 200). Если производитель в настройках камеры дает нам возможность выбрать значение от 1 до 200, следовательно, в этом поле необходимо выставить значение равное количеству простых кадров через которое будет происходить опорный кадр.
В этом случае необходимо выставить значение «15», что соответствует пятнадцати простым кадрам между опорными кадрами. (см. скриншот ниже).

¶ Проверка видеопотока с помощью VLC-плеера
Для проверки стабильности работы камеры, рекомендуем воспользоваться VLC-плеером https://www.videolan.org/vlc/index.ru.html.
После установки плеера выполните:
- Зайти во вкладу Инструменты → Настройки (Ctrl+P)
- В открывшемся окне перейти в раздел Ввод/кодеки
- В пункте Транспорт потока Live555 необходимо выбрать настройку RTP поверх RTSP (TCP)

- Нажать сохранить и закрыть окно с настройками.
- После этого необходимо открыть пункт Инструменты > Сообщения, в разделе Детализация: выставить 2(отладка)
- Затем перейти в раздел Медиа > Открыть URL.
- Ввести URI камеры в форматe: rtsp:/// — для каждой модели камеры ссылка на RTSP поток будет уникальна, необходимо обратиться к руководству по настройке вашей камеры
¶ Добавление RTSP ссылки в личном кабинете RDEA:

Пример.
Отдельные поля «логин» и «пароль» заполняются, если RTSP ссылка их не содержит.

¶ Использование видеопотоков под различные задачи
По умолчанию у каждоый ip-камеры имеется 2 потока:
- Main Stream (Основной или первычный)
- Sub Stream (Дополнительный или альтернативный)
Для каждого видеопотока возможно выставить индивидуальные настройки. Например, если вы используете регистратор для хранения локального архива на обслуживаемых объектах, то правильней было бы выставить более высокие настройки для основного потока, чтобы видеозапись велась в высоком качестве, но понизить настройки дополнительного потока для трансляции в приложение РосДомофон.
Key frame interval ip camera что это
02.09.2013 Сайт https://anteh.ru
Изложена суть вопроса. Приводятся личные домыслы. Основное окно настройки видео первичного потока приведено на изображении ниже и ещё ниже нагрузка и изображение, соответствующее настройкам. Если настройки задать неправильно, то получите нестабильную, и в некоторых случаях нерабочую систему.
Первый парамерт, с которым нужно определиться -это «Максимальный битрейт». Здесь есть 2 пути. 1 камера подключается к серверу сбора видеопотоков. 2 камера сама является сервером предоставляющим видеопотоки клиентам. В первом случае у камеры будет только 1 клиент, во втором сколько угодно. Отсюда, для первого случая bitrate можно выставить максимальным, для рассматриваемой камеры это 16384kbitp/s и ничего, если реальный будет меньше. Для второго случая, когда сама камера выступает в роли сервера и нужно на неё завести максимальное количество клиентов нужно параметр выбирать как можно меньше, но. Про но будет далее.
Bitrate можно назвать ключевым параметром, если его не будет хватать для передачи видео с заданным разрешением, fps, качеством и I Frame Rate, то получим проблемы, по крайней мере для этой камеры с передачей данных. Например если будет испотльзоваться udp, используется по умолчанию. То будут теряться кадры и ffmpeg будет постоянно отваливаться. ffmpeg1 будет продолжать работать, но будет выводить ошибки передачи. Если будет использован tcp, то ошибок не будет, но изображение будет кратковременно замирать, не все кадры будут доходить до сервера. Замирания можно наблюдать через web интерфейс камеры. Это совсем плохо, можно потерять важные кадры события.
Попробуем посчитать и проверить полученные значения:
Для текущих настроек Bitrate=704 * 576 * 10fps * 24bit color /1024 = 95040 kbit/s + служебные байты. Сжатие, качество, I Frame Interval без серьёзных знаний в этой области никак не учесть. Поэтому путь только один -эксперимнт.
Т.е. параметры настройки видео камеры нужно задавать так, чтобы скорость обмена между IP камерой и сервером не превышала заданный bitrate. Скорость обмена можно смотреть например через виндовс диспетчер задачь или на сервере, через ‘# systat -ifstat 1’. На вышеприведённых изображениях как раз показана реальная нагрузка на канал, при текущих настройках.
Задаваемые параметры всецело зависят от решаемой задачи. Если нужно получать поток для целей видеонаблюдения, или для трансляции живого видео потребителям, то параметры могут различаться весима существенно.

После bitrate следует обратить внимание на параметр ‘Интервал I кадра’ или I Frame Interval. Это интервал между ключевыми кадрами. Например, если =50, то только каждый 50й кадр будет ключевым, остальные разностные, содержашие информацию только о разнице между текущим и предыдущим изображением. Ключевой кадр полный и содержит всю информацию о текущем снимке. Т.е. если fps =10, то ключевой кадр будет передаваться раз в 5 секунд. Если I Frame Interval = 1, то каждый кадр будет ключевым. Мсысл этого параметра заключается в существенной экономии трафика, что можно проилюстрировать так:
Отсюда видим, что этот параметр существенно влияет на трафик.
Возвращаемся к случаю настройки IP камеры для видеонаблюдения. В видеонаблюдении большую роль играет достоверность кадра. И как правило используется mjpeg поток. Это важно для юридической силы видео, возможности увеличения кадра для более детального рассмотрения. Mjpeg представляет поток отдельных jpeg кадров, без межкадрового сжатия. Каждый кадр достоверный. Чтобы получить поток достоверных кадров без межкадрового сжатия для целей видеонаблюдения параметр I Frame Interval нужно установить в 1. Соответственно нагрузка на канал будет существенной и максимальным разрешением и fps уже не побалуешся. Так, на вышеприведённых изображениях были показаны максимально допустимые настройки для целей видеонаблюдения при цветном изображении. Если установить ночной режим, то fps можно поднять до 15. Параметр Quality для видеонаблюдения желательно установить максимальным. Разумеется всё зависит от количества камер, которое нужно завести на сервер, если это несколько, то параметры ставим получше, если за десяток, то похуже.
Если камеру настраиваем для прямой трансляции потребителям, то с настройками можно не стесняться. При помощи I Frame Interval и Quality трафик всегда можно подогнать под приемлемый. Причём для глаз особой разницы между quality среднее и максимальное не видно. Поэтому Quality для трансляции потока для просмотра не критично.
Назначение остальных параметров более менее понятно по смыслу.
Скриншоты демонстрирующие максимальные настройки для трансляции видео максимального качества напрямую потребителю человеку:
Для DS-2CD2012-I прошивка V5.0.2, как и V5.0.0 не пригодна, слишком сильно тормозит передача, наблюдаются множественные ошибки передачи потока. Нужно использовать только V4.0.9 версии ниже не проверял, с этой прошивкой и ffmpeg с udp работает без сбоев, но на всякий лучше использовать tcp. И в Zoneminder 1.25.0_2 с прошивкой V5.0.2 заметно наблюдались тормоза. В общем Hikvision как-то не очень, правда это суждение по одному текущему экземпляру камеры, но эту модель и все остальные, для которых предназначена эта прошивка покупать больше желания нет тем более за 8т.р.
Understanding the keyframe interval

IP cameras use video compression for 2 reasons: to save disk space and to save network bandwidth. A camera offers various configuration parameters regarding video compression, and one of them is the keyframe rate.
IP cameras use video compression for 2 reasons: to save disk space and to save network bandwidth. A camera offers various configuration parameters regarding video compression, and one of them is the keyframe rate.
How Video Compression Works
Unlike image compression (like jpeg), video compression uses a mechanism to save even more space: intraframe and interframe encoding. The first frame of the video is compressed like a normal frame (such as a jpeg) and a reference to it is retained. The following frame is compressed differently: only the differences with the first reference frame are kept. If nothing moves in the video scene, it means that the difference between the 2 video images is very small. This results in a very high compression of frame #2, since it is almost exactly the same as frame #1. However, the more changes there are in the scene, the more space is needed for the second frame. However, frame #2 will still be smaller using this type of difference encoding.
Frame #3 will be encoded using only the differences with frame #2. Frame #4 will be from the differences with frame #3, and so on…
After a certain number of frames, this encoding chain will be interrupted and a new complete keyframe will be generated. It is this keyframe that is often referred to as I-Frame
Here is an example of setting up a Uniview camera. The parameter here is called I Frame Interval. In this case, there will be 1 keyframe every 25 frames:

Here is an example with an Axis camera,. The parameter here is called GOP length. In this case, there will be 1 keyframe every 32 frames.

What settings should I use?
It depends. If you have little disk space, using a high keyframe rate can improve the space required to store the video. However, it may have an unwanted impact on video playback, especially when you search through the video. For example, if you try to position yourself at a specific moment in the replay, you will be positioned on the nearest keyframe. Why? Because a video decoder cannot decode an intermediate frame without decoding the previous key frame and the following frames. This can easily be noticeable when rewinding. You will notice that the rewind is a little jerky. This is because you will only see keyframes when viewing backwards.
A simple way to visualize this is to think about watching television (from your digital decoder for example). When you change the channel, sometimes it’s fast, sometimes it’s longer before you get the picture. This happens because the decoder is waiting for the next keyframe to arrive. So if the TV channel uses 1 keyframe every 2 seconds, you might have to wait up to 2 seconds when switching to the TV channel.
You will see the same effect with CCTV cameras. If the camera is configured to use 1 keyframe every 2 seconds, you may have to wait up to 2 seconds when connecting to the camera. The keyframe rate will have an effect on the speed at which you can connect to the camera.
I Frame Interval vs FPS
Each camera manufacturer uses a different nomenclature for frames per second and keyframe rate. The frame rate (fps) is the number of frames per second of the video stream. Keyframe, or I-frame interval, defines how often a keyframe is generated.
Here are some examples:

Example #1
The frame rate (fps) is fixed at 25, which means that the camera stream will be 25 frames/second. The I-frame interval is fixed at 25, which means that a keyframe will be generated every 25 frames. Doing some simple math, this means that a keyframe will be generated every 1 second.

Example #2
The frame rate is set to 10: 10 frames/second.
The I frame Interval is set to 40: 1 keyframe every 40 frames
Result: a keyframe will be generated every 4 seconds.
Here is an explanatory document which makes comparisons on the I frame rate:
Удаленный доступ к IP камерам. Часть 3. HEVC и web

HEVC (High Efficiency Video Coding — высокоэффективное кодирование видеоизображений), также известный как H.265, это видеокодек, широко используемый, в том числе, в системах видеонаблюдения. До недавнего времени веб браузеры практически не поддерживали этот формат. Но ситуация изменилась с выходом браузеров Chrome/Chromium версии 106. Это событие показалось мне достойным упоминания на Хабре, и в этой части статьи я расскажу, почему поддержка HEVC важна, о своих попытках подружить IP камеры с браузером и что из этого получилось.
В первой части я рассказывал о проксировании видеопотоков, во второй — о мобильном приложении. В этой статье будут использованы данные из обеих частей.
Итак, по данным caniuse HEVC работает в браузерах на основе Chrome/Chromium не ниже 106 версии (для Linux — не ниже 108 версии) при наличии аппаратного ускорения видео.

Меня интересует, в первую очередь, Linux. Но тут придется немного повозиться. Мне удалось запустить аппаратное декодирование для интегрированных видеокарт Intel HD Graphics 530 и Iris Plus Graphics 655, только указав переменные окружения LIBVA_DRIVER_NAME и LIBVA_DRIVERS_PATH (пример для Дебиан):
export LIBVA_DRIVER_NAME=iHD export LIBVA_DRIVERS_PATH=/usr/lib/x86_64-linux-gnu/dri
В Федоре путь другой: /usr/lib64/dri, в Арче — /usr/lib/dri.
Кроме того, мне пришлось включить API vulkan в настройках chrome://flags/#enable‑vulkan (или можно запускать браузер с флагами ‑enable‑features=Vulkan,VaapiVideoDecoder).
Конечно, в системе должен быть установлен нужный драйвер видеокарты. Вывод команды vainfo у меня выглядит примерно так:
$ vainfo Trying display: wayland vainfo: VA-API version: 1.17 (libva 2.17.1) vainfo: Driver version: Intel iHD driver for Intel(R) Gen Graphics - 23.1.0 () vainfo: Supported profile and entrypoints . VAProfileHEVCMain: VAEntrypointVLD VAProfileHEVCMain: VAEntrypointEncSlice VAProfileHEVCMain: VAEntrypointFEI VAProfileHEVCMain10: VAEntrypointVLD VAProfileHEVCMain10: VAEntrypointEncSlice .
После этого на странице chrome://gpu/ браузера в разделе Video Acceleration Information должно появиться упоминание HEVC:

К сожалению, это работало только в браузерах на основе Chromium 108. В 109-й версии поддержку libva в «никсах» сломали, и мне пока приходится пользоваться старой версией Brave (я его просто не обновляю). Следить за состоянием поддержки аппаратного декодирования можно, например, тут. В Windows и на Андроиде таких проблем я не наблюдал.
Тестирование MP4
Теперь, наконец, можно проверить, сможет ли браузер воспроизводить запись с IP камеры в формате H.265. Записываю тестовый фрагмент
ffmpeg -i rtsp://:554 -c copy -t 10 265.mp4
и открываю его в браузере — работает. Теперь можно рассмотреть варианты доставки видеопотока пользователю, используя только элемент , без сторонних библиотек и зависимостей и не устанавливая на клиентское устройство никаких дополнительных программ и плагинов.
HLS, MPEG-DASH и MSE
Браузер может «нативно» воспроизводить HLS (HTTP Live Streaming) — протокол потоковой передачи от Apple, это не опечатка. Дело в том, что HLS поддерживает совместимый с MPEG‑DASH формат m4s. Записать такой поток можно примерно так:
ffmpeg -i rtsp://:554 -c:v copy -an -strftime 1 -strftime_mkdir 1 \ -f hls -hls_segment_type fmp4 -hls_segment_filename %Y%m%d/%H%M%S.m4s live.m3u8
Полученные сегменты можно воспроизвести в браузере, используя MSE (Media Source Extensions).
const baseUrl = 'http://0.0.0.0:8000'; const initUrl = baseUrl + '/init.mp4'; const templateUrl = baseUrl + '/20230201/$dt$.m4s'; const sourceType = 'video/mp4; codecs="hev1.1.6.L120.0"'; let datetime = '095227'; const mediaSource = new MediaSource(); if ('MediaSource' in window && MediaSource.isTypeSupported(sourceType)) < mediaSource.addEventListener('sourceopen', onSourceOpen, < once: true >); window.video.src = URL.createObjectURL(mediaSource); > else < console.error('Unsupported MIME type or codec: ', sourceType); >function onSourceOpen() < const sourceBuffer = mediaSource.addSourceBuffer(sourceType); fetch(initUrl) .then(response =>response.arrayBuffer()) .then(data => < sourceBuffer.appendBuffer(data); sourceBuffer.addEventListener('updateend', fetchNextSegment, < once: true >); >); > function fetchNextSegment() < fetch(templateUrl.replace('$dt$', datetime)) .then(response =>response.arrayBuffer()) .then(data => < const sourceBuffer = mediaSource.sourceBuffers[0]; sourceBuffer.appendBuffer(data); // TODO: Fetch further segment and append it. >); >
API mse требует явного указания кодека, в этом примере — hev1.1.6.L120.0. Получить его можно так:
MP4Box -info init.mp4 2>&1 | grep RFC6381 | awk '' | paste -sd , -
Впрочем, в моем случае браузер не декодирует поток, поэтому сработает любой совместимый кодек.
Аналогичным образом можно использовать и технологию MPEG‑DASH (Dynamic Adaptive Streaming over HTTP). Команда
ffmpeg -i rtsp://:554 -c:v copy -an -f dash -t 10 playlist.mpd
создаст похожую структуру (только strftime тут не поддерживается), сегменты так же будут записаны в файлы .m4s, для воспроизведения можно так же использовать MSE.
Но для воспроизведения сегментов m4s необходим файл инициализации и плейлист, поэтому воспроизвести их напрямую не получится. Мне же хотелось иметь архив, который можно воспроизводить любыми подручными средствами, поэтому я стал поглядывать в сторону «чистого» mp4.
MP4
Сегменты mp4 можно записывать, например, так:
ffmpeg -i rtsp://:554 -c:v copy -an -f segment -reset_timestamps 1 \ -strftime 1 %Y%m%d/%H/%M/%S.mp4
Их можно воспроизводить чем угодно, а в браузере не нужен даже MSE. Это меня устроило, и я написал небольшое веб приложение для записи и воспроизведения видеопотоков с камер в режиме почти реального времени.
При создании приложения я использовал наработки проектов python-rtsp-server и Камеры. Не уверен, есть ли смысл дублировать листинги файлов здесь, исходники доступны на гитхабе. Пожалуй, детали реализации не так важны (в проекте около двадцати небольших файлов). Если возникнут вопросы, прошу задавать их в комментариях.
Итак, поскольку я не буду использовать MSE, сегменты придется «склеивать» в непрерывный видеопоток. Просто менять атрибут src тега не получится, даже если предварительно загружать сегменты в blob — изображение при этом мигает. Поэтому для «бесшовного» воспроизведения я использовал два элемента , расположенные друг над другом (с разными значениями z-index). По окончании воспроизведения сегмента элементы просто меняются местами. Атрибут src нижнего (невидимого) элемента меняется заранее, и браузер асинхронно выполняет предварительную загрузку изображения (preload). Это, пожалуй, единственная тонкость в клиентской части приложения.
UPD. В реальных проектах использование MSE всё же предпочтительней из-за меньшей нагрузки на браузер при манипуляциях с DOM. В этом случае нужно дополнительно фрагментировать каждый сегмент (добавить к ffmpeg опцию «-segment_format_options movflags=faststart+frag_keyframe+empty_moov+default_base_moof»), а буфер MediaSource переключить в режим «sequence» для воспроизведения в порядке добавления сегментов.
Вот что получилось в итоге:

Линия с ползунком внизу экрана — шкала времени. По умолчанию ползунок находится в крайнем правом положении, что соответствует прямой трансляции. Доступ ко всему видеоархиву предоставляется с этого же экрана, точки на шкале времени помогают ориентироваться по дням. Здесь, пожалуй, нужно подробнее остановиться на упомянутой выше команде ffmpeg и том, что и как она делает.
Файлы
Ffmpeg просто записывает файлы сегментов, последовательно и непрерывно. Длительность каждого сегмента равна длине GOP (Group of Pictures ), а точнее, интервалу между ключевыми I-кадрами (intra-coded frame). Это минимально возможная длительность сегмента, задается она в настройках камеры и для моего парка камер обычно равна 4 секундам, что при частоте кадров 25 fps соответствует 100 кадрам. Таким образом, при заданной вложенности папок ГГГГММДД/ЧЧ/MM/CC.mp4 каждая конечная папка должна содержать 15 файлов CC.mp4.
Эти файлы не удаляются в течение заданного в файле server/_config.py периода времени (по умолчанию 14 дней) и просто загружаются в элементы клиентской стороны в нужном порядке.
Клиенты не обращаются к камерам напрямую, а читают уже записанные статические сегменты. Таким образом выполняется одно из главных условий — к камере должно быть лишь одно подключение (в первой части статьи я упоминал, что камеры плохо поддерживают множественные подключения).
Размер файла сегмента составляет в среднем 100. 200 кБ в зависимости о освещенности сцены и активности движения. Это связано с особенностями алгоритма сжатия HEVC. Впрочем, к сжатию я вернусь позже, а сейчас важно то, что сегменты имеют небольшой размер, а это, в свою очередь, обеспечивает быструю загрузку видео в браузер. Очень быструю загрузку. В среднем в локальной сети (а это наиболее типичный случай применения) со скоростью соединения 1 Гбит и при использовании SSD на сервере сегмент загружается около 50 мс. Это дает возможность менять кадры с частотой до 20 fps при движении ползунка времени, то есть фактически без видимых задержек вручную двигать время в нужном направлении и с нужной скоростью. Такая отзывчивость действительно впечатляет!
Правда, при проксировании трафика через интернет скорость может значительно падать (у меня частота кадров опускалась до 2 fps). Это же относится и к мобильным устройствам, у которых не хватает ни вычислительных ресурсов, ни ширины канала. Впрочем, загружается сегмент все равно значительно быстрее, чем при подключении по rtsp.
Нагрузка
Важным достоинством такой схемы является, помимо скорости, практически нулевая нагрузка и на сервер, и на клиента. Дело в том, что видеопоток передается от камеры до клиента без транскодирования. То есть, грубо говоря, видеопроцессор клиентского устройства воспроизводит видео в том виде, в котором его передает камера. Средняя нагрузка на процессор сервера, по моим наблюдениям, составляет около 0.05 % в зависимости от производительности оборудования. Это дает возможность свободно подключить к одному серверу более сотни камер.
Объяснять важность снижения нагрузки на клиентское устройство, особенно на смартфон, я думаю, не нужно.
Место на диске
При почти нулевой нагрузке и высокой скорости узким местом серверной стороны приложения становится место на диске, дефицит которого заставляет ограничивать либо количество камер, либо длительность видеоархива.
И тут на помощь снова приходит HEVC, а точнее, его модификация H.265+ — cовременный метод компрессии в видеонаблюдении, впервые предложенный компанией Hikvision. Эта технология, в числе прочего, позволяет существенно (по данным компании на 30-50%) сэкономить место на жестком диске. Но и это еще не всё, позже я рассмотрю эту тему под другим углом, а сейчас вернусь к интерфейсу приложения.
Интерфейс
При ширине экрана 1920 пикселей и продолжительности видеоархива 14 дней точность позиционирования шкалы времени (под капотом там обычный ) составляет около 10 минут. Это позволяет очень быстро найти нужное событие, если известно его время или событие оставило визуальный след. Быстро, но не очень точно. Чтобы добраться до нужного сегмента, можно воспользоваться дополнительными стрелками над шкалой времени.
Шкала перемотки почти логарифмическая: 1 сегмент (~4 секунды), 1 минута, 10 минут, 1час. Это позволяет попасть в нужное время за ограниченное число последовательных итераций.
Молния в центре — переключатель ускоренного воспроизведения, а значок, похожий на Wi-Fi — детектор движения. Тут, пожалуй, стоит сделать еще одно отступление.
Детектор движения
Эксплуатирует ещё одну особенность алгоритма сжатия Н.265+. Дело в том, что упомянутый выше ключевой кадр, упрощенно говоря, содержит полное изображение сцены, а дальнейшие элементы GOP — лишь её изменение. Это означает, что при появлении в кадре движущегося объекта размер файла сегмента растет, и в случае сжатия Н.265+ растет настолько значительно, что это увеличение размера достаточно достоверно можно считать признаком движения. Поэтому в режиме «детектора движения» я просто сравниваю размер текущего файла с предыдущим и, в случае превышения порогового значения, такой сегмент попадает в на экран. Удивительно, но несмотря на примитивнейший алгоритм, это сработало. Безусловно, этот алгоритм можно и нужно улучшить, но в рамках моего эксперимента по велосипедостроению достаточно просто знать, что это возможно.
Кстати, в режиме H.265+ камеры Hikvision не поддерживают (UPD: на самом деле, поддерживают, но с некоторыми ограничениями) доступ к API встроенной системы оповещения (по крайней мере, мои экземпляры), поэтому такой способ обнаружения вполне имеет право на жизнь.
PWA и SSL
Получившееся приложение я оформил в виде PWA (progressive web app), в основном, ради мобильных устройств. Одним из обязательных требований для работы PWA является наличие валидного SSL сертификата. Но если для обычного интернет ресурса можно использовать, например, сертификат letsencrypt, то в локальной сети это проблематично. Ну и ладно, создам самозаверенный сертификат, примерно так:
sudo openssl genrsa -out rootCA.key 4096 sudo openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 \ -subj "/C=ХХ/L=Nsk/O=R&K/OU=R&K/CN=R&K" -out rootCA.crt sudo chown $(whoami):$(whoami) rootCA.key openssl genrsa -out localhost.key 2048 openssl req -new -sha256 -key localhost.key \ -subj "/C=ХХ/L=Nsk/O=localhost/OU=localhost/CN=localhost" -out localhost.csr openssl x509 -req -sha256 -in localhost.csr -out localhost.crt -days 3650 \ -CAkey rootCA.key -CA rootCA.crt -CAcreateserial -extensions SAN \ -extfile <(printf "[SAN]\nsubjectAltName=DNS:localhost,DNS:ваш-домен,IP:127.0.0.1,IP:ваш-ip") sudo chown root:root rootCA.key
В этом примере известная корпорация «Рога и копыта» из страны ХХ выдает сертификат не менее известной организации Локалхост. После этого файлы localhost.crt и localhost.key нужно поместить в папку server приложения, а корневой сертификат rootCA.crt импортировать в браузер в разделе chrome://settings/security — Настроить сертификаты — Центры сертификации — Импорт. Конечно, ключ rootCA.key нужно хранить в максимально защищенном месте.
Теперь в меню браузера должен появиться пункт «Установить приложение». Полную информацию о соответствии приложения требованиям PWA можно посмотреть, выполнив анализ страницы на вкладке Lighthouse в инструментах разработчика.
Организация приложения
Настройки приложения находятся в файле server/_config.py и, в целом, аналогичны настройкам python-rtsp-server.
Настройки групп временно находятся в этом же файле. Поясню: группа объединяет несколько камер на одном экране, это важнейшая часть приложения. Позволяет одновременно показывать объект с нескольких ракурсов или несколько объектов. Это самый востребованный экран для оперативного выяснения обстановки.
Приложение целиком закрыто авторизацией. В конфигурации задается мастер-пароль для доступа ко всем камерам и группам и пароль для доступа к отдельным камерам. Для тестирования мне этого достаточно.
Итоги
Прошу не считать сказанное выше непреложной истиной — это всего лишь моё личное мнение, основанное на личном опыте. Приложение находится в стадии раннего альфа-тестирования и ни в коем случае не готово к промышленной эксплуатации. Но у него уже есть очевидные преимущества и недостатки. Чтобы было понятней, сравню cams-pwa с предыдущим проектом Камеры.
Преимущества:
- Несмотря на статус эксперимента, в этом приложении уже сейчас больше функционала. По сути, это «киллер-фича» проекта. Похоже, получив свободный доступ к видеоархиву, моя мини-фокус-группа не собирается возвращаться к предыдущей версии:)
- Работает на любых устройствах, где можно установить свежий Хром.
- Скорость. Подключение по протоколу rtsp может «зависнуть», пока не будет получен ключевой кадр. В зависимости от длины GOP, подключение может занимать более 10 секунд. Это много. Проксирование через сегменты гарантирует почти мгновенное получение картинки.
- Простые настройки на стороне клиента. Пользователю не нужно вводить страшные rtsp адреса, айпи, каналы и прочие непонятные штуки.
- «Нативное» масштабирование. Из‑за особенностей реализации плагина libvlc, используемого в Камерах, поверхность изображения увеличивается «как есть». Это приводит к тому, что при просмотре камер высокого разрешения на устройствах с более низкой плотностью пикселей увеличенное изображение смазывается. Масштабирование средствами браузера, в числе прочего, решает эту проблему.
Недостатки:
- Требуется серверная часть и специалист для её настройки.
- Более высокая задержка (отставание) воспроизведения в «прямом эфире». Поскольку в этом проекте воспроизводится последний законченный файл, задержка составляет 1 GOP относительно реального времени. Пока я с этим ничего не делал. Не очень критично из-за того, что отчасти компенсируется временем на открытие приложения, но всё же требует внимания.
P.S. Сохранение сегментов средствами ffmpeg чувствительно к качеству оборудования, надёжности питания, сетевому соединению и даже производительности файловой системы сервера (но это не точно), особенно при адаптивных алгоритмах сжатия. Ffmpeg имеет тенденцию портить ключевой кадр сегмента. Визуально это проявляется в виде цветных пятен на нижней части изображения или его пикселизации. В равной степени относится к MP4, HLS и DASH. Исправляется принудительным переключением на TCP командой ffmpeg -rtsp_transport tcp -i rtsp://. для камер, поддерживающих этот режим.
Ну вот, теперь, кажется, предупредил обо всём. Если что-то забыл или в чём-то ошибся, прошу высказываться в комментариях. Конструктивная критика, замечания, пожелания и предложения, как всегда, приветствуются!
UPD: дублирую ссылку на github здесь, чтобы не искать по тексту.