前面三篇文章给大家详细讲解了核心的调用过程,以及给出了预览部分的示例代码,大家完全可以举一反三的去增加和扩展更多的海康SDK函数来实现更多的视频监控功能,我在这里就不去干重复的劳动去一一解释SDK了,相信帮助文档会比我带给你们的信息更完整,我将大家带入门即可,任务完成。今天我将我的客户端 ClientDemo 的全部完整代码贴出,你可以直接拷贝去运行,有任何问题,可以在评论区交流,包含3个文件:
hcnetsdk.py
python 与 c++ 结构、函数、变量的转化定义
#Created by marco for conversion structs & parameters from c++ to python. 2020-Aug-06import osfrom ctypes import *from enum import EnumAPP_PATH = os.path.dirname(os.path.abspath(__file__))#It's different from c++, we only need to load library HCNetSDK.dll for Liveview in c++,#The HCPreview.dll will be loaded by program automatically, but this is not happened in python,#We have to load it manually hcnetsdk = cdll.LoadLibrary(APP_PATH + 'HCNetSDK.dll')hcpreview = cdll.LoadLibrary(APP_PATH + 'HCPreview.dll')hcplayback = cdll.LoadLibrary(APP_PATH + 'HCPlayBack.dll')SERIALNO_LEN = 48 #SN lengthclass NET_DVR_DEVICEINFO(Structure): _fields_ = [("sSerialNumber", c_byte * SERIALNO_LEN), #SN ("byAlarmInPortNum", c_byte), #DVR Alarm input ("byAlarmOutPortNum", c_byte), #DVR Alarm Output ("byDiskNum", c_byte), #DVR Number of Hard Disk ("byDVRType", c_byte), #DVR Type, 1: DVR 2: ATM DVR 3: DVS ...... ("byChanNum", c_byte), #DVR Number of Channel ("byStartChan", c_byte) #The first Channel No. E.g. DVS- 1, DVR- 1 ]#Preview via software decodingclass NET_DVR_CLIENTINFO(Structure): _fields_ = [("lChannel", c_long), #channel no. ("lLinkMode", c_long), #If 31st bit is 0, it means connect main stream, is 1 means sub stream. Bit 0~bit 30 are used for link mode: 0: TCP mode, 1: UDP mode, 2: Multi- play mode, 3: RTP mode,4-RTP/RTSP,5-RSTP/HTTP ("hPlayWnd", c_uint32), #the play window's handle; set NULL to disable preview ("sMultiCastIP", c_char_p), #Multicast group ("byProtoType", c_byte), #0-private protocol,1-RTSP protocol ("byRes", c_byte * 3) ]#Image Qualityclass NET_DVR_JPEGPARA(Structure): # 0-CIF, 1-QCIF, 2-D1, 3-UXGA(1600x1200), 4-SVGA(800x600),5-HD720p(1280x720), # 6-VGA, 7-XVGA, 8-HD900p, 9-HD1080, 10-2560*1920, # 11-1600*304, 12-2048*1536, 13-2448*2048, 14-2448*1200, 15-2448*800, # 16-XGA(1024*768), 17-SXGA(1280*1024),18-WD1(960*576/960*480), 19-1080i, 20-576*576, # 21-1536*1536, 22-1920*1920, 23-320*240, 24-720*720, 25-1024*768, # 26-1280*1280, 27-1600*600, 28-2048*768, 29-160*120, 55-3072*2048, # 64-3840*2160, 70-2560*1440, 75-336*256, # 78-384*256, 79-384*216, 80-320*256, 82-320*192, 83-512*384, # 127-480*272, 128-512*272, 161-288*320, 162-144*176, 163-480*640, # 164-240*320, 165-120*160, 166-576*720, 167-720*1280, 168-576*960, # 180-180*240, 181-360*480, 182-540*720, 183-720*960, 184-960*1280, # 185-1080*1440 215-1080*720(occupied untested), 216-360x640(occupied untested), # 245-576*704[P]/480*704[N](occupied untested) # 500-384*288, # 0xff-Auto(Use resolution of current stream) _fields_ = [("wPicSize", c_ushort), ("wPicQuality", c_ushort) # 0 - the best, 1 - better, 2 - average; ]#**********************PTZ Commands begin*************************LIGHT_PWRON = 2 # Switch on light WIPER_PWRON = 3 # Switch on Wiper FAN_PWRON = 4 # Switch on Fan HEATER_PWRON = 5 # Switch on Heater AUX_PWRON1 = 6 # Switch on auxiliary equipment 1AUX_PWRON2 = 7 # Switch on auxiliary equipment 2SET_PRESET = 8 # Configure Preset CLE_PRESET = 9 # Clean Preset ZOOM_IN = 11 # Zoom inZOOM_OUT = 12 # Zoom out FOCUS_NEAR = 13 # Focus in FOCUS_FAR = 14 # Focus outIRIS_OPEN = 15 # Iris open IRIS_CLOSE = 16 # Iris close TILT_UP = 21 # PTZ tilt up TILT_DOWN = 22 # PTZ tilt downPAN_LEFT = 23 # PTZ pan left PAN_RIGHT = 24 # PTZ pan rightUP_LEFT = 25 # PTZ turn up and left UP_RIGHT = 26 # PTZ turn up and right DOWN_LEFT = 27 # PTZ turn down and left DOWN_RIGHT = 28 # PTZ turn down and right PAN_AUTO = 29 # PTZ auto pan FILL_PRE_SEQ = 30 # Add preset to sequence SET_SEQ_DWELL = 31 # Set cruise point's residence time SET_SEQ_SPEED = 32 # Set cruise point CLE_PRE_SEQ = 33 # Delete preset from sequence STA_MEM_CRUISE = 34 # Start recording trace STO_MEM_CRUISE = 35 # Stop recoding trace RUN_CRUISE = 36 # Start Cruise RUN_SEQ = 37 # Start Sequence STOP_SEQ = 38 # Stop Sequence GOTO_PRESET = 39 # Go to preset DEL_SEQ = 43 # delete cruise pathSTOP_CRUISE = 44 # stop cruiseDELETE_CRUISE = 45 # delete cruiseDELETE_ALL_CRUISE = 46 # delete all cruisePAN_CIRCLE = 50 # PTZ of the SS speed automatic circle scanningDRAG_PTZ = 51 # PTZ dragLINEAR_SCAN = 52 # Area scanning 2014-03-15 CLE_ALL_PRESET = 53 # Clean All Preset CLE_ALL_SEQ = 54 # Clean All Seq CLE_ALL_CRUISE = 55 # Clean All Cruise POPUP_MENU = 56 # Operation Menu TILT_DOWN_ZOOM_IN = 58 # PTZ tilt down & Zoom in TILT_DOWN_ZOOM_OUT = 59 # PTZ tilt down & Zoom out PAN_LEFT_ZOOM_IN = 60 # PTZ pan left & Zoom inPAN_LEFT_ZOOM_OUT = 61 # PTZ pan left & Zoom outPAN_RIGHT_ZOOM_IN = 62 # PTZ pan right & Zoom inPAN_RIGHT_ZOOM_OUT = 63 # PTZ pan right & Zoom out UP_LEFT_ZOOM_IN = 64 # PTZ turn up and left & Zoom inUP_LEFT_ZOOM_OUT = 65 # PTZ turn up and left & Zoom OutUP_RIGHT_ZOOM_IN = 66 # PTZ turn up and right & Zoom inUP_RIGHT_ZOOM_OUT = 67 # PTZ turn up and right & Zoom OutDOWN_LEFT_ZOOM_IN = 68 # PTZ turn down and left & Zoom in DOWN_LEFT_ZOOM_OUT = 69 # PTZ turn down and left & Zoom Out DOWN_RIGHT_ZOOM_IN = 70 # PTZ turn down and right & Zoom in DOWN_RIGHT_ZOOM_OUT = 71 # PTZ turn down and right & Zoom Out TILT_UP_ZOOM_IN = 72 # PTZ tilt up & Zoom in TILT_UP_ZOOM_OUT = 73 # PTZ tilt up & Zoom out DVR_VEHICLE_CONTROL_LIST = 0x1 #Vehicle black and white list data type (data type) 2013-11-04#**********************PTZ Commands end*************************#Time correction structureclass NET_DVR_TIME(Structure): _fields_ = [("dwYear", c_uint32), ("dwMonth", c_uint32), ("dwDay", c_uint32), ("dwHour", c_uint32), ("dwMinute", c_uint32), ("dwSecond", c_uint32), ]#Record Parametersclass NET_DVR_FIND_DATA(Structure): _fields_ = [("sFileName", c_char * 100), #File Name ("struStartTime", NET_DVR_TIME), #Start time of the file ("struStopTime", NET_DVR_TIME), #End time of the file ("dwFileSize", c_uint32) #File size ]#*******************Return Value of File&Log Query API*************************/NET_DVR_FILE_SUCCESS = 1000 #Get log informationNET_DVR_FILE_NOFIND = 1001 #No logNET_DVR_ISFINDING = 1002 #On searchingNET_DVR_NOMOREFILE = 1003 #No more filesNET_DVR_FILE_EXCEPTION = 1004 #Error on log query#*************************************************#Play Control Commands#Macro Definition#NET_DVR_PlayBackControl#NET_DVR_PlayControlLocDisplay#NET_DVR_DecPlayBackCtrl#**************************************************NET_DVR_PLAYSTART = 1 # Start PlayNET_DVR_PLAYSTOP = 2 # Stop PlayNET_DVR_PLAYPAUSE = 3 # Pause PlayNET_DVR_PLAYRESTART = 4 # Restore PlayNET_DVR_PLAYFAST = 5 # Play fasterNET_DVR_PLAYSLOW = 6 # Play slowerNET_DVR_PLAYNORMAL = 7 # Normal SpeedNET_DVR_PLAYFRAME = 8 # Play frame by frameNET_DVR_PLAYSTARTAUDIO = 9 # Open audioNET_DVR_PLAYSTOPAUDIO = 10 # Close audioNET_DVR_PLAYAUDIOVOLUME = 11 # Adjust volume NET_DVR_PLAYSETPOS = 12 # Change the playback progress NET_DVR_PLAYGETPOS = 13 # Get the playback progressNET_DVR_PLAYGETTIME = 14 # Get the played time (available when playback by time) NET_DVR_PLAYGETFRAME = 15 # Get the played frame number (available when playback by file) NET_DVR_GETTOTALFRAMES = 16 # Get total frame number of current file (available when playback by file) NET_DVR_GETTOTALTIME = 17 # Get total time of current file (available when playback by file) NET_DVR_THROWBFRAME = 20 # Discard B frameNET_DVR_SETSPEED = 24 # Setup stream speedNET_DVR_KEEPALIVE = 25 # Keep connection with server (if callback is blocked, send it every 2 second) NET_DVR_PLAYSETTIME = 26 # Set playback position according to absolute time NET_DVR_PLAYGETTOTALLEN = 27 # Get total time length of all the detected files under playback by time modeNET_DVR_PLAYSETTIME_V50 = 28 #Set playback position according to absolute time (support time zone)NET_DVR_PLAY_FORWARD = 29 #change stream from reverse to forwardNET_DVR_PLAY_REVERSE = 30 #change stream from froward to reverseNET_DVR_SET_DECODEFFRAMETYPE = 31 #Set decode frame typeNET_DVR_SET_TRANS_TYPE = 32 #Set Transcodeing Type NET_DVR_PLAY_CONVERT = 33 #playback decodeNET_DVR_START_DRAWFRAME = 34 #start draw I Frame NET_DVR_STOP_DRAWFRAME = 35 #stop draw I FrameNET_DVR_CHANGEWNDRESOLUTION = 36 #change wnd sizeNET_DVR_RESETBUFFER= 37 #reset matrix decode buffer(remote playback file)NET_DVR_VOD_DRAG_ING = 38 #playback in drag NET_DVR_VOD_DRAG_END = 39 #end of the playback drag NET_DVR_VOD_RESET_PLAYTIME = 40 #reset playback timeclass DWORD(Structure): _fields_ = [("value", c_uint32)]class HCNetSDK: def NET_DVR_Init(self): return hcnetsdk.NET_DVR_Init() def NET_DVR_SetReconnect(self, dwInterval=30000, bEnableRecon=True): return hcnetsdk.NET_DVR_SetReconnect(dwInterval, bEnableRecon) def NET_DVR_Login(self, sDVRIP, wDVRPort, sUserName, sPassword): di = NET_DVR_DEVICEINFO() pdi = byref(di) return hcnetsdk.NET_DVR_Login(str.encode(sDVRIP), wDVRPort, str.encode(sUserName), str.encode(sPassword), pdi) def NET_DVR_Logout(self, lUserID): return hcnetsdk.NET_DVR_Logout(lUserID) def NET_DVR_Cleanup(self): return hcnetsdk.NET_DVR_Cleanup() def NET_DVR_RealPlay(self, lUserID, lChannel, hPlayWnd): ci = NET_DVR_CLIENTINFO() ci.lChannel = lChannel ci.hPlayWnd = hPlayWnd pci = byref(ci) return hcnetsdk.NET_DVR_RealPlay(lUserID, pci) def NET_DVR_StopRealPlay(self, lRealHandle): return hcnetsdk.NET_DVR_StopRealPlay(lRealHandle) def NET_DVR_GetLastError(self): return hcnetsdk.NET_DVR_GetLastError() def NET_DVR_GetSDKVersion(self): return hcnetsdk.NET_DVR_GetSDKVersion() def NET_DVR_GetSDKBuildVersion(self): return hcnetsdk.NET_DVR_GetSDKBuildVersion() def NET_DVR_CapturePicture(self, lRealHandle, sPicFileName): return hcnetsdk.NET_DVR_CapturePicture(lRealHandle, str.encode(sPicFileName)) def NET_DVR_CaptureJPEGPicture(self, lUserID, lChannel, sPicFileName): jpeg = NET_DVR_JPEGPARA() pjpeg = byref(jpeg) return hcnetsdk.NET_DVR_CaptureJPEGPicture(lUserID, lChannel, pjpeg, str.encode(sPicFileName)) def NET_DVR_PTZControl(self, lRealHandle, dwPTZCommand, dwStop): return hcnetsdk.NET_DVR_PTZControl(lRealHandle, dwPTZCommand, dwStop) def NET_DVR_PTZPreset(self, lRealHandle, dwPTZPresetCmd, dwPresetIndex): return hcnetsdk.NET_DVR_PTZPreset(lRealHandle, dwPTZPresetCmd, dwPresetIndex) def NET_DVR_FindFile(self, lUserID, lChannel, net_dvr_time_from, net_dvr_time_to): pfrom = byref(net_dvr_time_from) pto = byref(net_dvr_time_to) return hcnetsdk.NET_DVR_FindFile(lUserID, lChannel, 0xff, pfrom, pto) def NET_DVR_FindNextFile(self, lFindHandle, net_dvr_find_data): pfind = byref(net_dvr_find_data) return hcnetsdk.NET_DVR_FindNextFile(lFindHandle, pfind) def NET_DVR_FindClose(self, lFindHandle): return hcnetsdk.NET_DVR_FindClose(lFindHandle) def NET_DVR_PlayBackByName(self, lUserID, sPlayBackFileName, hWnd): return hcnetsdk.NET_DVR_PlayBackByName(lUserID, str.encode(sPlayBackFileName), c_uint32(hWnd)) def NET_DVR_PlayBackControl(self, lPlayHandle, dwControlCode, dwInValue, OutValue): dw = DWORD() pdw = byref(dw) ret = hcnetsdk.NET_DVR_PlayBackControl(lPlayHandle, dwControlCode, dwInValue, pdw) OutValue['value'] = dw.value return ret def NET_DVR_StopPlayBack(self, lPlayHandle): return hcnetsdk.NET_DVR_StopPlayBack(lPlayHandle) def NET_DVR_GetFileByName(self, lUserID, sDVRFileName, sSavedFileName): return hcnetsdk.NET_DVR_GetFileByName(lUserID, str.encode(sDVRFileName), str.encode(sSavedFileName)) def NET_DVR_StopGetFile(self, lFileHandle): return hcnetsdk.NET_DVR_StopGetFile(lFileHandle) def NET_DVR_GetDownloadPos(self, lFileHandle): return hcnetsdk.NET_DVR_GetDownloadPos(lFileHandle) def NET_DVR_PlayBackCaptureFile(self, lPlayHandle, sFileName): return hcnetsdk.NET_DVR_PlayBackCaptureFile(lPlayHandle, str.encode(sFileName)) def NET_DVR_ClientGetVideoEffect(self, lRealHandle, OutParams): BrightValue = DWORD() ContrastValue = DWORD() SaturationValue = DWORD() HueValue = DWORD() pBrightValue = byref(BrightValue) pContrastValue = byref(ContrastValue) pSaturationValue = byref(SaturationValue) pHueValue = byref(HueValue) ret = hcnetsdk.NET_DVR_ClientGetVideoEffect(lRealHandle, pBrightValue, pContrastValue, pSaturationValue, pHueValue) OutParams['Bright'] = BrightValue.value OutParams['Contrast'] = ContrastValue.value OutParams['Saturation'] = SaturationValue.value OutParams['Hue'] = HueValue.value return ret def NET_DVR_ClientSetVideoEffect(self, lRealHandle, dwBrightValue, dwContrastValue, dwSaturationValue, dwHueValue): return hcnetsdk.NET_DVR_ClientSetVideoEffect(lRealHandle, dwBrightValue, dwContrastValue, dwSaturationValue, dwHueValue)
clientdemo.py
实现图像预览、抓图、云台控制等等功能的 Demo 客户端
import sysfrom PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *from hcnetsdk import *import pickleimport datetimeclass PTZUp(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, TILT_UP, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, TILT_UP, 1) event.accept()class PTZDown(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, TILT_DOWN, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, TILT_DOWN, 1) event.accept()class PTZLeft(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, PAN_LEFT, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, PAN_LEFT, 1) event.accept()class PTZRight(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, PAN_RIGHT, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, PAN_RIGHT, 1) event.accept()class PTZZoomIn(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, ZOOM_IN, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, ZOOM_IN, 1) event.accept()class PTZZoomOut(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, ZOOM_OUT, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, ZOOM_OUT, 1) event.accept()class PTZFocusNear(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, FOCUS_NEAR, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, FOCUS_NEAR, 1) event.accept()class PTZFocusFar(QPushButton): def __init__(self, text, parent): self.parent = parent super().__init__(text, parent) def mousePressEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, FOCUS_FAR, 0) else: self.parent.text('You have to open live first') event.accept() def mouseReleaseEvent(self, event): if -1 != self.parent.lRealHandle: self.parent.sdk.NET_DVR_PTZControl(self.parent.lRealHandle, FOCUS_FAR, 1) event.accept()class ClientDemo(QWidget): def __init__(self): super().__init__() #Init SDK self.sdk = HCNetSDK() self.sdk.NET_DVR_Init() self.sdk.NET_DVR_SetReconnect() self.lUserID = -1 self.lRealHandle = -1 #Dialog self.resize(1300, 850) self.setWindowTitle('ClientDemo') #Layout self.hbl = QHBoxLayout() self.hbl2 = QHBoxLayout() self.hbl3 = QHBoxLayout() self.hbl4 = QHBoxLayout() self.vbl = QVBoxLayout() self.vbl.addLayout(self.hbl) self.vbl.addLayout(self.hbl2) self.vbl.addLayout(self.hbl3) self.vbl.addLayout(self.hbl4) self.setLayout(self.vbl) #Login Infomation self.lbIP = QLabel('IP') self.eIP = QLineEdit() self.lbPort = QLabel('Port') self.ePort = QLineEdit() self.lbUser = QLabel('User') self.eUser = QLineEdit() self.lbPassword = QLabel('Password') self.ePassword = QLineEdit() self.ePassword.setEchoMode(QLineEdit.Password) self.lbChannel = QLabel('Channel') self.eChannel = QLineEdit() self.hbl.addWidget(self.lbIP) self.hbl.addWidget(self.eIP) self.hbl.addWidget(self.lbPort) self.hbl.addWidget(self.ePort) self.hbl.addWidget(self.lbUser) self.hbl.addWidget(self.eUser) self.hbl.addWidget(self.lbPassword) self.hbl.addWidget(self.ePassword) self.hbl.addWidget(self.lbChannel) self.hbl.addWidget(self.eChannel) #Button self.btnVersion = QPushButton('Version') self.btnVersion.clicked.connect(self.onVersion) self.hbl2.addWidget(self.btnVersion) self.btnLogin = QPushButton('Login') self.btnLogin.clicked.connect(self.onLogin) self.hbl2.addWidget(self.btnLogin) self.btnLogout = QPushButton('Logout') self.btnLogout.clicked.connect(self.onLogout) self.hbl2.addWidget(self.btnLogout) self.btnLive = QPushButton('Live') self.btnLive.clicked.connect(self.onLive) self.hbl2.addWidget(self.btnLive) self.btnCloseLive = QPushButton('Close Live') self.btnCloseLive.clicked.connect(self.onCloseLive) self.hbl2.addWidget(self.btnCloseLive) self.btnCapture = QPushButton('Capture') self.btnCapture.clicked.connect(self.onCapture) self.hbl2.addWidget(self.btnCapture) self.btnCaptureWithoutLive = QPushButton('Capture Without Live') self.btnCaptureWithoutLive.clicked.connect(self.onCaptureWithoutLive) self.hbl2.addWidget(self.btnCaptureWithoutLive) #PTZ Button self.btnPtzUp = PTZUp('Up', self) self.hbl3.addWidget(self.btnPtzUp) self.btnPtzDown = PTZDown('Down', self) self.hbl3.addWidget(self.btnPtzDown) self.btnPtzLeft = PTZLeft('Left', self) self.hbl3.addWidget(self.btnPtzLeft) self.btnPtzRight = PTZRight('Right', self) self.hbl3.addWidget(self.btnPtzRight) self.btnPtzZoomIn = PTZZoomIn('Zoom In', self) self.hbl3.addWidget(self.btnPtzZoomIn) self.btnPtzZoomOut = PTZZoomOut('Zoom Out', self) self.hbl3.addWidget(self.btnPtzZoomOut) self.btnPtzFocusNear = PTZFocusNear('Focus Near', self) self.hbl3.addWidget(self.btnPtzFocusNear) self.btnPtzFocusFar = PTZFocusFar('Focus Far', self) self.hbl3.addWidget(self.btnPtzFocusFar) #Video Params self.btnGetVideoParams = QPushButton('Video Params') self.btnGetVideoParams.clicked.connect(self.onGetVideoParams) self.hbl4.addWidget(self.btnGetVideoParams) self.lbBright = QLabel('Bright') self.hbl4.addWidget(self.lbBright) self.eBright = QLineEdit() self.hbl4.addWidget(self.eBright) self.lbContrast = QLabel('Contrast') self.hbl4.addWidget(self.lbContrast) self.eContrast = QLineEdit() self.hbl4.addWidget(self.eContrast) self.lbSaturation = QLabel('Saturation') self.hbl4.addWidget(self.lbSaturation) self.eSaturation = QLineEdit() self.hbl4.addWidget(self.eSaturation) self.lbHue = QLabel('Hue') self.hbl4.addWidget(self.lbHue) self.eHue = QLineEdit() self.hbl4.addWidget(self.eHue) self.btnSetVideoParams = QPushButton('Set Video Params') self.btnSetVideoParams.clicked.connect(self.onSetVideoParams) self.hbl4.addWidget(self.btnSetVideoParams) #Screen self.Screen = QTextEdit() self.vbl.addWidget(self.Screen) #Load Config self.LoadConfig() def text(self, info): self.Screen.setText(info) def closeEvent(self, event): self.SaveConfig() event.accept() def checkLoginInfo(self): ip = self.eIP.text() port = self.ePort.text() user = self.eUser.text() password = self.ePassword.text() if '' == ip or '' == port or '' == user or '' == password: return False if not port.isdigit(): return False return True def checkChannelInfo(self): channel = self.eChannel.text() if '' == channel or not channel.isdigit(): return False return True def checkVideoParams(self): bright = self.eBright.text() contrast = self.eContrast.text() saturation = self.eSaturation.text() hue = self.eHue.text() if '' == bright or not bright.isdigit(): return False if '' == contrast or not contrast.isdigit(): return False if '' == saturation or not saturation.isdigit(): return False if '' == hue or not hue.isdigit(): return False return True def SaveConfig(self): if self.checkLoginInfo() and self.checkLoginInfo(): ip = self.eIP.text() port = self.ePort.text() user = self.eUser.text() password = self.ePassword.text() channel = self.eChannel.text() di = dict(ip=ip, port=port, user=user, password=password, channel=channel) path = APP_PATH + 'clientdemo.conf' with open(path, 'wb') as f: pickle.dump(di, f) def LoadConfig(self): try: path = APP_PATH + 'clientdemo.conf' with open(path, 'rb') as f: di = pickle.load(f) self.eIP.setText(di['ip']) self.ePort.setText(di['port']) self.eUser.setText(di['user']) self.ePassword.setText(di['password']) self.eChannel.setText(di['channel']) except Exception as e: print(str(e)) def onVersion(self): self.Screen.clear() ver = hex(self.sdk.NET_DVR_GetSDKVersion()) build = hex(self.sdk.NET_DVR_GetSDKBuildVersion()) self.text('SDK Version: ' + str(ver) + '' + 'Build Version: ' + str(build)) def onLogin(self): if -1 == self.lUserID: if self.checkLoginInfo(): self.lUserID = self.sdk.NET_DVR_Login(self.eIP.text(), int(self.ePort.text()), self.eUser.text(), self.ePassword.text()) if -1 != self.lUserID: self.text('Login was successful') else: self.text('Login was failed, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters before login') else: self.text('You have already logined') def onLogout(self): if -1 != self.lUserID: self.sdk.NET_DVR_Logout(self.lUserID) self.lUserID = -1 self.text('Logout was successful') else: self.text('Now you are in logout status') def onLive(self): if -1 != self.lUserID: if self.checkChannelInfo(): if -1 != self.lRealHandle: self.sdk.NET_DVR_StopRealPlay(self.lRealHandle) self.lRealHandle = -1 self.lRealHandle = self.sdk.NET_DVR_RealPlay(self.lUserID, int(self.eChannel.text()), self.Screen.winId()) if -1 != self.lRealHandle: self.text('Live was successful') else: self.text('Live was failed, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters before live') else: self.text('You have to login first') def onCloseLive(self): if -1 != self.lRealHandle: self.sdk.NET_DVR_StopRealPlay(self.lRealHandle) self.lRealHandle = -1 self.Screen.clear() self.text('Live closed') else: self.text('No any live opened') def onCapture(self): if -1 != self.lRealHandle: dt = datetime.datetime.now() path = APP_PATH + 'snapshot_' + str(dt.date()) + '_' + str(dt.hour) + '_' + str(dt.minute) + '_' + str(dt.second) + '.jpg' if self.sdk.NET_DVR_CapturePicture(self.lRealHandle, path): self.text('Picture stored to ' + path) else: self.text('Failed to capture picture, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('You have to open live first') def onCaptureWithoutLive(self): if -1 != self.lUserID: dt = datetime.datetime.now() path = APP_PATH + 'snapshot_' + str(dt.date()) + '_' + str(dt.hour) + '_' + str(dt.minute) + '_' + str(dt.second) + '.jpg' if self.checkChannelInfo(): if self.sdk.NET_DVR_CaptureJPEGPicture(self.lUserID, int(self.eChannel.text()), path): self.text('Picture stored to ' + path) else: self.text('Failed to capture picture, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters') else: self.text('You have to login first') def onGetVideoParams(self): if -1 != self.lRealHandle: params = {} if self.sdk.NET_DVR_ClientGetVideoEffect(self.lRealHandle, params): self.eBright.setText(str(params['Bright'])) self.eContrast.setText(str(params['Contrast'])) self.eSaturation.setText(str(params['Saturation'])) self.eHue.setText(str(params['Hue'])) self.text('Succeed to get video params') else: self.text('Failed to get video params, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('You have to open live first') def onSetVideoParams(self): if -1 != self.lRealHandle: if self.checkVideoParams(): bright = int(self.eBright.text()) contrast = int(self.eContrast.text()) saturation = int(self.eSaturation.text()) hue = int(self.eHue.text()) if self.sdk.NET_DVR_ClientSetVideoEffect(self.lRealHandle, bright, contrast, saturation, hue): self.text('Succeed to set video params') else: self.text('Failed to set video params, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters') else: self.text('You have to open live first')app = QApplication(sys.argv)dlg = ClientDemo()dlg.show()sys.exit(app.exec_())
playdemo.py
实现录像回放、回放抓图、回放控制、录像下载等功能的 Demo 客户端
import sysfrom PyQt5.QtWidgets import *from PyQt5.QtCore import *from PyQt5.QtGui import *from hcnetsdk import *import pickleimport datetimeimport timeclass PlayDemo(QWidget): def __init__(self): super().__init__() #Init SDK self.sdk = HCNetSDK() self.sdk.NET_DVR_Init() self.sdk.NET_DVR_SetReconnect(30000, True) self.lUserID = -1 self.lPlayHandle = -1 #Dialog self.resize(1100, 600) self.setWindowTitle('PlayDemo') #Layout self.hbl = QHBoxLayout() self.hbl2 = QHBoxLayout() self.hbl3 = QHBoxLayout() self.hbl4 = QHBoxLayout() self.vbl = QVBoxLayout() self.vbl.addLayout(self.hbl) self.vbl.addLayout(self.hbl2) self.vbl.addLayout(self.hbl3) self.vbl.addLayout(self.hbl4) self.setLayout(self.vbl) #Login Infomation self.lbIP = QLabel('IP') self.eIP = QLineEdit() self.lbPort = QLabel('Port') self.ePort = QLineEdit() self.lbUser = QLabel('User') self.eUser = QLineEdit() self.lbPassword = QLabel('Password') self.ePassword = QLineEdit() self.ePassword.setEchoMode(QLineEdit.Password) self.lbChannel = QLabel('Channel') self.eChannel = QLineEdit() self.hbl.addWidget(self.lbIP) self.hbl.addWidget(self.eIP) self.hbl.addWidget(self.lbPort) self.hbl.addWidget(self.ePort) self.hbl.addWidget(self.lbUser) self.hbl.addWidget(self.eUser) self.hbl.addWidget(self.lbPassword) self.hbl.addWidget(self.ePassword) self.hbl.addWidget(self.lbChannel) self.hbl.addWidget(self.eChannel) #Login self.btnLogin = QPushButton('Login') self.btnLogin.clicked.connect(self.onLogin) self.hbl2.addWidget(self.btnLogin) self.btnLogout = QPushButton('Logout') self.btnLogout.clicked.connect(self.onLogout) self.hbl2.addWidget(self.btnLogout) #Datetime self.lbFrom = QLabel('From') self.hbl2.addWidget(self.lbFrom) di = QDateTime.currentDateTime() ts = di.toTime_t() ts -= 86400 di = di.fromTime_t(ts) self.btnFromDatetime = QDateTimeEdit(di) #self.btnFromDatetime.resize(self.btnFromDatetime.height(), 25) self.hbl2.addWidget(self.btnFromDatetime) self.lbTo = QLabel('To') self.hbl2.addWidget(self.lbTo) self.btnToDatetime = QDateTimeEdit(QDateTime.currentDateTime()) #self.btnToDatetime.resize(self.btnToDatetime.height(), 25) self.hbl2.addWidget(self.btnToDatetime) #Search Record Files self.btnRecords = QPushButton('Records') self.btnRecords.clicked.connect(self.onRecords) self.hbl2.addWidget(self.btnRecords) #Play File Name self.lbPlayFile = QLabel('Play File Name') self.hbl3.addWidget(self.lbPlayFile) self.ePlayFile = QLineEdit() self.hbl3.addWidget(self.ePlayFile) #Download Record File self.btnDownload = QPushButton('Download') self.btnDownload.clicked.connect(self.onDownload) self.hbl4.addWidget(self.btnDownload) #Playback self.btnPlay = QPushButton('Play') self.btnPlay.clicked.connect(self.onPlay) self.hbl4.addWidget(self.btnPlay) self.btnStop = QPushButton('Stop') self.btnStop.clicked.connect(self.onStop) self.hbl4.addWidget(self.btnStop) self.btnBack = QPushButton('Back') self.btnBack.clicked.connect(self.onBack) self.hbl4.addWidget(self.btnBack) self.btnForward = QPushButton('Forward') self.btnForward.clicked.connect(self.onForward) self.hbl4.addWidget(self.btnForward) self.btnPause = QPushButton('Pause') self.btnPause.clicked.connect(self.onPause) self.hbl4.addWidget(self.btnPause) self.pause = False self.btnCapture = QPushButton('Capture') self.btnCapture.clicked.connect(self.onCapture) self.hbl4.addWidget(self.btnCapture) #Screen self.Screen = QTextEdit() self.vbl.addWidget(self.Screen) #Load Config self.LoadConfig() def text(self, info): self.Screen.setText(info) def closeEvent(self, event): self.SaveConfig() event.accept() def checkLoginInfo(self): ip = self.eIP.text() port = self.ePort.text() user = self.eUser.text() password = self.ePassword.text() if '' == ip or '' == port or '' == user or '' == password: return False if not port.isdigit(): return False return True def checkChannelInfo(self): channel = self.eChannel.text() if '' == channel or not channel.isdigit(): return False return True def checkPlayFile(self): filename = self.ePlayFile.text() if '' == filename: return False return True def SaveConfig(self): if self.checkLoginInfo() and self.checkLoginInfo(): ip = self.eIP.text() port = self.ePort.text() user = self.eUser.text() password = self.ePassword.text() channel = self.eChannel.text() di = dict(ip=ip, port=port, user=user, password=password, channel=channel) path = APP_PATH + 'playdemo.conf' with open(path, 'wb') as f: pickle.dump(di, f) def LoadConfig(self): try: path = APP_PATH + 'playdemo.conf' with open(path, 'rb') as f: di = pickle.load(f) self.eIP.setText(di['ip']) self.ePort.setText(di['port']) self.eUser.setText(di['user']) self.ePassword.setText(di['password']) self.eChannel.setText(di['channel']) except Exception as e: print(str(e)) def onLogin(self): if -1 == self.lUserID: if self.checkLoginInfo(): self.lUserID = self.sdk.NET_DVR_Login(self.eIP.text(), int(self.ePort.text()), self.eUser.text(), self.ePassword.text()) if -1 != self.lUserID: self.text('Login was successful') else: self.text('Login was failed, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters before login') else: self.text('You have already logined') def onLogout(self): if -1 != self.lUserID: self.sdk.NET_DVR_Logout(self.lUserID) self.lUserID = -1 self.text('Logout was successful') else: self.text('Now you are in logout status') def onRecords(self): if -1 != self.lUserID: if self.checkChannelInfo(): fromDatetime = NET_DVR_TIME() toDatetime = NET_DVR_TIME() fromDatetime.dwYear = self.btnFromDatetime.date().year() fromDatetime.dwMonth = self.btnFromDatetime.date().month() fromDatetime.dwDay = self.btnFromDatetime.date().day() fromDatetime.dwHour = self.btnFromDatetime.time().hour() fromDatetime.dwMinute = self.btnFromDatetime.time().minute() fromDatetime.dwSecond = self.btnFromDatetime.time().second() toDatetime.dwYear = self.btnToDatetime.date().year() toDatetime.dwMonth = self.btnToDatetime.date().month() toDatetime.dwDay = self.btnToDatetime.date().day() toDatetime.dwHour = self.btnToDatetime.time().hour() toDatetime.dwMinute = self.btnToDatetime.time().minute() toDatetime.dwSecond = self.btnToDatetime.time().second() lFindHandle = self.sdk.NET_DVR_FindFile(self.lUserID, int(self.eChannel.text()), fromDatetime, toDatetime) records = '' if -1 != lFindHandle: while True: data = NET_DVR_FIND_DATA() ret = self.sdk.NET_DVR_FindNextFile(lFindHandle, data) if NET_DVR_ISFINDING == ret: time.sleep(0.2) continue elif NET_DVR_FILE_SUCCESS == ret: records += 'File Name: ' + bytes.decode(data.sFileName) records += ' File Size: ' + str(data.dwFileSize) records += ' From: ' + str(data.struStartTime.dwYear) + '-' + str(data.struStartTime.dwMonth) + '-' + str(data.struStartTime.dwDay) + '-' + str(data.struStartTime.dwHour) + '_' + str(data.struStartTime.dwMinute) + '_' + str(data.struStartTime.dwSecond) records += ' To: ' + str(data.struStopTime.dwYear) + '-' + str(data.struStopTime.dwMonth) + '-' + str(data.struStopTime.dwDay) + '-' + str(data.struStopTime.dwHour) + '_' + str(data.struStopTime.dwMinute) + '_' + str(data.struStopTime.dwSecond) records += '' elif NET_DVR_FILE_NOFIND == ret: break elif NET_DVR_NOMOREFILE == ret: break else: break self.sdk.NET_DVR_FindClose(lFindHandle) self.Screen.setText(records) else: self.text('Search files failed, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters') else: self.text('You have to login first') def onDownload(self): if -1 != self.lUserID: if self.checkPlayFile(): dt = datetime.datetime.now() path = APP_PATH + '' + self.ePlayFile.text() + '_' + str(dt.date()) + '_' + str(dt.hour) + '_' + str(dt.minute) + '_' + str(dt.second) + '.mp4' self.lFileHandle = self.sdk.NET_DVR_GetFileByName(self.lUserID, self.ePlayFile.text(), path) if -1 != self.lFileHandle: OutValue = {} self.sdk.NET_DVR_PlayBackControl(self.lFileHandle, NET_DVR_PLAYSTART, 0, OutValue) pos = self.sdk.NET_DVR_GetDownloadPos(self.lFileHandle) if -1 != pos: while True: pos = self.sdk.NET_DVR_GetDownloadPos(self.lFileHandle) print('Downloading ... ' + str(pos) + '%') if pos >= 100: break time.sleep(1) self.sdk.NET_DVR_StopGetFile(self.lFileHandle) self.lFileHandle = -1 else: self.text('Failed to download, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters in Play-File-Name box, refer the result after you clicked the Records button') else: self.text('You have to login first') def onPlay(self): if -1 != self.lUserID: if self.checkPlayFile(): self.lPlayHandle = self.sdk.NET_DVR_PlayBackByName(self.lUserID, self.ePlayFile.text(), self.Screen.winId()) if -1 != self.lPlayHandle: OutValue = {} if self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYSTART, 0, OutValue): self.text('Playing ...') else: self.text('Failed to play, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Failed to play, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('Please input the correct parameters in Play-File-Name box, refer the result after you clicked the Records button') else: self.text('You have to login first') def onStop(self): if -1 != self.lPlayHandle: self.sdk.NET_DVR_StopPlayBack(self.lPlayHandle) self.lPlayHandle = -1 self.Screen.clear() self.text('Stopped') else: self.text('Now you are in stop status') def onBack(self): if -1 != self.lPlayHandle: OutValue = {} self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYGETPOS, 0, OutValue) dwInValue = OutValue['value'] - 1 self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYSETPOS, dwInValue, OutValue) else: self.text('You have to play video first') def onForward(self): if -1 != self.lPlayHandle: OutValue = {} self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYGETPOS, 0, OutValue) dwInValue = OutValue['value'] + 1 self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYSETPOS, dwInValue, OutValue) else: self.text('You have to play video first') def onPause(self): if -1 != self.lPlayHandle: OutValue = {} if self.pause: self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYRESTART, 0, OutValue) self.pause = False else: self.sdk.NET_DVR_PlayBackControl(self.lPlayHandle, NET_DVR_PLAYPAUSE, 0, OutValue) self.pause = True else: self.text('You have to play video first') def onCapture(self): if -1 != self.lPlayHandle: dt = datetime.datetime.now() path = APP_PATH + 'snapshot_' + str(dt.date()) + '_' + str(dt.hour) + '_' + str(dt.minute) + '_' + str(dt.second) + '.jpg' if self.sdk.NET_DVR_PlayBackCaptureFile(self.lPlayHandle, path): self.text('Picture stored to ' + path) else: self.text('Failed to capture, Error Code: ' + str(self.sdk.NET_DVR_GetLastError())) else: self.text('You have to play video first')app = QApplication(sys.argv)dlg = PlayDemo()dlg.show()sys.exit(app.exec_())