Как использовать python для управление видеорегистратором
Перейти к содержимому

Как использовать python для управление видеорегистратором

  • автор:

Как использовать python для управление видеорегистратором

Скачай курс
в приложении

Перейти в приложение
Открыть мобильную версию сайта

© 2013 — 2023. Stepik

Наши условия использования и конфиденциальности

Get it on Google Play

Public user contributions licensed under cc-wiki license with attribution required

Подключаемся к камерам по onvif

Что такое ONVIF (Open Network Video Interface Forum)

ONVIF — это стандарт сферы видеонаблюдения, содержащий протоколы взаимодействия IP камер, IP серверов (кодировщиков), регистрасторов, основанный на POST XML запросах.

В данной статье я буду придерживаться следующей терминологии:

  • Service — служба (Например: device management service — служба управления устройством);
  • PSIM (Physical security information management system) — автоматизированный охранный программный комплекс;

По типу устройств ONVIF подразделяется на несколько профилей:

  1. S — профиль IP камер, кодировщиков, других IP видео устройств (потоковое аудио и видео, управление параметрами потока, изображения и вещания);
  2. C — профиль систем контроля доступа основанных на IP (сигнализация, блокировка, разблокировка дверей и т.п.);
  3. Q — профиль упрощенного механизма настройки и расширенной безопасности (настройка устройств, обновление, NTP, SSL, мониторинг)
  4. G — профиль сетевых видеорегистраторов (NVR), систем управления зданиями и PSIM (управление и контроль записи, передача аудио и мета-информации);

Устройство поддерживающее ONVIF может поддерживать несколько профилей. Например камера с функцией записи может поддерживать профили S и G.

По предоставляемые протоколом ONVIF службы (более подробно можно ознакомиться на официальном сайте), также привожу характерные url служб для устройств с которыми я работаю:

  1. Access Control
  2. Action Engine
  3. Advanced Security
  4. Analytics http://onvif_host/onvif/Analytics
  5. Device IO http://onvif_host/onvif/DeviceIO
  6. Display
  7. Door Control
  8. Imaging http://onvif_host/onvif/Imaging
  9. Media http://onvif_host/onvif/Media
  10. PTZ (Pan, tilt, zoom — панорамирование, наклон, масштабирование)
  11. Receiver
  12. Recording Control
  13. Recording Search
  14. Replay Control
  15. Video Analytics Device
  16. Events http://onvif_host/onvif/Events

Любое устройство поддерживающее ONVIF поддерживает функции ядра, а дальше есть различия по назначению, например у регистратора нет поддержки PTZ и Door Control.

Поддержка сервисов по типам устройств:

  • NVD (Network video display) — устройства получающее видео изображение по сети и отображающее ее (Core, Streaming, Receiver, Display, Device IO);
  • NVT (Network video transmitter) — IP камера или кодировщик (Core, Media, Streaming, Device IO, Imaging, PTZ, Analytics);
  • NVA (Network video analytics) — устройство поддерживающее обработку информации, аналитику и передачу meta информации (Core, Streaming, Receiver, Analytics, Video Analytics Device, Device IO);
  • NVS (Network video storage) — устройства записи с NVT, как правило с поддержкой профиль G (Core, Streaming, Recording Search, Replay Control, Device IO, Receiver, Recording Control);

Полезные ссылки

Полная документация по ONVIF 2.5 на официальном сайте onvif

Спецификация ядра ONVIF на официальном сайте onvif

Полезная программа для изучения протокола — onvif device manager

Самый лучший кроссплатформенный сниффер — wireshark

Список всех функций onvif — список всех функций

Суть протокола

Протокол onvif относится к протоколам RPC с удалённым вызовом процедур на базе web-сервиса. В основе лежит WSDL — XML описание веб-сервиса. Обмен сообщениями также происходит с помощью XML сообщений (SOAP пакетов), последовательностями XML запрос-ответ.

Точка входа

Спецификация ядра onvif в разделе 5 (описание веб-сервисов) определяет единую точку входа для всех устройств для службы управления устройством:

