此贴能起到的作用

通过这个帖子,能了解到如何用Python调用海康SDK,实现业务逻辑需要结合哪些资料,这些接口的参数是怎么样的,如何翻译成Python,如何传参,参数中的一些变量,常量可以怎样查找。

戳这里获得demo源码

开发资源

海康威视SDK下载 https://www.hikvision.com/cn/download_61.html

SDK只有对linux和windows的支持,没有对mac的支持,所以mac开发比较累

基于SDK开发

SDK中给到了基于Java,C#等demo(这写可以帮助我们了解部分变量的定义和值域,很重要,可以在Python构建实体的时候作为参考),但是没有python。

linux和windows的SDK中分别是.so和.dll,对于python我们需要ctypes库来完成二次开发

硬件产品开发文档,这里有详细硬件功能调用链,很详细,不过demo是c++的,另外demo中的一些变量或者常量不能查看引用,这里我们需要结合Java或者C#的包去查看具体值域。

https://open.hikvision.com/hardware/definitions/接口或实体.html

,这个路径下是接口的详细文档。

代码实践

基础SDK调用实现

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41from ctypes import *

import os

import logging

import hkws.model.login as login

import hkws.model.preview as preview

from hkws.callback import hikFunc

from hkws.callback import g_real_data_call_back

class HKAdapter:

so_list = []

# 加载目录下所有so文件

def add_lib(self, path, suffix):

files = os.listdir(path)

for file in files:

if not os.path.isdir(path + file):

if file.endswith(suffix):

self.so_list.append(path + file)

else:

self.add_lib(path + file + "/", suffix)

# python 调用 sdk 指定方法

def call_cpp(self, func_name, *args):

for so_lib in self.so_list:

try:

lib = cdll.LoadLibrary(so_lib)

try:

value = eval("lib.%s" % func_name)(*args)

logging.info("调用的库:" + so_lib)

logging.info("执行成功,返回值:" + str(value))

return value

except:

continue

except:

continue

# logging.info("库文件载入失败:" + so_lib )

logging.error("没有找到接口!")

return False

初始化SDK及释放SDK

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15# 初始化海康微视 sdk

def init_sdk(self):

init_res = self.call_cpp("NET_DVR_Init") # SDK初始化

if init_res:

logging.info("SDK初始化成功")

return True

else:

error_info = self.call_cpp("NET_DVR_GetLastError")

logging.error("SDK初始化错误:" + str(error_info))

return False

# 释放sdk

def sdk_clean(self):

result = self.call_cpp("NET_DVR_Cleanup")

logging.info("释放资源", result)

用户设备登录

请求所用参数,这里需要用python ctypes参照https://open.hikvision.com/hardware/definitions/NET_DVR_Login_V40.html 所给出的结构写出对应的python类,有些常量具体数值是没有的,需要结合之前所说的Java,C#的demo看。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147class NET_DVR_USER_LOGIN_INFO(Structure):

_fields_ = [

("sDeviceAddress", c_byte * 129), # 设备地址,IP或者普通域名

("byUseTransport", c_byte), # 是否启用能力透传 0:不启动,默认 1:启动

("wPort", c_uint16), # 设备端口号

("sUserName", c_byte * 64), # 登录用户名

("sPassword", c_byte * 64), # 登录密码

# ("fLoginResultCallBack",) #

("bUseAsynLogin", c_bool), # 是否异步登录, 0:否 1:是

("byProxyType", c_byte), # 代理服务器类型:0- 不使用代理,1- 使用标准代理,2- 使用EHome代理

# 是否使用UTC时间:

# 0 - 不进行转换,默认;

# 1 - 输入输出UTC时间,SDK进行与设备时区的转换;

# 2 - 输入输出平台本地时间,SDK进行与设备时区的转换

("byUseUTCTime", c_byte),

# 登录模式(不同模式具体含义详见“Remarks”说明):

# 0- SDK私有协议,

# 1- ISAPI协议,

# 2- 自适应(设备支持协议类型未知时使用,一般不建议)

("byLoginMode", c_byte),

# ISAPI协议登录时是否启用HTTPS(byLoginMode为1时有效):

# 0 - 不启用,

# 1 - 启用,

# 2 - 自适应(设备支持协议类型未知时使用,一般不建议)

("byHttps", c_byte),

# 代理服务器序号,添加代理服务器信息时相对应的服务器数组下表值

("iProxyID", c_long),

# 保留,置为0

("byRes3", c_byte * 120),

]

