龙空技术网

纯python实现的视频监控客户端软件(二)

Marco快乐编程 218

前言:

目前大家对“hcnetsdkdll153”可能比较珍视,兄弟们都需要剖析一些“hcnetsdkdll153”的相关文章。那么小编同时在网摘上搜集了一些关于“hcnetsdkdll153””的相关知识,希望大家能喜欢,各位老铁们快快来了解一下吧!

回顾

让我们回顾一下上次的内容,test.py 文件中那6行代码实现的c++ dll加载:

import os

from ctypes import *

APP_PATH = os.path.dirname(os.path.abspath(__file__))

hcnetsdk = cdll.LoadLibrary(APP_PATH + '\\HCNetSDK.dll')

hcpreview = cdll.LoadLibrary(APP_PATH + '\\HCPreview.dll')

hcplayback = cdll.LoadLibrary(APP_PATH + '\\HCPlayBack.dll')

继续

本来想直接贴全部代码,结果头条说我的字数太多,不能发布,只能一点点按顺序贴,麻烦各位一部分一部分的拷贝了,不过这样也有利于我每贴一段,进行一定程度的代码解释备注。

库导入

接着写,我们需要导入如下的库:

from PyQt5.QtWidgets import *

from PyQt5.QtCore import *

from PyQt5.QtGui import *

import pickle

import sys

PyQT5 是诺基亚的一套老牌的跨界面开发包,利用它我们可以轻松开发windows/linux界面应用程序。

pickle是用于配置文件读写的库,本例中用于读写IP、端口、用户名、密码等配置;

sys是系统库,我们需要在创建QT程序时用到它。

结构定义与转换

以 python 的方式来定义 c++ 结构体,我们先看一下HCNetSDK.h中的原始c++定义:

NET_DVR_DEVICEINFO

NET_DVR_CLIENTINFO

再看我们在 python 中的转换代码如下:

SERIALNO_LEN = 48 #SN length

class 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 decoding

class 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)

]

结构体 NET_DVR_DEVICEINFO 是调用海康登录函数时需要传入的参数:

结构体 NET_DVR_CLIENTINFO 是调用海康预览函数时需要传入的参数;

这里对重要的几个参数解释一下:

lLinkMode 为0代表取主码流、为1代表取子码流;

hPlayWnd 指定你需要显示视频内容的窗口;

从上可以看出,python 直接调用 c++ dll,最大的困难在于在两个语言之间进行适当的结构体、变量类型的转换,这不仅要求你对两种语言都非常熟悉,而且还要去你对windows API 编程要熟悉,特别是 windows 基于c/c++定义的一些操作系统变量类型,比如:DWORD、WORD等,这块对于初学者来说并不是那么友好。

函数定义与转换

同样,除了结构体的转换,我们还必须完成函数的转换,让我们先看看 HCNetSDK.h 中的原始c++函数定义,如下是部分截图:

我们必须转换函数的参数为 python 能够认知的类型,所以,接下来我在 python 中定义了 HCNetSDK 这个类,来实现所有的参数转换:

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()

同样这些转换对于初学者来说不太友好,你必须理解指针、常量指针、结构指针、引用等等一些概念,因此,直接拷贝代码好了,本例只写了10个函数,如果你要扩展其他函数,可以依样画葫芦,或者有问题在评论区留言好了。

结语

由于头条篇幅的限制,我们紧接着下一篇文章继续贴代码。

标签: #hcnetsdkdll153