http://onvif_host/onvif/device_service 

Для работы с камерами по протоколу onvif в языке python существует python-onvif.

Установим библиотеку onvif

$ pwd /onvif_cameras/ $ virtualenv -ppython2.7 env $ source env/bin/activate (env)$ pip install onvif 

Находимся в директории /onvif_cameras/ Виртуальное окружение /onvif_cameras/env/ Важно! Путь к виртуальному окружению необходим поскольку при установке onvif скачивается пространства имен, схемы данных в папку wsdl

/onvif_cameras/env/wsdl$ ls accesscontrol.wsdl deviceio.wsdl onvif.xsd t-1.xsd actionengine.wsdl devicemgmt.wsdl ptz.wsdl types.xsd addressing display.wsdl r-2.xsd ws-addr.xsd advancedsecurity.wsdl doorcontrol.wsdl receiver.wsdl ws-discovery.xsd analyticsdevice.wsdl envelope recording.wsdl xmlmime analytics.wsdl events.wsdl remotediscovery.wsdl xml.xsd b-2.xsd imaging.wsdl replay.wsdl bf-2.xsd include rw-2.wsdl bw-2.wsdl media.wsdl search.wsdl 

Hikvision DS-2CD8153F-E (Onvif 2.02)

  • Подключимся к камере
  • Определим сервис
  • Получим информацию об устройстве
  • Посмотрим и установим системное время
  • Перезагрузим камеру
from onvif import ONVIFCamera, ONVIFService, ONVIFError camera = ONVIFCamera('192.168.0.112', 80, u'admin', u'password', u'/onvif_cameras/env/wsdl/') response = camera.devicemgmt.GetDeviceInformation() response (reply) Manufacturer = "HIKVISION" Model = "DS-2CD8153F-E" FirmwareVersion = "V4.0.1 build 120508" SerialNumber = "DS-2CD8153F-E0120120914BBRR411180126" HardwareId = "88" > 

Посмотрим все сервисы

response = camera.devicemgmt.GetServices('IncludeCapability': True>) [(Service) Namespace = "http://www.onvif.org/ver10/device/wsdl" XAddr = "http://192.168.0.112/onvif/device_service" Version = (OnvifVersion) Major = 1 Minor = 3 > >, (Service) Namespace = "http://www.onvif.org/ver10/media/wsdl" XAddr = "http://192.168.0.112/onvif/Media" Version = (OnvifVersion) Major = 1 Minor = 3 > >, (Service) Namespace = "http://www.onvif.org/ver10/events/wsdl" XAddr = "http://192.168.0.112/onvif/Events" Version = (OnvifVersion) Major = 1 Minor = 4 > >, (Service) Namespace = "http://www.onvif.org/ver20/ptz/wsdl" XAddr = "http://192.168.0.112/onvif/PTZ" Version = (OnvifVersion) Major = 2 Minor = 1 > >, (Service) Namespace = "http://www.onvif.org/ver20/imaging/wsdl" XAddr = "http://192.168.0.112/onvif/Imaging" Version = (OnvifVersion) Major = 2 Minor = 1 > >, (Service) Namespace = "http://www.onvif.org/ver10/deviceIO/wsdl" XAddr = "http://192.168.0.112/onvif/DeviceIO" Version = (OnvifVersion) Major = 1 Minor = 1 > >] 

Так же можно определить отдельный сервис, что гораздо быстрее и посмотреть все сервисы аналогично

management_service = ONVIFService('http://192.168.0.112/onvif/media', u'admin', u'password', '/onvif_cameras/env/wsdl/devicemgmt.wsdl') services = management_service.GetServices('IncludeCapability': True>) 

Посмотрим системное время на камере

response = camera.devicemgmt.GetSystemDateAndTime() response (SystemDateTime) DateTimeType = "NTP" DaylightSavings = False TimeZone = (TimeZone) TZ = "CST-8:00:00" > UTCDateTime = (DateTime) Time = (Time) Hour = 8 Minute = 26 Second = 23 > Date = (Date) Year = 2015 Month = 1 Day = 10 > > LocalDateTime = (DateTime) Time = (Time) Hour = 12 Minute = 26 Second = 23 > Date = (Date) Year = 2015 Month = 1 Day = 10 > > > 