# 设备参数结构体。

class NET_DVR_DEVICEINFO_V30(Structure):

_fields_ = [

("sSerialNumber", c_byte * 48), # 序列号

("byAlarmInPortNum", c_byte), # 模拟报警输入个数

("byAlarmOutPortNum", c_byte), # 模拟报警输出个数

("byDiskNum", c_byte), # 硬盘个数

("byDVRType", c_byte), # 设备类型,详见下文列表

("byChanNum", c_byte), # 设备模拟通道个数,数字(IP)通道最大个数为byIPChanNum + byHighDChanNum*256

("byStartChan", c_byte), # 模拟通道的起始通道号,从1开始。数字通道的起始通道号见下面参数byStartDChan

("byAudioChanNum", c_byte), # 设备语音对讲通道数

("byIPChanNum", c_byte),

# 设备最大数字通道个数,低8位,搞8位见byHighDChanNum. 可以根据ip通道个数是否调用NET_DVR_GetDVRConfig (配置命令NET_DVR_GET_IPPARACFG_V40)获得模拟和数字通道的相关参数

("byZeroChanNum", c_byte), # 零通道编码个数

("byMainProto", c_byte), # 主码流传输协议类型: 0 - private, 1 - rtsp, 2- 同时支持私有协议和rtsp协议去留(默认采用私有协议取流)

("bySubProto", c_byte), # 字码流传输协议类型: 0 - private , 1 - rtsp , 2 - 同时支持私有协议和rtsp协议取流 (默认采用私有协议取流)

# 能力,位与结果为0表示不支持,1

# 表示支持

# bySupport & 0x1,表示是否支持智能搜索

# bySupport & 0x2,表示是否支持备份

# bySupport & 0x4,表示是否支持压缩参数能力获取

# bySupport & 0x8, 表示是否支持双网卡

# bySupport & 0x10, 表示支持远程SADP

# bySupport & 0x20, 表示支持Raid卡功能

# bySupport & 0x40, 表示支持IPSAN目录查找

# bySupport & 0x80, 表示支持rtp over rtsp

("bySupport", c_byte),

# 能力集扩充,位与结果为0表示不支持,1

# 表示支持

# bySupport1 & 0x1, 表示是否支持snmp

# v30

# bySupport1 & 0x2, 表示是否支持区分回放和下载

# bySupport1 & 0x4, 表示是否支持布防优先级

# bySupport1 & 0x8, 表示智能设备是否支持布防时间段扩展

# bySupport1 & 0x10, 表示是否支持多磁盘数(超过33个)

# bySupport1 & 0x20, 表示是否支持rtsp over http

# bySupport1 & 0x80, 表示是否支持车牌新报警信息,且还表示是否支持NET_DVR_IPPARACFG_V40配置

("bySupport1", c_byte),

# 能力集扩充,位与结果为0表示不支持,1

# 表示支持

# bySupport2 & 0x1, 表示解码器是否支持通过URL取流解码

# bySupport2 & 0x2, 表示是否支持FTPV40

# bySupport2 & 0x4, 表示是否支持ANR(断网录像)

# bySupport2 & 0x20, 表示是否支持单独获取设备状态子项

# bySupport2 & 0x40, 表示是否是码流加密设备

("bySupport2", c_byte),

("wDevType", c_uint16), # 设备型号,详见下文列表

# 能力集扩展,位与结果:0 - 不支持,1 - 支持

# bySupport3 & 0x1, 表示是否支持多码流

# bySupport3 & 0x4, 表示是否支持按组配置,具体包含通道图像参数、报警输入参数、IP报警输入 / 输出接入参数、用户参数、设备工作状态、JPEG抓图、定时和时间抓图、硬盘盘组管理等

# bySupport3 & 0x20,表示是否支持通过DDNS域名解析取流

("bySupport3", c_byte),

# 是否支持多码流,按位表示,位与结果:0 - 不支持,1 - 支持

# byMultiStreamProto & 0x1, 表示是否支持码流3

# byMultiStreamProto & 0x2, 表示是否支持码流4

# byMultiStreamProto & 0x40, 表示是否支持主码流

# byMultiStreamProto & 0x80, 表示是否支持子码流

("byMultiStreamProto", c_byte),

("byStartDChan", c_byte), # 起始数字通道号,0表示无数字通道,比如DVR或IPC

("byStartDTalkChan", c_byte), # 起始数字对讲通道号,区别于模拟对讲通道号,0表示无数字对讲通道

("byHighDChanNum", c_byte), # 数字通道个数,高8位

# 能力集扩展,按位表示,位与结果:0 - 不支持,1 - 支持

# bySupport4 & 0x01, 表示是否所有码流类型同时支持RTSP和私有协议

# bySupport4 & 0x10, 表示是否支持域名方式挂载网络硬盘

("bySupport4", c_byte),

# 支持语种能力,按位表示,位与结果:0 - 不支持,1 - 支持

# byLanguageType == 0,表示老设备,不支持该字段

# byLanguageType & 0x1,表示是否支持中文

# byLanguageType & 0x2,表示是否支持英文

("byLanguageType", c_byte),

("byVoiceInChanNum", c_byte), # 音频输入通道数

("byStartVoiceInChanNo", c_byte), # 音频输入起始通道号,0表示无效

("byRes3", c_byte * 2), # 保留,置为0

("byMirrorChanNum", c_byte), # 镜像通道个数,录播主机中用于表示导播通道

("wStartMirrorChanNo", c_uint16), # 起始镜像通道号

("byRes2", c_byte * 2)] # 保留,置为0

