Протокол DVR-IP, NetSurveillance, Sofia
Подключаемый модуль NETSurveillance ActiveX использует протокол на основе TCP, называемый просто "Digital Video Recorder Interface Protocol" by the "Hangzhou male Mai Information Co" (то есть «Протокол интерфейса цифрового видеорегистратора» от «Hangzhou male Mai Information Co»).
Существует очень мало поддерживающего его программного обеспечения или документации, кроме инструментов, предоставляемых производителями этих камер, что делает многие параметры конфигурации недоступными.
Коды команд и ответов можно найти здесь: https://gist.github.com/ekwoodrich/a6d7b8db8f82adf107c3c366e61fd36f
Подключение к этому протоколу выполняется на портах TCP 34567 и UDP 34568.
Пример программы, использующей этот протокол — CMS. Смотрите также статью «Установка и настройка программы CMS для IP камер».
python-dvr
python-dvr — это библиотека Python для настройки широкого спектра IP-камер, использующих подключаемый модуль NETsurveillance ActiveX XMeye SDK
DeviceManager.py
DeviceManager.py — это автономная программа Tkinter и консольного интерфейса, как и оригинальный DeviceManager.exe, она может работать на обеих системах — если нет TK — она запускается с консольным интерфейсом.
Программа DeviceManager (из python-dvr) умеет работать со следующими группами камер наблюдения:
- XM
- Dahua
- Fros
- Wans
- Beward
Скорее всего, это не производитель, а тип используемой системы обнаружения камер в LAN. То есть если у вашей камеры другой производитель, DeviceManager всё равно может их найти.
Для установки и запуска DeviceManager выполните команды:
git clone https://github.com/NeiroNx/python-dvr cd python-dvr ./DeviceManager.py
Откроется графический интерфейс, там достаточно нажать кнопку «Поиск».
Как подключиться к DVR-IP, NetSurveillance, Sofia в командной строке
Для подключения в командной строке, можно использовать интерактивную сессию Python или создать небольшой скрипт.
В папке python-dvr создайте файл camera.py. Для подключения используется следующий код:
from dvrip import DVRIPCam from time import sleep host_ip = '192.168.0.167' cam = DVRIPCam(host_ip, user='admin', password='ПАРОЛЬ') if cam.login(): print("Success! Connected to " + host_ip) else: print("Failure. Could not connect.")
Замените 192.168.0.167 на IP вашей камеры, а ПАРОЛЬ на настоящий пароль от неё.
К примеру, этот код покажет время на камере:
from dvrip import DVRIPCam from time import sleep host_ip = '192.168.0.167' cam = DVRIPCam(host_ip, user='admin', password='ПАРОЛЬ') if cam.login(): print("Success! Connected to " + host_ip) else: print("Failure. Could not connect.") print("Время камеры:", cam.get_time())
Запускать так:
python3 camera.py
Понятно, что строки кода для подключения будут повторяться в каждом скрипте, поэтому не будем их дублировать — просто помните, что они должны быть перед функцией, которую вы выбрали:
Базовое использование
Перезагрузка камеры:
cam.reboot()
Ожидание, когда камера запустится:
sleep(60)
Войти снова
cam.login()
Синхронизировать время камеры с временем ПК:
cam.set_time()
Отключиться:
cam.close()
Отображение специального текста OSD
info = cam.get_info("fVideo.OSDInfo") info["OSDInfo"][0]["Info"] = ["Test:","Temp: 26 C","Hum: 21 %"] # 3 строки текста info["OSDInfo"][0]["OSDInfoWidget"]["EncodeBlend"] = True info["OSDInfo"][0]["OSDInfoWidget"]["PreviewBlend"] = True info["OSDInfo"][0]["OSDInfoWidget"]["BackColor"]= '0x80000000' info["OSDInfo"][0]["OSDInfoWidget"]["FrontColor"]= '0xF0FFFF00' info["OSDInfo"][0]["OSDInfoWidget"]["RelativePos"] = [6144,6144,8192,8192] # позиция блока OSD cam.set_info("fVideo.OSDInfo", info)
Настройки камеры
Код
params = cam.get_general_info()
возвращает общую информацию о камере (часовые пояса, форматы, политика автоматической перезагрузки, параметры безопасности):
{ "AppBindFlag": { "BeBinded": false }, "AutoMaintain": { "AutoDeleteFilesDays": 0, "AutoRebootDay": "Tuesday", "AutoRebootHour": 3 }, "DSTState": { "InNormalState": true }, "General": { "AutoLogout": 0, "FontSize": 24, "IranCalendarEnable": 0, "LocalNo": 0, "MachineName": "LocalHost", "OverWrite": "OverWrite", "ScreenAutoShutdown": 10, "ScreenSaveTime": 0, "VideoOutPut": "Auto" }, "Location": { "DSTEnd": { "Day": 1, "Hour": 1, "Minute": 1, "Month": 10, "Week": 0, "Year": 2021 }, "DSTRule": "Off", "DSTStart": { "Day": 1, "Hour": 1, "Minute": 1, "Month": 5, "Week": 0, "Year": 2021 }, "DateFormat": "YYMMDD", "DateSeparator": "-", "IranCalendar": 0, "Language": "Russian", "TimeFormat": "24", "VideoFormat": "PAL", "Week": null, "WorkDay": 62 }, "OneKeyMaskVideo": null, "PwdSafety": { "PwdReset": [ { "QuestionAnswer": "", "QuestionIndex": 0 }, { "QuestionAnswer": "", "QuestionIndex": 0 }, { "QuestionAnswer": "", "QuestionIndex": 0 }, { "QuestionAnswer": "", "QuestionIndex": 0 } ], "SecurityEmail": "", "TipPageHide": false }, "ResumePtzState": null, "TimingSleep": null }
А этот код:
params = cam.get_system_info()
возвращает настройки оборудования, серийный номер камеры, текущую версию программного обеспечения и тип прошивки:
{ "AlarmInChannel": 2, "AlarmOutChannel": 1, "AudioInChannel": 1, "BuildTime": "2020-01-08 11:05:18", "CombineSwitch": 0, "DeviceModel": "HI3516EV300_85H50AI", "DeviceRunTime": "0x0001f532", "DigChannel": 0, "EncryptVersion": "Unknown", "ExtraChannel": 0, "HardWare": "HI3516EV300_85H50AI", "HardWareVersion": "Unknown", "SerialNo": "a166379674a3b447", "SoftWareVersion": "V5.00.R02.000529B2.10010.040600.0020000", "TalkInChannel": 1, "TalkOutChannel": 1, "UpdataTime": "", "UpdataType": "0x00000000", "VideoInChannel": 1, "VideoOutChannel": 1 }
Эта функция:
params = cam.get_system_capabilities()
возвращает возможности программного обеспечения камеры (сигналы тревоги и обнаружения, протоколы связи и особенности оборудования):
{ "AlarmFunction": { "AlarmConfig": true, "BlindDetect": true, "HumanDection": true, "HumanPedDetection": true, "LossDetect": true, "MotionDetect": true, "NetAbort": true, "NetAlarm": true, "NetIpConflict": true, "NewVideoAnalyze": false, "PEAInHumanPed": true, "StorageFailure": true, "StorageLowSpace": true, "StorageNotExist": true, "VideoAnalyze": false }, "CommFunction": { "CommRS232": true, "CommRS485": true }, "EncodeFunction": { "DoubleStream": true, "SmartH264": true, "SmartH264V2": false, "SnapStream": true }, "NetServerFunction": { "IPAdaptive": true, "Net3G": false, "Net4GSignalLevel": false, "NetAlarmCenter": true, "NetDAS": false, "NetDDNS": false, "NetDHCP": true, "NetDNS": true, "NetEmail": true, "NetFTP": true, "NetIPFilter": true, "NetMutlicast": false, "NetNTP": true, "NetNat": true, "NetPMS": true, "NetPMSV2": true, "NetPPPoE": false, "NetRTSP": true, "NetSPVMN": false, "NetUPNP": true, "NetWifi": false, "OnvifPwdCheckout": true, "RTMP": false, "WifiModeSwitch": false, "WifiRouteSignalLevel": true }, "OtherFunction": { "NOHDDRECORD": false, "NoSupportSafetyQuestion": false, "NotSupportAutoAndIntelligent": false, "SupportAdminContactInfo": true, "SupportAlarmRemoteCall": false, "SupportAlarmVoiceTipInterval": true, "SupportAlarmVoiceTips": true, "SupportAlarmVoiceTipsType": true, "SupportAppBindFlag": true, "SupportBT": true, "SupportBallTelescopic": false, "SupportBoxCameraBulb": false, "SupportCamareStyle": true, "SupportCameraWhiteLight": false, "SupportCfgCloudupgrade": true, "SupportChangeLanguageNoReboot": true, "SupportCloseVoiceTip": false, "SupportCloudUpgrade": true, "SupportCommDataUpload": true, "SupportCorridorMode": false, "SupportCustomizeLpRect": false, "SupportDNChangeByImage": false, "SupportDimenCode": true, "SupportDoubleLightBoxCamera": false, "SupportDoubleLightBulb": false, "SupportElectronicPTZ": false, "SupportFTPTest": true, "SupportFaceDetectV2": false, "SupportFaceRecognition": false, "SupportMailTest": true, "SupportMusicBulb433Pair": false, "SupportMusicLightBulb": false, "SupportNetWorkMode": false, "SupportOSDInfo": false, "SupportOneKeyMaskVideo": false, "SupportPCSetDoubleLight": true, "SupportPTZDirectionControl": false, "SupportPTZTour": false, "SupportPWDSafety": true, "SupportParkingGuide": false, "SupportPtz360Spin": false, "SupportRPSVideo": false, "SupportSetBrightness": false, "SupportSetDetectTrackWatchPoint": false, "SupportSetHardwareAbility": false, "SupportSetPTZPresetAttribute": false, "SupportSetVolume": true, "SupportShowH265X": true, "SupportSnapCfg": false, "SupportSnapV2Stream": true, "SupportSnapshotConfigV2": false, "SupportSoftPhotosensitive": true, "SupportStatusLed": false, "SupportTextPassword": true, "SupportTimeZone": true, "SupportTimingSleep": false, "SupportWebRTCModule": false, "SupportWriteLog": true, "SuppportChangeOnvifPort": true }, "PreviewFunction": { "Talk": true, "Tour": false }, "TipShow": { "NoBeepTipShow": true } }
Настройки/режимы видео камеры
params = cam.get_info("Camera")
Вернёт примерно следующие данные:
{'ClearFog': [{'enable': 0, 'level': 50}], 'DistortionCorrect': {'Lenstype': 0, 'Version': 0}, 'FishLensParam': [{'CenterOffsetX': 300, 'CenterOffsetY': 300, 'ImageHeight': 720, 'ImageWidth': 1280, 'LensType': 0, 'PCMac': '000000000000', 'Radius': 300, 'Version': 1, 'ViewAngle': 0, 'ViewMode': 0, 'Zoom': 100}], 'FishViCut': [{'ImgHeight': 0, 'ImgWidth': 0, 'Xoffset': 0, 'Yoffset': 0}], 'Param': [{'AeSensitivity': 5, 'ApertureMode': '0x00000000', 'BLCMode': '0x00000000', 'DayNightColor': '0x00000000', 'Day_nfLevel': 3, 'DncThr': 30, 'ElecLevel': 50, 'EsShutter': '0x00000002', 'ExposureParam': {'LeastTime': '0x00000100', 'Level': 0, 'MostTime': '0x00010000'}, 'GainParam': {'AutoGain': 1, 'Gain': 50}, 'IRCUTMode': 0, 'IrcutSwap': 0, 'Night_nfLevel': 3, 'PictureFlip': '0x00000000', 'PictureMirror': '0x00000000', 'RejectFlicker': '0x00000000', 'WhiteBalance': '0x00000000'}], 'ParamEx': [{'AutomaticAdjustment': 3, 'BroadTrends': {'AutoGain': 0, 'Gain': 50}, 'CorridorMode': 0, 'ExposureTime': '0x100', 'LightRestrainLevel': 16, 'LowLuxMode': 0, 'PreventOverExpo': 0, 'SoftPhotosensitivecontrol': 0, 'Style': 'type1'}], 'WhiteLight': {'MoveTrigLight': {'Duration': 60, 'Level': 3}, 'WorkMode': 'Auto', 'WorkPeriod': {'EHour': 6, 'EMinute': 0, 'Enable': 1, 'SHour': 18, 'SMinute': 0}}}
Чтобы получить настройки текущего кодирования
enc_info = cam.get_info("Simplify.Encode")
Вернёт примерно следующие данные:
[{'ExtraFormat': {'AudioEnable': False, 'Video': {'BitRate': 552, 'BitRateControl': 'VBR', 'Compression': 'H.265', 'FPS': 20, 'GOP': 2, 'Quality': 3, 'Resolution': 'D1'}, 'VideoEnable': True}, 'MainFormat': {'AudioEnable': False, 'Video': {'BitRate': 2662, 'BitRateControl': 'VBR', 'Compression': 'H.265', 'FPS': 25, 'GOP': 2, 'Quality': 4, 'Resolution': '1080P'}, 'VideoEnable': True}}]
Изменение битрейта
NewBitrate = 7000 enc_info[0]['MainFormat']['Video']['BitRate'] = NewBitrate cam.set_info("Simplify.Encode", enc_info)
Получение параметров цвета видеоканала
colors = cam.get_info("AVEnc.VideoColor.[0]")
Вернёт примерно следующие данные:
[{'Enable': True, 'TimeSection': '0 00:00:00-24:00:00', 'VideoColorParam': {'Acutance': 3848, 'Brightness': 50, 'Contrast': 50, 'Gain': 0, 'Hue': 50, 'Saturation': 50, 'Whitebalance': 128}}, {'Enable': False, 'TimeSection': '0 00:00:00-24:00:00', 'VideoColorParam': {'Acutance': 3848, 'Brightness': 50, 'Contrast': 50, 'Gain': 0, 'Hue': 50, 'Saturation': 50, 'Whitebalance': 128}}]
Изменить ИК cut
cam.set_info("Camera.Param.[0]", { "IrcutSwap" : 0 })
Изменить настройки WDR
WDR_mode = True cam.set_info("Camera.ParamEx.[0]", { "BroadTrends" : { "AutoGain" : int(WDR_mode) } })
Получение сетевых настроек
net = cam.get_info("NetWork.NetCommon")
Включение адаптивного IP режима
cam.set_info("NetWork.IPAdaptive", { "IPAdaptive": True })
Установить имя хоста камеры
cam.set_info("NetWork.NetCommon.HostName", "IVG-85HG50PYA-S")
Выбор DHCP режима (в данном примере включается)
dhcpst = cam.get_info("NetWork.NetDHCP") dhcpst[0]['Enable'] = True cam.set_info("NetWork.NetDHCP", dhcpst)
Добавление пользователя и Изменение пароля
Пользователь "test2" с паролем "123123"
cam.addUser("test2","123123")
Смена пароля
cam.changePasswd("321321",cam.sofia_hash("123123"),"test2")
Удаление пользователя "test2"
if cam.delUser("test2"): print("User deleted") else: print("Can not delete it")
Системного пользователя нельзя удалить
if cam.delUser("admin"): print("You do it! How?") else: print("It system reserved user")
Получение снимка JPEG
with open("snap.jpg", "wb") as f: f.write(cam.snapshot())
Получение аудио/видео потока
Только видео записывается в файл (с использованием простой lambda):
with open("datastream.h265", "wb") as f: cam.start_monitor(lambda frame, meta, user: f.write(frame))
Запись потока данных с дополнительной фильтрацией (захват первых 100 кадров):
class State: def __init__(self): self.counter = 0 def count(self): return self.counter def inc(self): self.counter += 1 with open("datastream.h265", "wb") as f: state = State() def receiver(frame, meta, state): if 'frame' in meta: f.write(frame) state.inc() print(state.count()) if state.count() == 100: cam.stop_monitor() cam.start_monitor(receiver, state)
Настройка заголовка камеры
Простой способ изменить заголовок картинки:
cam.channel_title(["Backyard"])
Использовать шрифт Unicode с главного компьютера для создания растрового изображения для заголовка из PIL import Image, ImageDraw, ImageFont
w_disp = 128 h_disp = 64 fontsize = 32 text = "Туалет" imageRGB = Image.new('RGB', (w_disp, h_disp)) draw = ImageDraw.Draw(imageRGB) font = ImageFont.truetype("/Library/Fonts/Arial Unicode.ttf", fontsize) w, h = draw.textsize(text, font=font) draw.text(((w_disp - w)/2, (h_disp - h)/2), text, font=font) image1bit = imageRGB.convert("1") data = image1bit.tobytes() cam.channel_bitmap(w_disp, h_disp, data)
Использовать свой собственный логотип на картинке
img = Image.open('vixand.png') width, height = img.size data = img.convert("1").tobytes() cam.channel_bitmap(width, height, data)
Показать текущую температуру, скорость, координаты GPS и т. д.
Используйте тот же метод, чтобы нарисовать текст в растровое изображение и передать его на камеру, но рассмотрите возможность размещения внутреннего хранилища растровых изображений в ОЗУ:
mount -t tmpfs -o size=100k tmpfs /mnt/mtd/tmpfs ln -sf /mnt/mtd/tmpfs/0.dot /mnt/mtd/Config/Dot/0.dot
Обновление прошивки камеры
Необязательно: получить информацию о параметрах обновления
print(cam.get_upgrade_info())
Выполнение обновления
cam.upgrade("General_HZXM_IPC_HI3516CV300_50H20L_AE_S38_V4.03.R12.Nat.OnvifS.HIK.20181126_ALL.bin")
Связанные статьи:
- Инструкция по openRTSP — клиент RTSP для приёма и записи потокового медиа (100%)
- Как записать видео с IP камеры (RTSP поток) (100%)
- Как получить доступ к веб камере в HTML (57.2%)
- Как одновременно захватывать экран и видео с веб камеры в Linux и Windows (57.2%)
- Программы чтобы снимать видео и фотографии с веб камеры в Linux (57.2%)
- Как уменьшить размер фотографий. Массовое сжатие фотографий в командной строке (RANDOM - 50%)
Спасибо за статью, полезно
От себя еще хочу добавить очень хороший проект — https://openipc.org
Я включил OSD меню, а как его отключить???
Что такое OSD меню и где вы его включили? Предположу, где включили — там и же и отключите.
По cloud id никак нельзя подключаться к камере?