Установим время через словарь dict или через определение объекта времени. Второй вариант при установке времени если будет задан неверный аттрибут вызовет ошибку, что очень удобно.

import datetime time_dict =  'UTCDateTime': datetime.datetime.now() > camera.devicemgmt.SetSystemDateAndTime(time_dict) 

или определим объект времени

time_object = camera.devicemgmt.create_type('SetSystemDateAndTime') time_object.DateTimeType = 'Manual' time_object.DaylightSavings = True time_object.TimeZone = 'CST-8:00:00' time_object.UTCDateTime.Date.Year = 2015 time_object.UTCDateTime.Date.Month = 1 time_object.UTCDateTime.Date.Day = 10 time_object.UTCDateTime.Time.Hour = 12 time_object.UTCDateTime.Time.Minute = 26 time_object.UTCDateTime.Time.Second = 0 camera.devicemgmt.SetSystemDateAndTime(time_object) 
response = camera.devicemgmt.SystemReboot() 

Для написания скриптов на bash очень не плохо подходит ONVIF CLI

$ onvif-cli devicemgmt GetHostname --user 'admin' --password 'password' --host '192.168.0.112' --port 80 True: 'FromDHCP': True, 'Name': hision> 

Python скрипт для загрузки файлов из архива камер и регистраторов.

Написал тут python скриптик для синхронизации видоархива камер dahua и облака mega.nz. Он позволяет скачать dav файлы за заданный период с камеры и тут же заливает их в облако.
Собственно прошу не придраться к самой теме, ибо по пути у меня еще предусмотрена обработка этих файлов при помощи компьютерного зрения, потому прямая заливка на ftp или nas не интересна. Да и вообще, все же захотелось свой метод выдергивания файлов из камер с SD картами/регистратора. Тот же RemotePlayBackTool подзадолбал своим ограничением в 100 файлов, когда пришлось вытягивать видео за неделю с достаточно проходной камеры. Да и , внезапно, не работает он с одиночными камерами. Хотя API тот же.
Для себя изучив API dahua, написал вот такой скриптик (во вложении). Он умеет подключаться к камере, вытягивать Dav файлы за интервал времени без ограничения по количеству, и заливать их на удаленный сервер.
При подключении к одиночной камере с SD картой все работает без проблем.

Спойлер: вывод

