Как использовать python для управление видеорегистратором
Скачай курс
в приложении
Перейти в приложение
Открыть мобильную версию сайта
© 2013 — 2023. Stepik
Наши условия использования и конфиденциальности
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 подразделяется на несколько профилей:
- S — профиль IP камер, кодировщиков, других IP видео устройств (потоковое аудио и видео, управление параметрами потока, изображения и вещания);
- C — профиль систем контроля доступа основанных на IP (сигнализация, блокировка, разблокировка дверей и т.п.);
- Q — профиль упрощенного механизма настройки и расширенной безопасности (настройка устройств, обновление, NTP, SSL, мониторинг)
- G — профиль сетевых видеорегистраторов (NVR), систем управления зданиями и PSIM (управление и контроль записи, передача аудио и мета-информации);
Устройство поддерживающее ONVIF может поддерживать несколько профилей. Например камера с функцией записи может поддерживать профили S и G.
По предоставляемые протоколом ONVIF службы (более подробно можно ознакомиться на официальном сайте), также привожу характерные url служб для устройств с которыми я работаю:
- Access Control
- Action Engine
- Advanced Security
- Analytics http://onvif_host/onvif/Analytics
- Device IO http://onvif_host/onvif/DeviceIO
- Display
- Door Control
- Imaging http://onvif_host/onvif/Imaging
- Media http://onvif_host/onvif/Media
- PTZ (Pan, tilt, zoom — панорамирование, наклон, масштабирование)
- Receiver
- Recording Control
- Recording Search
- Replay Control
- Video Analytics Device
- 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], это обычная ситуация админ должен уметь все и сразу.
Информацией в данной статьей я хочу поделиться в виду того, что потребовалось не мало времени для поиска решения задачи и написания небольшого скрипта. Если у кого будут предложения по иной реализации задач, буду рад ознакомиться.
Задача
- Организовать вывод видеонаблюдения с разных точек объекта на монитор в штабе, для постоянного контроля происходящего.(Строительная компания, на каждом объекте имеется штаб для ИТР состава.)
- Организовать видео-стену в офисе для контроля работы на объектах.
В данной статье не буду рассматривать способы обеспечения соединения с объектами, у нас поднят VPN на firewall zyxel, есть иной способ — пробросить порты, но понадобятся белые IP на всех объектах что очень накладно и настройка firewall для доступа с определенных адресов. По этому рекомендую настроить VPN в сети много мануалов.
Часть 1. Подготовка
Вывести изображение с видеорегистраторов можно несколькими способами:
- через приложения для смартфонов;
- На прямую видео кабелем (HDMI, VGA)
- софт для ПК;
- Браузер. (web-морда)
Мы будем рассматривать 4 вариант.
Вопрос остается в том как организовать автологин и прочие манипуляции в браузере, дабы не давать всем сотрудникам пароль, и не напрягать лишней работой, включил ПК и все работает.
У меня на момент выполнения задачи были базовые знания Python, С++ учил когда-то давно в универе. Выбор пал на Python так как системы с которых открывается вся история на Windows, С++ сложнее по синтаксису и давно не работал с ним, рассматривать реализацию на нем даже не стал.
В Python есть библиотека Selenium, позволяющая работать c браузерами, к сожалению Web-морды наших регистраторов корректно работают только в IE. И Selenium-у потребуется Web-driver, скачать можно с сайта библиотеки.
Ссылка на web-driver
Часть 2. Написание
Для удобства разработки использовал VS Code. (установку и настройку не буду рассматривать, информации в сети много)
- Создать окружение для разработки, для этого в оболочке PS следует ввести:
python -m venv hiwatch cd hiwatch\Scripts .\activate.ps1
Мы создаем окружение, переходим в папку Scripts и активируем его.
- Создаем файл .py и устанавливаем Selenium.
cd .. #переходим в каталог выше hiwatch\ touch video.py #создаем файл питона pip3 install selenium #устанавливаем Selenium
так же качаем файл IE webdriver с сайта selenium (ссылка выше) и закидываем в папку hiwatch.
- Ниже будет предоставлен код из файла 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
- Ниже код из файла 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
- Перегоняем программу из .PY в .EXE для запуска на разных хостах без установки Python и прочего, получим самостоятельную программу.
pyinstaller --noconfirm --onedir --console --add-data "C:/Users/!Ваш путь к этой папке!/IEDriverServer.exe;." "C:/Users/!Ваш путь к этой папке!/video.py"
- Сборка содержится в папке dist, которая находится в одной директории с папкой hiwatch.
Часть 3. Заключение
Вам остается только перенести результат из папки dist на любую машину.
В заключении я хотел бы сказать что не являюсь разработчиком, и мог не совсем правильно описать некоторые действия — прошу не судить строго.