class NET_DVR_DEVICEINFO_V40(Structure):

_fields_ = [

("struDeviceV30", NET_DVR_DEVICEINFO_V30), # 设备参数

("bySupportLock", c_byte), # 设备是否支持锁定功能,bySuportLock 为1时,dwSurplusLockTime和byRetryLoginTime有效

("byRetryLoginTime", c_byte), # 剩余可尝试登陆的次数,用户名,密码错误时,此参数有效

# 密码安全等级: 0-无效,1-默认密码,2-有效密码,3-风险较高的密码,

# 当管理员用户的密码为出厂默认密码(12345)或者风险较高的密码时,建议上层客户端提示用户名更改密码

("byPasswordLevel", c_byte),

("byProxyType", c_byte), # 代理服务器类型,0-不使用代理,1-使用标准代理,2-使用EHome代理

# 剩余时间,单位:秒,用户锁定时次参数有效。在锁定期间,用户尝试登陆,不算用户名密码输入对错

# 设备锁定剩余时间重新恢复到30分钟

("dwSurplusLockTime", c_ulong),

# 字符编码类型(SDK所有接口返回的字符串编码类型,透传接口除外):

# 0 - 无字符编码信息(老设备)

# 1 - GB2312

("byCharEncodeType", c_byte),

# 支持v50版本的设备参数获取,设备名称和设备类型名称长度扩展为64字节

("bySupportDev5", c_byte),

# 登录模式(不同的模式具体含义详见"Remarks"说明:0- SDK私有协议,1- ISAPI协议)

("byLoginMode", c_byte),

# 保留,置为0

("byRes2", c_byte * 253),

]

class NET_DVR_Login_V40(Structure):

_fields_ = [

("pLoginInfo", NET_DVR_USER_LOGIN_INFO),

("lpDeviceInfo", NET_DVR_DEVICEINFO_V40)

]

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45# 用户登录指定摄像机设备

def login(self, address="192.168.1.1", port=8000, user="admin", pwd="admin"):

# 设置连接时间

set_overtime = self.call_cpp("NET_DVR_SetConnectTime", 5000, 4) # 设置超时

if set_overtime:

logging.info(address + ", 设置超时时间成功")

else:

error_info = self.call_cpp("NET_DVR_GetLastError")

logging.error(address + ", 设置超时错误信息:" + str(error_info))

return False

# 设置重连

self.call_cpp("NET_DVR_SetReconnect", 10000, True)

b_address = bytes(address, "ascii")

b_user = bytes(user, "ascii")

b_pwd = bytes(pwd, "ascii")

struLoginInfo = login.NET_DVR_USER_LOGIN_INFO()

struLoginInfo.bUseAsynLogin = 0 # 同步登陆

i = 0

for o in b_address:

struLoginInfo.sDeviceAddress[i] = o

i += 1

struLoginInfo.wPort = port

i = 0

for o in b_user:

struLoginInfo.sUserName[i] = o

i += 1

i = 0

for o in b_pwd:

struLoginInfo.sPassword[i] = o

i += 1

device_info = login.NET_DVR_DEVICEINFO_V40()

loginInfo1 = byref(struLoginInfo)

loginInfo2 = byref(device_info)

user_id = self.call_cpp("NET_DVR_Login_V40", loginInfo1, loginInfo2)

logging.info(address + ", 登录结果:" + str(user_id))

if user_id == -1: # -1表示失败,其他值表示返回的用户ID值。

error_info = self.call_cpp("NET_DVR_GetLastError")

logging.error(address + ", 登录错误信息:" + str(error_info))

return user_id

调用网络摄像机获得视频数据流

这里会有callback的概念,这里是针对视频流的回调,得到视频流后可以自定义视频流的处理,比如直接对接openCV等

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50# 定义callback

@CFUNCTYPE(None, c_long, c_ulong, c_byte, c_ulong, c_ulong)

def g_real_data_call_back(lRealPlayHandle: c_long,

dwDataType: c_ulong,

pBuffer: c_byte,

dwBufSize: c_ulong,

dwUser: c_ulong):

print('callback pBufSize is ', lRealPlayHandle, dwBufSize)

# 预览参数结构体

class NET_DVR_PREVIEWINFO(Structure):

_fields_ = [

# 通道号,目前设备模拟通道号从1开始,数字通道的起始通道号通过

# NET_DVR_GetDVRConfig(配置命令NET_DVR_GET_IPPARACFG_V40)获取(dwStartDChan)

('lChannel', c_long),

# 码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推

('dwStreamType', c_ulong),

# 连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输)

('dwLinkMode', c_ulong),

# 播放窗口的句柄,为NULL表示不解码显示

('hPlayWnd', c_void_p),

# 0-非阻塞取流,1- 阻塞取流

# 若设为不阻塞,表示发起与设备的连接就认为连接成功,如果发生码流接收失败、播放失败等

# 情况以预览异常的方式通知上层。在循环播放的时候可以减短停顿的时间,与NET_DVR_RealPlay

# 处理一致。

# 若设为阻塞,表示直到播放操作完成才返回成功与否,网络异常时SDK内部connect失败将会有5s

# 的超时才能够返回,不适合于轮询取流操作。

('bBlocked', c_bool),

# 是否启用录像回传: 0-不启用录像回传,1-启用录像回传。ANR断网补录功能,

# 客户端和设备之间网络异常恢复之后自动将前端数据同步过来,需要设备支持。

('bPassbackRecord', c_bool),

# 延迟预览模式:0-正常预览,1-延迟预览

('byPreviewMode', c_byte),

# 流ID,为字母、数字和"_"的组合,IChannel为0xffffffff时启用此参数

('byStreamID', c_byte * 32),

# 应用层取流协议:0-私有协议,1-RTSP协议。

# 主子码流支持的取流协议通过登录返回结构参数NET_DVR_DEVICEINFO_V30的byMainProto、bySubProto值得知。

# 设备同时支持私协议和RTSP协议时,该参数才有效,默认使用私有协议,可选RTSP协议。

('byProtoType', c_byte),

# 保留,置为0

('byRes1', c_byte),

# 码流数据编解码类型:0-通用编码数据,1-热成像探测器产生的原始数据

# (温度数据的加密信息,通过去加密运算,将原始数据算出真实的温度值)

('byVideoCodingType', c_byte),

# 播放库播放缓冲区最大缓冲帧数,取值范围:1、6(默认,自适应播放模式) 15:置0时默认为1

('dwDisplayBufNum', c_ulong),

# 保留,置为0

('byRes', c_byte * 216),

]

视频流回调可以在NET_DVR_RealPlay_V40中直接得到,也可以用以下返回的lRealPlayHandle去调用callback_real_data()获得,回调所得的数据可以在回调函数里面操作

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23def start_preview(self, cbFunc: hikFunc, userId=0):

req = preview.NET_DVR_PREVIEWINFO()

req.hPlayWnd = None

req.lChannel = 1 # 预览通道号

req.dwStreamType = 0 # 码流类型:0-主码流,1-子码流,2-三码流,3-虚拟码流,以此类推

req.dwLinkMode = 0 # 连接方式:0-TCP方式,1-UDP方式,2-多播方式,3-RTP方式,4-RTP/RTSP,5-RTP/HTTP,6-HRUDP(可靠传输)

req.bBlocked = 1 # 0-非阻塞 1-阻塞

struPlayInfo = byref(req)

# 这个回调函数不适合长时间占用

# fRealDataCallBack_V30 = preview.REALDATACALLBACK

lRealPlayHandle = self.call_cpp("NET_DVR_RealPlay_V40", userId, struPlayInfo, cbFunc, None)

print("start_preview lrealPlayHandle is ", lRealPlayHandle)

if lRealPlayHandle < 0:

self.logout(userId)

self.sdk_clean()

return lRealPlayHandle

def stop_preview(self, lRealPlayHandle):

self.call_cpp("NET_DVR_StopRealPlay", lRealPlayHandle)

def callback_real_data(self, lRealPlayHandle: c_long, cbFunc: g_real_data_call_back, dwUser: c_ulong):

return self.call_cpp("NET_DVR_SetRealDataCallBack", lRealPlayHandle, cbFunc, dwUser)

参考资料

https://www.hikvision.com/cn/download_61.html

https://open.hikvision.com/docs/e3fc37bb504f98c2dfb2adec5a74cfef

https://docs.python.org/3.6/library/ctypes.html

https://coolview.github.io/2018/09/26/Python%20%E8%B0%83%E7%94%A8%E6%B5%B7%E5%BA%B7%20SDK/

python如何使用sdk_Python实现海康威视SDK二次开发-1相关推荐

  1. 海康威视SDK二次开发通过云台参数设置控制摄像机的位置

    海康威视SDK二次开发通过云台参数设置控制摄像机的位置 由于最近在开发海康威视摄像头,特此记录一下通过云台参数控制摄像机的位置,我这里是通过properties配置文件输入的参数,也可以不用配置文件, ...

  2. 使用NetBeans 海康威视 SDK 二次开发

    环境: Windows 7 64 1.安装NetBeans IDE 8.2 https://netbeans.apache.org/download/index.html https://netbea ...

  3. Qt调用海康威视SDK二次开发抓图,录像,停止录像

    在前置SDK都配置好的基础上直接进行即可 MainWindow.h  声明三个按钮的slots private:int lUserID:int lRealPlayHandle;//这两个是在配置之前S ...

  4. win10系统海康威视SDK二次开发Qt环境配置

    先下载海康SDK 我下载的win64版本: 海康SDK官网下载 解压后得到库文件和头文件 头文件 库文件 新建QWidget项目,选择64位的kits工具,在pro目录新建include文件夹和lib ...

  5. 海康威视工业相机SDK二次开发(VS+Opencv+QT+海康SDK+C++)(一)

    最近在做一个项目,涉及到工业相机,需要对其进行二次开发.相机方面选择了海康威视,网上关于海康威视工业相机SDK的开发资料很少,官方文档里面虽然写的是支持C++开发的,但其实是C.自己也摸索了一段时间, ...

  6. 海康威视摄像机SDK二次开发--提取音频保存至文件

    由于最近在开发海康威视摄像头,特此记录一下如何提取音频数据,这里主要依靠语音对讲返回的音频数据,通过回调函数写入文件中,加个WAV头即可播放,编码格式可以自己设置在代码中有注释 文件结构 其中Came ...

  7. 海康威视工业相机SDK二次开发

    海康威视工业相机SDK二次开发 好气,第一次写文章,结果没不小心保存关掉,什么都没了. 本人是一名在读研究生,被导师分配了做项目中海康工业相机的二次开发.实现的需求是:实现八个相机同时打开视频,并且分 ...

  8. 海康威视摄像机SDK二次开发--指定云台位置,焦距放大倍数,拍摄时长,并拆分保存为视频文件

    按照config.txt配置,出现的效果是有几组参数就录制几个视频,视频时长按照配置文件录制 config.txt的内容,请参照海康威视摄像机SDK二次开发–实时预览视频流保存到指定文件中 java实 ...

  9. Linux下海康威视工业相机的SDK二次开发

    1.客户端软件MVS的安装 1.1安装包的下载和解压 去 官网 下载两个软件安装,分别是客户端和开发环境.(这里我们下载V2.1.1(Linux)和Runtime组件包(Linux)): 工业相机文档 ...

最新文章

  1. cdh 添加jar包_使用maven下载cdh版本的大数据jar包
  2. 使用JUnit5对DynamoDB应用程序进行单元测试
  3. MVP 模式实例解析
  4. 理解 JavaScript 的 async/await
  5. 漫谈 Clustering (2): k-medoids
  6. linux的forx函数-进程控制
  7. mysql5.5 mysqldump_mysql5.5mysqldump原文翻译_MySQL
  8. java 异或表示状态
  9. EXCEL 利用随机数公式生成随机字母、随机密码
  10. Groovy - Groovy ambiguous method overload
  11. HI3861学习笔记(12)——GPIO输入接口使用
  12. 最新版Shiro-SpringBoot项目实战笔记
  13. 长程蓝牙温湿度及光照度传感器 , 带四通道开关及指示灯(集成太阳能微能量采集功能)
  14. 如何在Windows 7和Vista之间共享文件和打印机
  15. VBA批量OCR识别提取身份证照片信息_白描网页版 - 高效准确且免费的OCR文字识别工具...
  16. android盒子 小米遥控,小米盒子遥控器手机版下载-小米盒子遥控器appv6.0.0 安卓版 - 极光下载站...
  17. 猿创征文|unity中的MVC编程思想基础
  18. 【51毕业设计案例】【007】WIFI智能定时加湿器-基于51单片机
  19. python深度学习之基于LSTM时间序列的股票价格预测
  20. C++语法学习笔记二十七: 引用折叠,转发、完美转发,forward

热门文章

  1. 九零后程序员心声:互联网的同行们,别卷了,再卷人都卷没了
  2. 获取站点真实IP地址-多地点Ping方法
  3. SQL学习——窗口函数
  4. 初识qml——PathView QQmlContext c++类与qml的数据交互
  5. Windows Phone 开发学习笔记(六) Hello Windows Phone之生死有命
  6. 图片中的人物怎么抠出来?分享几种好用抠图方法
  7. Go单元测试学习笔记 V1.0
  8. 从李佳琦的粉丝群来解说社群运营
  9. ffmpeg 修改视频封面
  10. 锐龙r7 6800h和酷睿i7 1260p哪个好 r76800h和i71260p对比