Login OK! Total: 53687091200.0 Used: 35095520.0 Free: 53651995680.0
Trying to login 192.168.0.110
Login success! Got token: 64538280
Trying to find files in interval: 2020-8-16 01:30:00 — 2020-8-16 01:40:00
Find files success! Got response: OK
Got file record: /mnt/sd/2020-08-16/001/dav/01/01.29.18-01.30.17[M][0@0][0].dav length: 26052907
Got file record: /mnt/sd/2020-08-16/001/dav/01/01.30.19-01.32.56[M][0@0][0].dav length: 72192180
Got file record: /mnt/sd/2020-08-16/001/dav/01/01.33.20-01.39.18[M][0@0][0].dav length: 143003371
File c:\temp\01.29.18-01.30.17[M][0@0][0].dav exists, skipping!
File: 192.168.0.120_4_20200614131500-20200614131908.dav Size: 35095520 Date: 2020-08-16 22:10:23 [0 days]
UPLOADING . c:\temp\01.29.18-01.30.17[M][0@0][0].dav
100%|██████████| 26.1M/26.1M [01:34 Downloading 2 of 3 to c:\temp\01.30.19-01.32.56[M][0@0][0].dav
100%|██████████| 72.2M/72.2M [00:09 File: 192.168.0.120_4_20200614131500-20200614131908.dav Size: 35095520 Date: 2020-08-16 22:10:23 [0 days]
File: 01.29.18-01.30.17[M][0@0][0].dav Size: 26052907 Date: 2020-08-16 23:35:04 [0 days]
UPLOADING . c:\temp\01.30.19-01.32.56[M][0@0][0].dav
100%|██████████| 72.2M/72.2M [05:09 Downloading 3 of 3 to c:\temp\01.33.20-01.39.18[M][0@0][0].dav
100%|██████████| 143M/143M [00:18 File: 192.168.0.120_4_20200614131500-20200614131908.dav Size: 35095520 Date: 2020-08-16 22:10:23 [0 days]
File: 01.29.18-01.30.17[M][0@0][0].dav Size: 26052907 Date: 2020-08-16 23:35:04 [0 days]
File: 01.30.19-01.32.56[M][0@0][0].dav Size: 72192180 Date: 2020-08-16 23:40:26 [0 days]
UPLOADING . c:\temp\01.33.20-01.39.18[M][0@0][0].dav
14%|█ | 20.4M/143M [01:29

Однако при попытке скачать файл с регистратора (DHI-NVR2108-4KS2 V4.000.0000001.5 ), постоянно получаю ошибку авторизации. Т.е. процесс подключения проходит штатно, список файлов отдается верно, но вот скачка dav файла обламывается с ошибкой авторизации.

Ссылка на скачку выглядит вот так:
http://192.168.0.120/cgi-bin/RPC_Loadfile/mnt/dvr/2020-06-22/003/dav/08/0/0/183965/08.31.03-08.31.54[M][0@0][0].dav
авторизация digest (хотя пробовал и basic)
Размер файла в заголовке запроса отдается, а вот скачка не идет.

Спойлер: api dahua выглядит так:

URL Syntax http:///cgi-bin/RPC_Loadfile/ For example: http://10.61.5.117/cgi-bin/RPC_Loadfile/2012_09_15_12_37_05:2012_09_15_18_34_14[0][0].dav

При подключении к одиночной камере все работает, а к регистратору не хочет. Через браузер также не получается скачать файл по ссылке. Та же ошибка авторизации. Там в новой версии что-то поменяли с безопаской? Пробовал включать compatible mode безопасности — тот же эффект.

P.S. кстати , а может ли кто поделиться свежим dahua API ? Хотя бы 2.7

Автоматизация видеонаблюдения

Всем привет! Я работаю не в IT компании системным администратором. В перечень обязанностей входит и администрирование систем видеонаблюдения [мы используем CTV и HiWatch], это обычная ситуация админ должен уметь все и сразу.

Информацией в данной статьей я хочу поделиться в виду того, что потребовалось не мало времени для поиска решения задачи и написания небольшого скрипта. Если у кого будут предложения по иной реализации задач, буду рад ознакомиться.

Задача

  1. Организовать вывод видеонаблюдения с разных точек объекта на монитор в штабе, для постоянного контроля происходящего.(Строительная компания, на каждом объекте имеется штаб для ИТР состава.)
  2. Организовать видео-стену в офисе для контроля работы на объектах.

В данной статье не буду рассматривать способы обеспечения соединения с объектами, у нас поднят VPN на firewall zyxel, есть иной способ — пробросить порты, но понадобятся белые IP на всех объектах что очень накладно и настройка firewall для доступа с определенных адресов. По этому рекомендую настроить VPN в сети много мануалов.

Часть 1. Подготовка

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

  1. через приложения для смартфонов;
  2. На прямую видео кабелем (HDMI, VGA)
  3. софт для ПК;
  4. Браузер. (web-морда)

Мы будем рассматривать 4 вариант.

Вопрос остается в том как организовать автологин и прочие манипуляции в браузере, дабы не давать всем сотрудникам пароль, и не напрягать лишней работой, включил ПК и все работает.

У меня на момент выполнения задачи были базовые знания Python, С++ учил когда-то давно в универе. Выбор пал на Python так как системы с которых открывается вся история на Windows, С++ сложнее по синтаксису и давно не работал с ним, рассматривать реализацию на нем даже не стал.

В Python есть библиотека Selenium, позволяющая работать c браузерами, к сожалению Web-морды наших регистраторов корректно работают только в IE. И Selenium-у потребуется Web-driver, скачать можно с сайта библиотеки.

Ссылка на web-driver

Часть 2. Написание

Для удобства разработки использовал VS Code. (установку и настройку не буду рассматривать, информации в сети много)

  1. Создать окружение для разработки, для этого в оболочке PS следует ввести:
python -m venv hiwatch cd hiwatch\Scripts .\activate.ps1

Мы создаем окружение, переходим в папку Scripts и активируем его.

  1. Создаем файл .py и устанавливаем Selenium.
cd .. #переходим в каталог выше hiwatch\ touch video.py #создаем файл питона pip3 install selenium #устанавливаем Selenium

так же качаем файл IE webdriver с сайта selenium (ссылка выше) и закидываем в папку hiwatch.

  1. Ниже будет предоставлен код из файла video.py с пояснением, для регистраторов Hiwatch & Hikvision.
#video.py import time from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By time.sleep(60) #здесь и далее приостановка выполнения в секундах drive = webdriver.Ie(executable_path = r'IEDriverServer.exe') #присваиваем переменной drive исполняемый файл webdriver-a drive.get('http://192.168.*.*/') #IP адрес регистратора может быть указан номер порта time.sleep(15) drive.find_element(By.ID, 'username').send_keys('log') #Ваш логин к регистратору drive.find_element(By.ID, 'password').send_keys("pass") #Ваш пароль к регистратору drive.find_element(By.ID, 'password').send_keys(Keys.ENTER) #Иммитация нажатия Enter для перехода на следущую страницу time.sleep(10) search = drive.find_element(By.CLASS_NAME, 'icon-playall') #выбор кнопки воспроизведения изображения drive.execute_script("arguments[0].click();", search) #иммитация нажатия time.sleep(5) full = drive.find_element(By.CLASS_NAME, 'icon-full') #выбор кнопки изображения на полный экран drive.execute_script("arguments[0].click();", full) #иммитация нажатия drive.close drive.quit
  1. Ниже код из файла video.py для регистратора CTV.
import time from selenium import webdriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By time.sleep(5) #здесь и далее приостановка выполнения в секундах drive = webdriver.Ie(executable_path = r'IEDriverServer.exe') #присваиваем переменной drive исполняемый файл webdriver-a drive.get('http://192.168.*.*/') #IP адрес регистратора может быть указан номер порта time.sleep(10) drive.find_element(By.ID, 'txtUserName').send_keys('login') #Ваш логин к регистратору drive.find_element(By.ID, 'txtPassword').send_keys('Pass') #Пароль к регистратору drive.find_element(By.ID, 'txtPassword').send_keys(Keys.ENTER) #Иммитация нажатия Enter для перехода на следущую страницу time.sleep(10) search1 = drive.find_element(By.ID, 'seg_selector') #открытие вкладки для выбора сетки отображения drive.execute_script("arguments[0].click();", search1) #иммитация нажатия search2 = drive.find_element(By.ID, 'seg_9') #выбор сетки 3*3 drive.execute_script("arguments[0].click();", search2) #иммитация нажатия time.sleep(5) full = drive.find_element(By.ID, 'full_screen') #выбор кнопки изображения на полный экран drive.execute_script("arguments[0].click();", full) #иммитация нажатия drive.close drive.quit 
  1. Перегоняем программу из .PY в .EXE для запуска на разных хостах без установки Python и прочего, получим самостоятельную программу.
pyinstaller --noconfirm --onedir --console --add-data "C:/Users/!Ваш путь к этой папке!/IEDriverServer.exe;." "C:/Users/!Ваш путь к этой папке!/video.py"
  1. Сборка содержится в папке dist, которая находится в одной директории с папкой hiwatch.

Часть 3. Заключение

Вам остается только перенести результат из папки dist на любую машину.

В заключении я хотел бы сказать что не являюсь разработчиком, и мог не совсем правильно описать некоторые действия — прошу не судить строго.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *